Rock Paper Javascript trouble - javascript

I have looked through quite a few of the posts regarding rock, paper, scissors, but I am still unable to find a clear solution. I am relatively new, just trying to fully understand what I'm doing.
I have gone back and forth through this with a few different approaches. Therefore, I fear that there are inconsistencies in the code structure.
I am mostly stuck right now with updating the scoreboard and trying to update playerChoice from the DOM. Any help would be much appreciated. Thank you all.
const player = {
currentChoice: null,
playerScore: 0
}
const computer = {
currentChoice: null,
computerScore: 0
}
const choices = ["Lapis", "Papyrus", "Scalpellus"];
player.currentChoice = choices[0]
function computerChooses() {
const randomIndex = Math.floor(Math.random() * choices.length);
computer.currentChoice = choices[randomIndex]
}
//using dot-method to access the array
function compareChoices() {
computerChooses();
if (computer.currentChoice === player.currentChoice) {
postResult("It's a tie! Both players chose " + player.currentChoice);
//conditionals computer against player
} else if (computer.currentChoice === choices[0]) {
if (player.currentChoice === choices[1]) {
postResult("The Player wins.");
player.playerScore += 1
} else {
postResult("The Computer wins.");
computer.computerScore += 1
}
} else if (computer.currentChoice === choices[1]) {
if (player.currentChoice === choices[2]) {
postResult("The Player Wins")
player.playerScore += 1
} else {
postResult("The Computer wins.");
computer.computerScore += 1
}
} else if (computer.currentChoice === choices[2]) {
if (player.currentChoice === choices[0]) {
postResult("The Player wins.");
player.playerScore += 1
} else {
postResult("The Computer wins.")
computer.computerScore += 1
}
}
}
function postResult(results) {
const resultText = document.createElement('p');
resultText.innerText = results;
document.body.appendChild(resultText);
}
compareChoices();
function weaponSelect() {
document.getElementById
}
document.getElementById('button').addEventListener('click', buttonSelect)
buttonSelect();

from your example, I took the liberty to change things a bit by creating a function to hold the core game, and then call it to play 10 times and show the result
the idea is to divide the use of the game from the game implementation as it should not be the game concern to count how many times a player won, the game should focus only on running the game itself, that is the most basic principle of programming together with DRY (Do not Repeat Yourself)...
I start with the implementation by using the javascript Classes that wraps all the game should do...
will hold the 3 variables
will be able to automatically choose an option
as well ask for one
and passing 2 options, will determine the winner
Then I started by using it to run 10 times and calculate the winner for each time... completely independent from the game it self.
I've commented the code, let me know if something's off...
// game
class RpsGame {
constructor() {
this.options = ["rock", "paper", "scissors"];
[this.ROCK, this.PAPER, this.SCISSORS] = this.options;
}
// will ask the player for a manual input
askPlayerSelection = () => {
var s = null;
while (s == null) {
s = prompt(`What do you want to play? press 1: ${ROCK} 2: ${PAPER} 3: ${SCISSORS}`);
try {
s = parseInt(s, 10); // convert to integer
if (!Number.isInteger(s) || s < 1 && s > 3) s = null; // has to be valid
}
catch(err) { s = null; } // if not valid, set as null so it asks again
}
return this.options[s-1];
}
// automatically assign an option
getAutoPlayerSelection = () => {
var s = Math.floor(Math.random() * 2); // betwen 0 and 2
return this.options[s];
}
// calculates the winner between player1 and player2
calculateWinner = (player1, player2) => {
// same
if (player1 === player2) return 'DRAW';
// p1 has rock
else if (player1 === this.ROCK) {
if (player2 === this.PAPER) return 'player2';
if (player2 === this.SCISSORS) return 'player1';
}
// p1 has paper
else if (player1 === this.PAPER) {
if (player2 === this.ROCK) return 'player1';
if (player2 === this.SCISSORS) return 'player2';
}
// p1 has scissors
else {
if (player2 === this.PAPER) return 'player1';
if (player2 === this.ROCK) return 'player2';
}
}
}
// #############################################################################################
// let's start the game engine
var engine = new RpsGame();
var selection = { rounds: [], player1: 0, player2: 0 };
// let's play 10 times
for (var i=1; i<10; i += 1) {
var player1 = engine.getAutoPlayerSelection(); // change to engine.askPlayerSelection if manual input
var player2 = engine.getAutoPlayerSelection();
var winner = engine.calculateWinner(player1, player2);
selection.rounds.push(winner); // save the winner
if (winner !== 'DRAW') selection[winner] += 1; // append
}
// put result in the HTML
document.querySelector('pre').innerHTML = JSON.stringify(selection, null, 2);
pre {
background-color: #eef;
padding: 10px;
}
<pre></pre>
in order to test, click Run code snippet as many times you want to run the 10 times

Related

How I make my function in a rock, pepper, scissors game wait for a button press in Javascript?

So I have this code(I added the whole JS code but the part I want help is in the function game) that simply runs 5 rounds of a game of rock, papper, scissors with a press of a button in my html file.
The thing is that each round I want the function to wait for a button click of any of the three buttons (rock, papper or scissors)
I will appriciate any help, thank you and have a nice day!
let rock = "Rock";
let papper = "Papper";
let scissors = "Scissors";
let wins = 0;
let playerSelection;
const btnrock = document.getElementById('btn1');
const btnpapper = document.getElementById('btn2');
const btnscissors = document.getElementById('btn3');
const btnplay = document.getElementById('game')
function getPlayerChoice() {
btnrock.addEventListener('click', () => {
playerSelection = rock;
return playerSelection;
});
btnpapper.addEventListener('click', () => {
playerSelection = papper;
return playerSelection;
});
btnscissors.addEventListener('click', () => {
playerSelection = scissors;
return playerSelection;
});
}
btnplay.addEventListener('click', game)
function getComputerChoice() {
let min = Math.ceil(0);
let max = Math.floor(2);
let random = Math.floor(Math.random() * (max - min + 1) + min);
if (random == 0)
{
return rock;
}
if (random == 1){
return papper;
}
if (random == 2){
return scissors;
}
}
function playRound(playerSelection,pcChoice) {
if(pcChoice == rock && playerSelection == papper) {
wins++;
return "Player Wins!";
}
else if (pcChoice == rock && playerSelection == scissors) {
return "Player Loses!"
}
else if (pcChoice == scissors && playerSelection == rock){ wins++; return "Player Wins!"}
else if (pcChoice == scissors && playerSelection == papper){return "Player Loses!"}
else if (pcChoice == papper && playerSelection == rock){return "Player Loses!"}
else if (pcChoice == papper && playerSelection == scissors){wins++; return "Player Wins!"}
else {return "It's a Draw!"}
}
function game() {
for(let i = 0; i < 5; i++){
const pcChoice = getComputerChoice();
playerSelection = getPlayerChoice(); // I want this to wait
console.log("PC "+ pcChoice );
console.log('Player '+playerSelection);
let roundwinner = playRound(playerSelection,pcChoice);
console.log(roundwinner);
if(i === 2 && wins == 0){
break;
}
if(i === 3 && wins <= 1) {
break;
}
if(wins==3){
break;
}
}
if(wins >= 3) {
console.log("You are the winner of this match")
}
else {console.log('You lost the game');}
}
getPlayerChoice doesn't really get the player's choice - it adds event listeners. Run it 5 times and you get 5 listeners hooked up to the same event. I don't think you can wait for an event to fire in a loop like you're currently trying to. This would be a perfectly fine design in a console app when you want some input from the user, but in JS when working with events you have to leverage the events to execute your game's logic.
In other words, you might want to get rid of the for loop and consider moving that logic to event chain with a listener that first adds the user's input to the board and then executes the follow logic - e.g. gets the computer choice or determines whether the game is finished or not.

A program returns 'undefined' after returning correct values. (Rock Paper Scissors game)

I wrote this program and it behaves the way I planned and returns correct results.
Except, it also returns 'undefined' too, after displaying game results in the console.
I searched and read similar posts about 'function returning undefined' and still don't fully get the concept behind.
From which function am I getting 'undefined' in my code? why and how to fix it?
const options = ['Rock', 'Paper', 'Scissor']
let playerScore = 0;
let computerScore = 0;
function computerPlay() {
// Randomly choose the computer's option from the options array.
let computerChoice =
options[Math.floor(Math.random() * options.length)];
return computerChoice;
}
function capitalizeUserInput(playerInput) {
// Turn user input to a capitalized string.
playerInput = playerInput[0].toUpperCase()
+ playerInput.slice(1).toLowerCase();
return playerInput;
}
function playRound(comSelect, playerSelect) {
// Create a variable to return the result.
let result;
// If result is tie, return draw.
if (comSelect == playerSelect) {
return result = "draw";
// If User wins, increment the user score and return win.
} else if (comSelect == 'Rock' && playerSelect == 'Paper' ||
comSelect == 'Paper' && playerSelect == 'Scissor' ||
comSelect == 'Scissor' && playerSelect == 'Rock') {
playerScore += 1;
return result = "win";
// If Computer wins, increment the computer score and return lose.
} else {
computerScore += 1;
return result = "lose";
}
}
function game(totalRound = 5) {
let gamePlayed = 0;
while (gamePlayed < totalRound) {
let player = prompt('Rock, paper or scissor?!')
let computer = computerPlay();
player = capitalizeUserInput(player);
result = playRound(computer,player);
if (result == 'win') {
console.log(`${player} beats ${computer}, you won.`);
} else if (result == 'lose') {
console.log(`${computer} beats ${player}, you lost.`);
} else {
console.log('Draw!');
}
gamePlayed ++;
}
return displayGameResult(computerScore, playerScore);
}
function displayGameResult(computerScore, playerScore) {
if (computerScore > playerScore) {
console.log(`${computerScore}:${playerScore} You lost.`);
} else if (playerScore > computerScore) {
console.log(`${computerScore}:${playerScore} You won.`);
} else {
console.log(`${computerScore}:${playerScore} Record Tie!`);
}
}
console.log(game(5));
you are loggin the return of the function game() by doing this console.log(game(5));
but the function game is returning displayGameResult(computerScore, playerScore) and this function doesn't return anything and so you are logging undefined;
Just try to add return "not undefined ;) :P"; at the end of the displayGameResult function and you will not have undefined anymore
Your problem is that you are calling console.log(game(5));, game() is doing return displayGameResult(computerScore, playerScore);, but the problem is that displayGameResult() is not returning anything, so it returns undefined.
You can fix this by simply changing console.log(game(5)); to just game(5) and changing return displayGameResult(computerScore, playerScore); to displayGameResult(computerScore, playerScore); because these functions are not returning anything important and using their console.log() functions independently to console the result of the game.

I am new to JS and I am stuck when trying to bring the user back to the beginning of the program after user clicks OK in confirm

I was told to make paper scissors or rock game using javascript. After the user gets to the end of the script, I need to know how to make a function or I think that is what you need when a user clicks "OK" in confirm, the true value will bring the user to the start until the user clicks cancel. But even if I make a function, where would I plug that in? Thank you so much all!
Here is what I have so far...
alert("Welcome to Rock Paper Scissors Game! Press OK to continue");
prompt("Type in P for Paper, R for Rock, Or S for Scissors!")
const storedLetters = ["R", "P", "S"];
const rockPaperScissors = storedLetters[Math.floor(Math.random() * storedLetters.length)];
console.log(rockPaperScissors);
var howManyTimesDidYouWin = 0;
var howMayTimesDidILose = 0;
var howManyTimesDidItie = 0;
// Scanner mySccanner = new Scanner(System.in);
if(prompt = "R") {
alert("1, 2, 3! " + rockPaperScissors);
if(rockPaperScissors == "R") {
alert("We have Tied!");
} else if (rockPaperScissors == "P") {
alert("Computer has won!");
} else {
alert("You have won!");
}
} else if(prompt = "P") {
alert("1, 2, 3! " + rockPaperScissors);
if(rockPaperScissors == "P") {
alert("We have Tied!");
} else if (rockPaperScissors == "S") {
alert("Computer has won!");
} else {
alert("You have won!");
}
} else if(prompt =="S") {
alert("1, 2, 3! " + rockPaperScissors);
if(rockPaperScissors = "S") {
alert("We have Tied!");
} else if (rockPaperScissors == "R") {
alert("Computer has won!");
} else {
alert("You have won!");
}
}
if (alert = "We have Tied") {
howManyTimesDidItie++;
} else if (alert = "You have won!") {
howManyTimesDidYouWin++;
} else if (alert = "Computer has won!") {
howMayTimesDidILose++;
}
console.log(`Your total wins are: ${howManyTimesDidYouWin} and Your Loss are: ${howMayTimesDidILose} and You Tied: ${howManyTimesDidItie}`);
let confirmation = confirm(`Do you want to play again? If Yes, press "OK"! If you do not wish to continue, press "Cancel"`);
//This is where I get stuck!
// if(confirmation == false) {
// break;
// } else {
// continue;
// while(confirmation == true) {
// }
// while(confirmation) {
// continue;
// }
// while(confirmation = true) {
// continue;
// }
// var returnToStart = function() {
// if(confirmation == true) {
// continue;
// } else {
// break;
// }
With a bit of refactoring and extracting common logic into functions, you could make the whole program a bit simpler and achieve the repetitiveness that you want.
I've extracted the counts of each situation into constants so that you can easily track the stats.
I've also added repetitive game logic into it's own function which is then used in the logic where the game is running (runGame()).
This allows us to reuse the repetitive code. Then, I've put the whole game logic into the playGame() function, and finally, the game() function is responsible for taking in the player's input and running the whole game in a loop all over again until the player cancels.
let WIN_COUNT = 0;
let LOSE_COUNT = 0;
let TIE_COUNT = 0;
function gameLogic(rockPaperScissors, firstLetter, secondLetter) {
alert("1, 2, 3! " + rockPaperScissors);
if (rockPaperScissors === firstLetter) {
alert("We have Tied!");
TIE_COUNT++;
} else if (rockPaperScissors === secondLetter) {
alert("Computer has won!");
LOSE_COUNT++;
} else {
alert("You have won!");
WIN_COUNT++;
}
}
function runGame(input, rockPaperScissors, letters) {
if (input === letters[0]) {
gameLogic(rockPaperScissors, letters[0], letters[1]);
} else if (input === letters[1]) {
gameLogic(rockPaperScissors, letters[1], letters[2]);
} else if (input === letters[2]) {
gameLogic(rockPaperScissors, letters[2], letters[0]);
}
}
function playGame() {
alert("Welcome to Rock Paper Scissors Game! Press OK to continue");
const input = prompt("Type in P for Paper, R for Rock, Or S for Scissors!");
const storedLetters = ["R", "P", "S"];
const rockPaperScissors =
storedLetters[Math.floor(Math.random() * storedLetters.length)];
console.log(rockPaperScissors);
runGame(input, rockPaperScissors, storedLetters);
console.log(
`Your total wins are: ${WIN_COUNT} and Your Loss are: ${LOSE_COUNT} and You Tied: ${TIE_COUNT}`
);
}
function game() {
let playAgain = true;
while (playAgain !== false) {
playGame();
playAgain = confirm(
`Do you want to play again? If Yes, press "OK"! If you do not wish to continue, press "Cancel"`
);
}
}
game();
You need to separate different logics into functions you can call individually. In the example below, I created 4 functions: gameInit, gameStart, askUser and checkResult.
gameInit resets all stats to zero then starts the game by calling gameStart.
gameStart starts the game and saves the results. After this, the user is then prompted if he/she wants to continue playing or whether to reset all stats and play again. Calls gameInit for reset, gameStart for continue.
askUser prompts the user for his choice, making sure that it is valid. R, P and S (case-insensitive).
checkResult checks the result using the predefined variable judge.
I also tweaked some of your code so it looks a little readable (i.e., removed the too many if-else).
const storedLetters = ['r', 'p', 's'];
//store here for easy message formatting.
const rpsNames = ['rock', 'paper', 'scissors'];
// yeah, here's the judge that tells you which option
// will beat the one in the right
const judge = {
'rock': 'scissors', // r beats s
'paper': 'rock', // p beats r
'scissors': 'paper' // s beats p
};
// store here so we can easily access using `msgs[result]`
const msgs = {
tie: 'We have Tied!',
lose: 'Computer has won!',
win: 'You have won!'
};
// store results as objects so we can do `results[result]++`
// instead of incrementing different variables using `if-else`
var results = {
win: 0,
lose: 0,
tie: 0
};
function gameInit() {
alert("Welcome to Rock Paper Scissors Game! Press OK to continue");
results = {
win: 0,
lose: 0,
tie: 0
};
gameStart();
}
function gameStart() {
let userLetter = askUser();
let userIdx = storedLetters.indexOf(userLetter);
let userSelect = rpsNames[userIdx];
let compSelectIdx = Math.floor(Math.random() * 3); //randomly select 0-2
let compSelect = rpsNames[compSelectIdx];
alert("1, 2, 3! Computer picks " + compSelect);
let res = checkResult(userSelect, compSelect);
let msg = msgs[res];
alert(`${msg} You: ${userSelect}, Computer: ${compSelect}`);
//update stats
results[res]++;
alert(`Your total wins are: ${results.win} and Your Loss are: ${results.lose} and You Tied: ${results.tie}`);
let confirmation = confirm(`Do you want to play again? If Yes, press "OK"! If you do not wish to continue, press "Cancel"`);
if (confirmation) {
gameStart();
} else {
let restart = confirm('Do you want to reset all stats and play again?');
if (restart) {
gameInit();
}
}
}
function askUser() {
//make sure use it's not case-sensitive
var res = prompt("Type in P for Paper, R for Rock, Or S for Scissors!");
if (res) {
res = res.toLowerCase();
}
if (storedLetters.indexOf(res) === -1)
return askUser(); //ask again if incorrect selection
else
return res;
}
function checkResult(user, comp) {
if (user === comp) {
return 'tie';
}
var loser = judge[user]; //who loses vs user
// user beats comp
if (loser === comp) {
return 'win';
} else {
return 'lose';
}
}
gameInit();

storing value of a looped function into a variable , javascript

Hey all i need your help. In this rock paper scissor game the winner is the first to get to five wins between the user and computer. Although i have not looped this yet, i need help storing the counts of each win into a variable from my points() function into var playerPoints = 0 ; or
var compPoints = 0 ; depending on who wins the round. if you have loop suggestions feel free to advice me on that as well! thanks
//decalring an array with weapons of choice
const weaponArray = ["rock", "paper", "scissors"];
// selects a random index from array to represent computer choice
const computerChoice = weaponArray[[Math.floor(Math.random() * weaponArray.length)]];
//prompts user to make a choice of weapon
const playerPrompt = prompt("Please enter Rock, Paper, or Scissors!");
//lowers all alphabet input to lower case
const playerChoice = playerPrompt.toLowerCase();
//function runs player vs computer choices and determines winner of round
const round = (computerChoice, playerChoice) => {
if (playerChoice === "scissors" && computerChoice === "rock" || playerChoice === "rock" && computerChoice === "paper" || playerChoice ==="paper" && computerChoice === "scissors") {
return "Just Give Up Now Looser!";
}
else if (playerChoice === "rock" && computerChoice === "scissors" || playerChoice === "paper" && computerChoice === "rock" || playerChoice==="scissors" && computerChoice === "paper")
{
return "You Won This Round!";
}
else {
return "Its a Tie!";
}
};
//stores round function value into a variable
var state = round(computerChoice, playerChoice);
// adds points to player or computer based on "state" value
const points = () => {
if (state === "You Won This Round!"){
return playerPoints + 1;
}
else if (state === "Just Give Up Now Looser!"){
return compPoints + 1;
}
else{
return null
}
};
var playerPoints = points() ;
var compPoints = points() ;
console.log(state);
console.log(points());
//console.log(compPoints);
//console.log(playerPoints);
Might as well add my answer here. I wouldn't use a prompt approach, but buttons instead. Store the scores in an object and use a conditional to check if someone has reached five points after each game:
const userScore = document.querySelector('.user .score')
const computerScore = document.querySelector('.computer .score')
const resultContainer = document.querySelector('.result')
const userThrowContainer = document.querySelector('.userThrow')
const opponentThrowContainer = document.querySelector('.opponentThrow')
const buttons = document.querySelectorAll('button')
const score = {
user: 0,
computer: 0
}
function rpsMatch(userThrow) {
// Define possible throws
const throwOptions = [
'rock',
'paper',
'scissors'
]
// Choose randomly from array of throws
let opponentThrow = throwOptions[Math.floor(Math.random() * throwOptions.length)]
// Print user and computer throws
userThrowContainer.innerText = `You threw ${userThrow}`
opponentThrowContainer.innerText = `Computer threw ${opponentThrow}`
function userWins() {
resultContainer.innerText = 'You win'
score.user++
updateScores()
}
function computerWins() {
resultContainer.innerText = 'You lose'
score.computer++
updateScores()
}
function updateScores() {
userScore.innerText = score.user
computerScore.innerText = score.computer
}
function resetScore() {
userScore.innerText = 0
computerScore.innerText = 0
score.user = 0
score.computer = 0
}
// RPS logic
if (userThrow == opponentThrow) {
resultContainer.innerText = 'You tied'
} else {
if (userThrow == 'rock') {
opponentThrow == 'scissors' ? userWins() : computerWins()
} else if (userThrow == 'paper') {
opponentThrow == 'rock' ? userWins() : computerWins()
} else {
opponentThrow == 'paper' ? userWins() : computerWins()
}
}
if (score.user === 5) {
alert('You won the first to 5!')
resetScore()
}
if (score.computer === 5) {
alert('You lost the first to 5!')
resetScore()
}
}
// Attach event handlers to each button
buttons.forEach(button => {
button.addEventListener('click', e => {
// Assign data attribute to variable
let userThrow = e.target.dataset.type
e.preventDefault()
// Pass user selection to rpsMatch
rpsMatch(userThrow)
})
})
<div class="user">User Score: <span class="score">0</span></div>
<div class="computer">Computer Score: <span class="score">0</span></div>
<button data-type="rock">Rock</button>
<button data-type="paper">Paper</button>
<button data-type="scissors">Scissors</button>
<div class="userThrow"></div>
<div class="opponentThrow"></div>
<div class="result"></div>
I would not use prompt but HTML buttons to get the user's input. That way they don't have to type, just click.
Here is how you could do it:
//declaring an array with weapon of choice
const weaponArray = ["rock", "paper", "scissors"];
const players = ["tie", "you", "computer"];
const points = [0, 0, 0]; // tie, player, computer
const human = document.querySelector('#human');
const computer = document.querySelector('#computer');
const winner = document.querySelector('#winner');
const humanScore = document.querySelector('#humanScore');
const computerScore = document.querySelector('#computerScore');
// Respond to input
document.querySelector("#buttons").onclick = function(e) {
const playerChoice = +e.target.value; // 0, 1 or 2
human.textContent = weaponArray[playerChoice];
// selects a random index from array to represent computer choice
const computerChoice = Math.floor(Math.random() * weaponArray.length); // 0, 1 or 2
computer.textContent = weaponArray[computerChoice];
// Determine result
const result = (playerChoice + 3 - computerChoice) % 3; // 0 = tie, 1 = player win, 2 = computer win
winner.textContent = players[result];
// add point to the relevant winner. Winner 0 represents the ties - they don't really count
points[result]++;
humanScore.textContent = points[1];
computerScore.textContent = points[2];
if (result && points[result] >= 5) {
alert("Game over. " + players[result] + " won");
location.reload();
}
}
Please make your choice:<br>
<div id="buttons">
<button value="0">rock</button> <button value="1">paper</button> <button value="2">scissors</button><br>
</div>
Your weapon: <span id="human"></span><br>
Computer's weapon: <span id="computer"></span><br>
Winner: <span id="winner"></span><br>
Your score: <span id="humanScore"></span><br>
Computer's score: <span id="computerScore"></span><br>

Rock Paper Scissors Javascript Game Add Choice Limit

I've created a Javascript-based Rock Paper Scissors game and it's pretty good so far. However, I want to create an option for "best out of 3" or "best out of 5". Please could some of you awesome JS people have a look at my code and see how I could implement the best of "x" scenario. Basically, I guess it comes down to the number of clicks.
Anyway, the code speaks for itself and here is a live example of the code:
Rock Paper Scissors Live Github Example
And the code:
(function(){
/*
* Rock, paper, scissors
*
* The classic game recreated in Javascript for playing in the browser.
*
*/
// create the choices
var choices = [
'rock',
'paper',
'scissors'
];
var CHOICES_LENGTH = choices.length;
// create the text for winning or drawing
var USER_WINS = "You win!";
var COMP_WINS = "Computer wins";
var DRAW = "Draw"
var MEH = '<i class="fa fa-meh-o" aria-hidden="true"></i>';
var SMILE = '<i class="fa fa-smile-o" aria-hidden="true"></i>';
var FROWN = '<i class="fa fa-frown-o" aria-hidden="true"></i>';
var score = 0;
var computer_score = 0;
var gameType;
var clicks = 0;
// score elements
var userScore = getById('score');
var compScore = getById('computerScore');
userScore.textContent = score;
compScore.textContent = computer_score;
// get the game area and get access to all the buttons
var game = getById('game');
var userChoices = game.getElementsByTagName('button');
var comp = getById('computer');
var compChoices = comp.getElementsByTagName('div');
// get the results element and hide it initially
var results = getById('results');
hide(results);
var gameOver = getById('gameOver');
hide(gameOver);
// get the intro element and the buttons for choosing a game type
var intro = getById('intro');
var bestOf3 = getById('bestOf3');
var bestOf5 = getById('bestOf5');
// start the best of 3 game
bestOf3.onclick = function() {
enableGame();
gameType = 3;
}
bestOf5.onclick = function() {
enableGame();
gameType = 5;
}
function enableGame() {
enable(userChoices);
hide(intro);
}
// add an onclick event to each button and disable them initially
for(var i = 0; i < userChoices.length; i++) {
userChoices[i].onclick = selection;
userChoices[i].disabled = true;
}
function computerSelection() {
var randomIndex = Math.floor(Math.random() * CHOICES_LENGTH);
var compChoice = choices[randomIndex];
return compChoice;
}
function selection() {
// get the user and computer choice
var chosen = this.id;
var comp = computerSelection();
// get the users chosen item
var chosenItem = getById(chosen);
// prepare the chosenCompItem so we can assign it to a dynamic id
var chosenCompItem;
if(comp === 'rock') {
chosenCompItem = getById('computerRock');
}
else if(comp === 'paper') {
chosenCompItem = getById('computerPaper');
}
else if(comp === 'scissors') {
chosenCompItem = getById('computerScissors');
}
// show results and disable all choices so no more can
// be made while waiting for the pop up to fade out
show(results);
reappear(results);
disable(userChoices);
disable(compChoices);
// make the selected item stand out from the rest
chosenItem.classList.add('selected');
chosenCompItem.classList.add('selected');
// decide who wins
if(chosen === comp) {
results.textContent = DRAW;
// ugly repetive code. what can I do???
timeout();
results.innerHTML += MEH;
}
else if(chosen === 'rock' && comp === 'scissors') {
results.textContent = USER_WINS;
score += 1;
userScore.textContent = score;
timeout();
results.innerHTML += SMILE;
}
else if(chosen === 'paper' && comp === 'rock') {
results.textContent = USER_WINS;
score += 1;
userScore.textContent = score;
timeout();
results.innerHTML += SMILE;
}
else if(chosen === 'scissors' && comp === 'paper') {
results.textContent = USER_WINS;
score += 1;
userScore.textContent = score;
timeout();
results.innerHTML += SMILE;
}
else {
results.textContent = COMP_WINS;
computer_score +=1;
compScore.textContent = computer_score;
timeout();
results.innerHTML += FROWN;
}
console.log(clicks);
}
// utilities
function getById(id) {
return document.getElementById(id);
}
function hide(element) {
element.style.display = 'none';
}
function show(element) {
element.style.display = 'block';
}
function disappear(element) {
element.className = 'disappear';
}
function reappear(element) {
element.className = 'reappear';
}
function disable(elements) {
for(var i = 0; i < elements.length; i++) {
elements[i].disabled = true;
elements[i].classList.add('unselected');
}
}
function enable(elements) {
for(var i = 0; i < elements.length; i++) {
elements[i].disabled = false;
elements[i].classList.add('default');
elements[i].classList.remove('selected', 'unselected');
}
}
function timeout() {
setTimeout(function(){
disappear(results);
enable(userChoices);
enable(compChoices);
}, 2000)
}
})();
The code has massive room for improvement but the main thing here is, how do I make it so the user gets only 3 or 5 plays??
Hope this all makes sense.
Thanks
Assuming your definition of best of "N" is the same as mine, my code should work.
My definition of "best of N" is:
To win, one person must win N/2 rounds, with N/2 being rounded up to the nearest whole number.
You could use this code:
if(userScore + compScore === gameType) { gameOver(); }
And use a simple if statement to see who won.
Hope this helped!

Categories

Resources