Rock Paper Scissors assigning points each round - javascript

newbie here! Just starting learning week and a half ago. Creating the rock paper scissors game. The goal is to play 5 rounds against the computer to determine the overall winner. I'm a little stumped when it comes to how I can award the player a point if they win or the computer a point if it wins. Also all critiques of code are welcome as well.
Thanks a ton!
code so far...
let array = ['rock', 'paper', 'scissor'];
const getComputerChoice = () => {
let random = Math.floor((Math.random() * 3));
let randomNames = array[random];
return randomNames;
}
const game = () => {
for (let i = 0; i < 5; i++) {
let input = prompt('Choose rock, paper or scissor');
const playerSelection = input.toLowerCase();
const computerChoice = getComputerChoice();
const computerWins = `Computer Wins! ${computerChoice} beats ${playerSelection}.`;
const playerWins = `Player wins! ${playerSelection} beats ${computerChoice}.`;
const tie = `It's a tie, ${playerSelection} is equal to ${computerChoice}.`;
if (playerSelection !== 'rock' && playerSelection !== 'paper' && playerSelection !== 'scissor') {
i = i - 1;
console.log("Nice try! Please enter a valid input.");
}
if (playerSelection === 'rock' && computerChoice === 'paper' || playerSelection === 'paper' && computerChoice === 'scissor' || playerSelection === 'scissor' && computerChoice === 'rock') {
console.log(computerWins);
}
if (playerSelection === 'paper' && computerChoice === 'rock' || playerSelection === 'scissor' && computerChoice === 'paper' || playerSelection === 'rock' && computerChoice === 'scissor') {
console.log(playerWins);
} else {
if (playerSelection === computerChoice) {
console.log(tie);
}
}
}
}
game();

just add variable of score and increment after each win
let array = ['rock', 'paper', 'scissor'];
let player_score=0;
let computer_score=0;
const getComputerChoice = () => {
let random = Math.floor((Math.random() * 3));
let randomNames = array[random];
return randomNames;
}
const game = () => {
for (let i = 0; i < 5; i++) {
let input = prompt('Choose rock, paper or scissor');
const playerSelection = input.toLowerCase();
const computerChoice = getComputerChoice();
const computerWins = `Computer Wins! ${computerChoice} beats ${playerSelection}.`;
const playerWins = `Player wins! ${playerSelection} beats ${computerChoice}.`;
const tie = `It's a tie, ${playerSelection} is equal to ${computerChoice}.`;
if (playerSelection !== 'rock' && playerSelection !== 'paper' && playerSelection !== 'scissor') {
i = i - 1;
console.log("Nice try! Please enter a valid input.");
}
if (playerSelection === 'rock' && computerChoice === 'paper' || playerSelection === 'paper' && computerChoice === 'scissor' || playerSelection === 'scissor' && computerChoice === 'rock') {
computer_score+=1;
console.log(computerWins);
}
if (playerSelection === 'paper' && computerChoice === 'rock' || playerSelection === 'scissor' && computerChoice === 'paper' || playerSelection === 'rock' && computerChoice === 'scissor') {
player_score+=1;
console.log(playerWins);
} else {
if (playerSelection === computerChoice) {
console.log(tie);
}
}
}
console.log("Computer:"+computer_score+' vs '+'Player:'+player_score);
}
game();

Like Wiktor said in his comment, you can store the victories in variables, that you increment every time someone wins.
Before your for loop, you you'd initialize two variables, one for Computer wins, and one for Human wins:
var compWins = 0;
var humanWins = 0;
Then, when someone wins, you would increment the appropriate variable:
compWins++;
or
humanWins++;

You can add 2 variables like.
let playerPoints = 0;
let computerPoints = 0;
then, where you console.log the winner of a round you can add 1 at their counter.
if (playerSelection === 'rock' && computerChoice === 'paper' || playerSelection === 'paper' && computerChoice === 'scissor' || playerSelection === 'scissor' && computerChoice === 'rock') {
computerPoints += 1
console.log(computerWins);
}
if (playerSelection === 'paper' && computerChoice === 'rock' || playerSelection === 'scissor' && computerChoice === 'paper' || playerSelection === 'rock' && computerChoice === 'scissor') {
playerPoints += 1
console.log(playerWins)
Then you have the points. With them you can add another if to control if someone has won (when reach 3 points for example).

Do not use prompt(), confirm(), or alert(), they are horrible for UX. You need to use HTML if you are interacting with the user preferably <form> and form controls which are designed specifically for user interaction.
Details are commented in example
// Define the scores outside of event handler
let w = 0,
l = 0,
d = 0,
turns = 5;
// Reference the <form>
const rps = document.forms.rps;
// Event handler passes event object by default
const game = (e) => {
// Reference the tag user clicked
const clicked = e.target;
// If the user clicked a <button>...
if (clicked.matches('button')) {
// Decrement turn counter
turns--;
// Get a random number in the range of 0 to 2
const opponent = 3 * Math.random() << 0;
// Get the value of the <button> user clicked (will be 0 to 2)
const player = +clicked.value;
/*
Index number of the array is determined by the number of the player
and opponent
*/
const icon = ['🪨', '🧻', '✂️'];
const playerIcon = icon[player];
const opponentIcon = icon[opponent];
// Message is determined by outcome
const L = `Opponent wins! ${opponentIcon} beats ${playerIcon}.`;
const W = `You win! ${playerIcon} beats ${opponentIcon}.`;
const D = `It's a tie, ${playerIcon} does nothing to ${opponentIcon}.`;
/*
Outcome is determined by player and opponent numbers, the syntax is a chained
ternary -- it's an abbreviated "if/else if/else" statement:
¹If player equals opponent return D(raw)
²Else if player equals opponent +1 return W(ins)
³Else if player is 0 and opponent is 2 return W(ins)
⁴Else return L(ost)
*/
let outcome = player === opponent ? D : // ¹
player === opponent + 1 ? W : // ²
player === 0 && opponent === 2 ? W : L; // ³ : ⁴
// Reference all form controls (everything except the <label>s)
const fc = e.currentTarget.elements;
// Reference each <output>
const msg = fc.msg;
const wins = fc.wins;
const lost = fc.lost;
const draw = fc.draw;
const btns = Array.from(fc.btn);
const start = fc.start;
/*
Pass in the outcome (it's either D, W, or L)
Each case basically increments the associated score and shows the
associated message.
*/
switch (outcome) {
case D:
draw.value = ++d;
msg.value = D;
break;
case W:
wins.value = ++w;
msg.value = W;
break;
case L:
lost.value = ++l;
msg.value = L;
break;
default:
break;
}
/*
If turns is less than 1...
...display game over message...
...show reset <button>...
...hide the RPS <button>s...
...reset the turns counter scores
*/
if (turns < 1) {
msg.value = `5 turns, game over.`;
start.style.display = 'inline-block';
btns.forEach(b => b.style.display = 'none');
turns = 5, w = 0, l = 0, d = 0;
}
}
}
// Bind the click event to <form>
rps.onclick = game;
// Bind the reset event to <form>
rps.onreset = e => {
// Reference all form controls hide reset <button> show RPS <button>s
const fc = e.currentTarget.elements;
fc.start.style.display = 'none';
Array.from(fc.btn).forEach(b => b.style.display = 'inline-block');
}
html {
font: 300 3ch/1.25 'Segoe UI';
}
form {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
min-height: 100vh;
}
fieldset {
display: flex;
justify-content: space-evenly;
align-items: center;
min-width: 350px;
}
output {
font-family: Consolas
}
#msg {
font-family: 'Segoe UI';
}
button {
font: inherit;
cursor: pointer;
}
[type="reset"] {
display: none
}
<form id='rps'>
<fieldset>
<legend>Roshambo</legend>
<button name='btn' type='button' value='0'>🪨</button>
<button name='btn' type='button' value='1'>🧻</button>
<button name='btn' type='button' value='2'>✂️</button>
<button id='start' type='reset'>Play Again</button>
</fieldset>
<fieldset>
<output id='msg'> </output>
</fieldset>
<fieldset>
<label>Wins: <output id='wins'>0</output></label>
<label>Lost: <output id='lost'>0</output></label>
<label>Draw: <output id='draw'>0</output></label>
</fieldset>
</form>

Related

Rock,Paper&Scissors game problem in JavaScript

Whenever I run the code , computer-Point has score 1 before the game
started . Second issue that I couldn't figure out is that how to set a
play round for 5 set. these are the JavaScript code
describe the values
set computer choices
set check-winner Function
set Player choices
set game function
````
var playerPoint = 0;
var computerPoint = 0;
const userScore_p = document.querySelector(".human > p");
const computerScore_p = document.querySelector(".machine > p");
const result_p = document.querySelector('.result > p');
const rock = document.getElementById('rock')
const paper = document.getElementById('paper');
const scissors = document.getElementById('scissors');
const playerSelection = [rock, paper, scissors]
const weapons = ["rock", "paper", "scissors"];
// set the computer random choice
function getComputerChoice(){
const choice = weapons[Math.floor(Math.random() * weapons.length)];
return choice;
}
function checkWinner(playerSelection) {
const computerSelection = getComputerChoice();
if (playerSelection == computerSelection) {
result_p.textContent = "Tie";
}
else if ((playerSelection == "rock" && computerSelection == "scissors") ||
(playerSelection == "scissors" && computerSelection == "paper") ||
(playerSelection == "paper" && computerSelection == "rock")) {
result_p.textContent = "player Winnnn";
playerPoint++;
userScore_p.innerHTML = playerPoint;
} else {
result_p.textContent = "Player lost!!!!";
computerPoint++;
computerScore_p.innerHTML = computerPoint;
}
console.log(computerSelection)
console.log(playerSelection);
}
function getPlayerChoice() {
rock.addEventListener("click", function () {
checkWinner("rock");
});
paper.addEventListener("click", function() {
checkWinner("paper");
});
scissors.addEventListener("click", function() {
checkWinner("scissors")
});
}
function game() {
const computerSelection = getComputerChoice();
for (let i = 0; i < 5; i++) {
if (playerPoint > computerPoint) {
result_p.innerHTML = "you won the game"
} else if (playerPoint < computerPoint) {
result_p.innerHTML = "you lose the game"
} else {
result_p.innerHTML = "Drawwww"
}
}
}
game()
checkWinner();
getPlayerChoice();
````
The problem here is, player is not going to choose a weapon until they click on 1 of the 3 buttons, so when you call the function getPlayerChoice() it actually doesn't mean the player clicked on one of those buttons.
You should process the logics inside the checkWinner() function, which is called whenever the user clicks on a button.
let playerPoint = 0;
let computerPoint = 0;
const userScore_p = document.querySelector(".human > p");
const computerScore_p = document.querySelector(".machine > p");
const result_p = document.querySelector('.result > p');
const rock = document.getElementById('rock')
const paper = document.getElementById('paper');
const scissors = document.getElementById('scissors');
const playerSelection = [rock, paper, scissors]
rock.addEventListener("click", function() {
checkWinner("rock");
});
paper.addEventListener("click", function() {
checkWinner("paper");
});
scissors.addEventListener("click", function() {
checkWinner("scissors")
});
const weapons = ["rock", "paper", "scissors"];
// set the computer random choice
function getComputerChoice() {
const choice = weapons[Math.floor(Math.random() * weapons.length)];
return choice;
}
function checkWinner(playerSelection) {
const computerSelection = getComputerChoice();
if (playerSelection == computerSelection) {
result_p.textContent = "Tie";
} else if ((playerSelection == "rock" && computerSelection == "scissors") ||
(playerSelection == "scissors" && computerSelection == "paper") ||
(playerSelection == "paper" && computerSelection == "rock")) {
result_p.textContent = "player Winnnn";
playerPoint++;
userScore_p.innerHTML = playerPoint;
} else {
result_p.textContent = "Player lost!!!!";
computerPoint++;
computerScore_p.innerHTML = computerPoint;
}
console.log(computerSelection)
console.log(playerSelection);
}
<button id="rock">rock</button>
<button id="paper">paper</button>
<button id="scissors">scissors</button>
<div>
HUMAN
<div class="human">
<p>0</p>
</div>
</div>
<div>
MACHINE
<div class="machine">
<p>0</p>
</div>
</div>
<div>
RESULT
<div class="result">
<p></p>
</div>
</div>

For loop works well on Firefox but not on Chrome

I'm trying to understand why my code works well on Firefox and not on Chrome.
Basically what happens is that on Firefox the loop works and it prints the outputs on the page at every iteration and at the end.
On Chrome it only prints some of the outputs at the end of the loop.
I read that it might have to do with the way I'm asking the code to print the output on the page, which is .textContent, but I also tried to use .innerHtml and the problem persists.
The code is a bit long and I'm sure there is a shorter cleaner way to write, but it is my first project and this is the best I could do at this stage.
Thank you for your help :)
Here is what the html looks like:
const forma = document.querySelector('form');
const out0 = document.getElementById('user-choice');
const out1 = document.getElementById('computer-choice');
const out2 = document.getElementById('game-result');
const out3 = document.getElementById('user-score');
const out4 = document.getElementById('computer-score');
const out5 = document.getElementById('final-result');
// get a ramdom choice between Rock-paper-scissor from Computer
let choices = ['rock', 'paper', 'scissors'];
let randomValue = function computerPlay() {
let randomChoice = choices[Math.floor(Math.random() * choices.length)];
out1.textContent = randomChoice;
return randomChoice;
};
function game() {
let userScore = 0;
let computerScore = 0;
// iterate the function playRound 5 times with a for loop
for (let i = 0; i < 5; i++) {
// prompt an initial message "Rock, paper, scissor" to ask the user to input one of the 3
let sign = prompt("Rock, paper or scissors?");
// use a function to compare the random choice from computer with what the user has input in the prompt and return a result
function playRound(playerSelection, computerSelection) {
if (playerSelection == "rock" && computerSelection == choices[0]) {
i = i -1;
return "It's a tie! Play again!";
} else if (playerSelection == "rock" && computerSelection == choices[1]) {
computerScore = computerScore + 1;
out4.textContent = computerScore;
// this is when the computer wins
if(computerScore == 3) {
i = 5; // so that it practically breaks out of the loop
out5.textContent = "Unfortunately you lost the game :("
} else return "You lose this round! Paper beats rock.";
} else if (playerSelection == "rock" && computerSelection == choices[2]) {
userScore = userScore + 1;
out3.textContent = userScore;
if(userScore == 3) {
i = 5;
out5.textContent = "Congratulations, you won the game!"
} else return "You win this round! Rock beats scissors.";
} else if (playerSelection == "paper" && computerSelection == choices[0]) {
userScore = userScore + 1;
out3.textContent = userScore;
if(userScore == 3) {
i = 5;
out5.textContent = "Congratulations, you won the game!"
} else return "You win this round! Paper beats rock.";
} else if (playerSelection == "paper" && computerSelection == choices[1]) {
i = i -1;
return "It's a tie! Play again!";
} else if (playerSelection == "paper" && computerSelection == choices[2]) {
computerScore = computerScore + 1;
out4.textContent = computerScore;
if (computerScore == 3) {
i = 5;
out5.textContent = "Unfortunately you lost the game :("
} else return "You lose this round! Scissors beat paper.";
} else if (playerSelection == "scissors" && computerSelection == choices[0]) {
computerScore = computerScore + 1;
out4.textContent = computerScore;
if (computerScore == 3) {
i = 5;
out5.textContent = "Unfortunately you lost the game :("
} else return "You lose this round! Rock beats scissors.";
} else if (playerSelection == "scissors" && computerSelection == choices[1]) {
userScore = userScore + 1;
out3.textContent = userScore;
if(userScore == 3) {
i = 5;
out5.textContent = "Congratulations, you won the game!"
} else return "You win this round! Scissors beat paper.";
} else if (playerSelection == "scissors" && computerSelection == choices[2]) {
i = i -1;
return "It's a tie! Play again!";
// this currently doesn't work as it tries to convert the playerSelection toLowerCase, as requested in the let playerSelection = sign.toLowerCase(), but it cannot because the sign is null and so it returns an error that sign is null
} else if(playerSelection === '' || playerSelection === null) {
i = 0;
} else {
i = i -1;
return "I think you forgot how to play this game!";
}
}
// store the playerSelection argument value (equal to user input made lower case) in a variable
let playerSelection = sign.toLowerCase();
// store the computerSelection argument value (equal to radom choice determined by function randomValue) in a variable
let computerSelection = randomValue();
// print the user input made to lower case in the paragraph tag
out0.textContent = sign;
// print the return statement from the function in the out2 tag
out2.textContent= playRound(playerSelection, computerSelection);
}
}
// run the function
game();
And this is my Html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<form>
<strong>Your choice:</strong>
<output type="text" id="user-choice"></output>
</form>
</div>
<div>
<form>
<strong>Computer choice:</strong>
<output type="text" id="computer-choice"></output>
</form>
</div>
<div>
<form>
<strong>Result of this round:</strong>
<output type="text" id="game-result"></output>
</form>
</div>
<div>
<form>
<strong>User score:</strong>
<output type="number" id="user-score"></output>
</form>
</div>
<div>
<form>
<strong>Computer score:</strong>
<output type="number" id="computer-score"></output>
</form>
</div>
<div>
<form>
<strong>Game result:</strong>
<output type="text" id="final-result"></output>
</form>
</div>
<script src="script.js"></script>
</body>
</html>
You can use window.requestAnimationFrame to force the browser to render something. You will need to promisify it however, because requestAnimationFrame has a callback, and does not directly return a promise.
After doing that, your code should look like this:
const forma = document.querySelector('form');
const out0 = document.getElementById('user-choice');
const out1 = document.getElementById('computer-choice');
const out2 = document.getElementById('game-result');
const out3 = document.getElementById('user-score');
const out4 = document.getElementById('computer-score');
const out5 = document.getElementById('final-result');
// get a ramdom choice between Rock-paper-scissor from Computer
let choices = ['rock', 'paper', 'scissors'];
let userScore = 0;
let computerScore = 0;
let randomValue = function computerPlay() {
let randomChoice = choices[Math.floor(Math.random() * choices.length)];
out1.textContent = randomChoice;
return randomChoice;
};
async function game() {
// iterate the function playRound 5 times with a for loop
for (let i = 0; i < 5; i++) {
// prompt an initial message "Rock, paper, scissor" to ask the user to input one of the 3
let sign = prompt("Rock, paper or scissors?");
// use a function to compare the random choice from computer with what the user has input in the prompt and return a result
function playRound(playerSelection, computerSelection) {
if (playerSelection == "rock" && computerSelection == choices[0]) {
i = i - 1;
return "It's a tie! Play again!";
} else if (playerSelection == "rock" && computerSelection == choices[1]) {
computerScore = computerScore + 1;
out4.textContent = computerScore;
// this is when the computer wins
if (computerScore == 3) {
i = 5; // so that it practically breaks out of the loop
out5.textContent = "Unfortunately you lost the game :("
} else return "You lose this round! Paper beats rock.";
} else if (playerSelection == "rock" && computerSelection == choices[2]) {
userScore = userScore + 1;
out3.textContent = userScore;
if (userScore == 3) {
i = 5;
out5.textContent = "Congratulations, you won the game!"
} else return "You win this round! Rock beats scissors.";
} else if (playerSelection == "paper" && computerSelection == choices[0]) {
userScore = userScore + 1;
out3.textContent = userScore;
if (userScore == 3) {
i = 5;
out5.textContent = "Congratulations, you won the game!"
} else return "You win this round! Paper beats rock.";
} else if (playerSelection == "paper" && computerSelection == choices[1]) {
i = i - 1;
return "It's a tie! Play again!";
} else if (playerSelection == "paper" && computerSelection == choices[2]) {
computerScore = computerScore + 1;
out4.textContent = computerScore;
if (computerScore == 3) {
i = 5;
out5.textContent = "Unfortunately you lost the game :("
} else return "You lose this round! Scissors beat paper.";
} else if (playerSelection == "scissors" && computerSelection == choices[0]) {
computerScore = computerScore + 1;
out4.textContent = computerScore;
if (computerScore == 3) {
i = 5;
out5.textContent = "Unfortunately you lost the game :("
} else return "You lose this round! Rock beats scissors.";
} else if (playerSelection == "scissors" && computerSelection == choices[1]) {
userScore = userScore + 1;
out3.textContent = userScore;
if (userScore == 3) {
i = 5;
out5.textContent = "Congratulations, you won the game!"
} else return "You win this round! Scissors beat paper.";
} else if (playerSelection == "scissors" && computerSelection == choices[2]) {
i = i - 1;
return "It's a tie! Play again!";
// this currently doesn't work as it tries to convert the playerSelection toLowerCase, as requested in the let playerSelection = sign.toLowerCase(), but it cannot because the sign is null and so it returns an error that sign is null
} else if (playerSelection === '' || playerSelection === null) {
i = 0;
} else {
i = i - 1;
return "I think you forgot how to play this game!";
}
}
// store the playerSelection argument value (equal to user input made lower case) in a variable
let playerSelection = sign.toLowerCase();
// store the computerSelection argument value (equal to radom choice determined by function randomValue) in a variable
let computerSelection = randomValue();
// print the user input made to lower case in the paragraph tag
out0.textContent = sign;
// print the return statement from the function in the out2 tag
out2.textContent = playRound(playerSelection, computerSelection);
await promisifiedRequestAnimationFrame();
}
}
function promisifiedRequestAnimationFrame() {
return new Promise((resolve, reject) => {
window.requestAnimationFrame(() => {resolve()});
})
}
// run the function
game();
So what exactly changed?
We added a function, that returns a promise that resolves when the requestAnimationFrame is finished executing.
We made game() asynchronous. This allows us to use "await"
But why does it work?
Well, alerts, prompts and confirms are supposed to halt the code until a user does something. Firefox does not allow direct spamming of them, so there is a small time frame between your prompts on FF, but Chrome doesn't really care about that. You want a lot of prompts? Fine! By using window.requestAnimationFrame combined with await we will force chrome to wait until a frame has been drawn.

Rock-paper-scissors game - prompting user input via buttons for certain # of rounds?

Goal is to play five rounds.
For each round, player chooses action by clicking one of three buttons (rock, paper, or scissors), the computer chooses an action randomly, and the outcome of that round is logged.
However, my code ends up taking the player's first action, and then simulating five rounds against computer using the same player action for all five rounds.
let playerScore = 0;
let computerScore = 0;
let i = 0;
while (i < 5) {
document.querySelectorAll('.action').forEach(button => {
button.addEventListener('click', e => {
const outcome = game(e.target.id);
if (outcome === -1)
computerScore += 1;
if (outcome === 1)
playerScore += 1;
});
});
i += 1;
}
if (i == 4) {
console.log("Player score: ", playerScore);
console.log("Computer score: ", computerScore);
}
function computerPlay() {
const turnOutcome = Math.floor(Math.random() * 3);
switch (turnOutcome) {
case 0:
return "rock";
break;
case 1:
return "paper";
break;
case 2:
return "scissors";
break;
}
}
function playRound(playerSelection, computerSelection) {
playerSelection = playerSelection.toLowerCase();
computerSelection = computerSelection.toLowerCase();
if (playerSelection === "rock" && computerSelection === "paper")
return -1;
if (playerSelection === "paper" && computerSelection === "scissors")
return -1;
if (playerSelection === "scissors" && computerSelection === "rock")
return -1;
if (playerSelection === "rock" && computerSelection === "scissors")
return 1;
if (playerSelection === "paper" && computerSelection === "rock")
return 1;
if (playerSelection === "scissors" && computerSelection === "paper")
return 1;
if (playerSelection === computerSelection)
return 0;
}
function game(playerSelection) {
console.log(playerSelection);
computerSelection = computerPlay();
const outcome = playRound(playerSelection, computerSelection);
console.log(outcome);
return outcome;
}
<div class="container">
<div class="action-row">
<button class="action" id="rock">Rock</button>
<button class="action" id="paper">Paper</button>
<button class="action" id="scissors">Scissors</button>
</div>
</div>
Any hints/suggestions?
Also, am not sure why it's printing out final score before finishing the for loop.
Relevant portion of the code:
let playerScore = 0;
let computerScore = 0;
let i = 0;
while (i < 5) {
document.querySelectorAll('.action').forEach(button => {
button.addEventListener('click', e => {
const outcome = game(e.target.id);
if (outcome === -1)
computerScore += 1;
if (outcome === 1)
playerScore += 1;
});
});
i += 1;
}
if (i == 4) {
console.log("Player score: ", playerScore);
console.log("Computer score: ", computerScore);
}
You shouldn't have the while loop. That's not running 5 rounds of the game, it's adding 5 listeners to each button. When you click a button, it will run all the listeners.
And the code that displays the scores is not running after they play all the games, it's running immediately after you add the listeners.
Event listeners are asynchronous, they're not like prompting for input. They don't wait for a click, they just save a function to run later when the click happens.
Add a listener to each button, and the listener should increment a global variable containing the round number. When the round goes past 5, end the game and display the score.
let playerScore = 0;
let computerScore = 0;
let round = 1;
const max_rounds = 5;
document.querySelectorAll('.action').forEach(button => {
button.addEventListener('click', e => {
if (round <= max_rounds) {
const outcome = game(e.target.id);
if (outcome === -1)
computerScore += 1;
else if (outcome === 1)
playerScore += 1;
round++;
if (round == max_rounds) {
console.log("Player score: ", playerScore);
console.log("Computer score: ", computerScore);
}
}
});
});

How using DOM assign value to variable in JS?

Hello I'm working on Rock,Paper and Scissors project. I'm stuck at this problem. I don't know how to assign value to variable using DOM. When user clicks rock button the value of rocks hould be passed to variable and the variable should be used in playRound function. I don't understand how to fix the problem. When I click to button nothing works.
//Gives the random item to item var
function computerPlay() {
const theArr = ["rock", "paper", "scissors"];
var item = theArr[Math.floor(Math.random() * 3)];
return item;
}
//Returns players selection
function playerPlay(e) {
var pItem = e;
console.log(`${e}`);
return pItem;
}
var r = document.querySelector('.rock').addEventListener('click', playerPlay);
var p = document.querySelector('.paper').addEventListener('click', playerPlay);
var s = document.querySelector('.scissors').addEventListener('click', playerPlay);
var play = document.querySelector('.playbtn').addEventListener('click', playRound);
function playRound(playerSelection, computerSelection) {
playerSelection = playerPlay();
computerSelection = computerPlay();
if (playerSelection == 'rock' && computerSelection == 'paper' || playerSelection == 'paper' && computerSelection == 'scissors' ||
playerSelection == 'scissors' && computerSelection == 'rock') {
window.alert(`${computerSelection} beats ${playerSelection} YOU LOST!`);
} else if (playerSelection == computerSelection) {
window.alert(`${computerSelection} and ${playerSelection} it is a DRAW!`);
} else {
window.alert(`${playerSelection} beats ${computerSelection} YOU WIN!!!`);
}
}
<div class="buttons">
<button class="rock">ROCK</button>
<button class="paper">PAPER</button>
<button class="scissors">SCISSORS</button>
</div>
<div class="play-btn">
<button class="playbtn">PLAY</button>
</div>
</div>
</div>
You're not fetching the player's selection anywhere, and calling playerPlay() manually does not work, because it is supposed to be a callback.
I changed your code a little and the play button can be removed because it is kind of ambiguous. Try this out:
function computerPlay() {
const theArr = ["rock", "paper", "scissors"];
var item = theArr[Math.floor(Math.random() * 3)];
return item;
}
//Returns players selection
function playerPlay(e) {
var playerSelection = e.srcElement.classList[0];
console.log(playerSelection);
computerSelection = computerPlay();
if (playerSelection == 'rock' && computerSelection == 'paper' || playerSelection == 'paper' && computerSelection == 'scissors' || playerSelection == 'scissors' && computerSelection == 'rock') {
window.alert(`${computerSelection} beats ${playerSelection} YOU LOST!`);
} else if (playerSelection == computerSelection) {
window.alert(`${computerSelection} and ${playerSelection} it is a DRAW!`);
} else {
window.alert(`${playerSelection} beats ${computerSelection} YOU WIN!!!`);
}
}
var r = document.querySelector('.rock').addEventListener('click', playerPlay);
var p = document.querySelector('.paper').addEventListener('click', playerPlay);
var s = document.querySelector('.scissors').addEventListener('click', playerPlay);

Rock, Paper, Scissors game: entering the correct value returns the wrong console.log message

Sometimes when I enter "rock" in the prompt and hit OK, the console will say "Please type Rock, Paper, or Scissors" even in case I had actually done that. I believe this is due to the else clause, I'm just not sure what I did wrong.
Also, other times when I enter "rock" in the prompt and hit OK, nothing happens in the console (no score is added). Below is the screenshot
const playerSelection = ''
const computerSelection = computerPlay()
let computerScore = 0;
let playerScore = 0;
console.log(playRound(playerSelection, computerSelection))
function computerPlay(){
let values = ['rock', 'paper', 'scissors'],
valueToUse = values [Math.floor(Math.random()* values.length)];
return valueToUse;
};
function playRound(playerSelection, computerSelection) {
while(true){
playerSelection = prompt ('Pick your poison');
if (playerSelection.toLowerCase() === 'rock' && computerPlay() === 'paper'){
computerScore += 1
console.log('Sorry! Paper beats Rock')
}
else if (playerSelection.toLowerCase() === 'rock'.toLowerCase() && computerPlay() === 'scissors'){
playerScore += 1
console.log('Good job! Rock beats Scissors');
}
else
{
console.log('Please type Rock, Paper, or Scissors')
}
console.log (`User Selection: ${playerSelection.toUpperCase()} | Player Score: ${playerScore}
Computer Selection: ${computerSelection.toUpperCase()} | Computer Score: ${computerScore}`);
}
}
You only call computerSelection once, at the beginning of pageload:
const computerSelection = computerPlay()
It then proceeds to only get used in the log:
Computer Selection: ${computerSelection.toUpperCase()} |
But your tests call computerPlay again, creating new strings for the computer every time:
if (playerSelection.toLowerCase() === 'rock' && computerPlay() === 'paper'){
// function invocation ^^^^^^^^^^^^^^
computerScore += 1
console.log('Sorry! Paper beats Rock')
}
else if (playerSelection.toLowerCase() === 'rock'.toLowerCase() && computerPlay() === 'scissors'){
// function invocation ^^^^^^^^^^^^^^
In addition to that, you aren't exhaustively testing each possibility for rock-paper-scissors (like when the player picks something other than 'rock').
To start with, call computerPlay only once, then use the computerSelection variable:
if (playerSelection.toLowerCase() === 'rock' && computerSelection === 'paper') {
computerScore += 1
console.log('Sorry! Paper beats Rock')
} else if (playerSelection.toLowerCase() === 'rock' && computerSelection === 'scissors') {
Also note that there isn't much point calling toLowerCase on something that's already a lower-cased string literal - just use the plain string.
You can update the code as following
Remove all unnecessary global variable declarations.
Remove unnecessary arguments of playRound function.
Add more logic for other player selection cases.
Nest condition for computer selection cases.
playRound();
function computerPlay(){
let values = ['rock', 'paper', 'scissors'],
valueToUse = values [Math.floor(Math.random()* values.length)];
return valueToUse;
};
function playRound() {
let playerSelection;
let computerSelection;
let playerScore = 0;
let computerScore = 0;
while(true){
playerSelection = prompt('Pick your poison').toLowerCase();
computerSelection = computerPlay();
if (playerSelection === 'rock') {
if (computerSelection === 'paper') {
computerScore += 1;
} else if (computerSelection === 'scissors') {
playerScore += 1;
}
} else if (playerSelection === 'paper') {
if (computerSelection === 'scissors') {
computerScore += 1;
} else if (computerSelection === 'rock') {
playerScore += 1;
}
} else if (playerSelection === 'scissors') {
if (computerSelection === 'rock') {
computerScore += 1;
} else if (computerSelection === 'paper') {
playerScore += 1;
}
} else {
console.log('Please type Rock, Paper, or Scissors');
continue;
}
console.log (`User Selection: ${playerSelection.toUpperCase()} | Player Score: ${playerScore}
Computer Selection: ${computerSelection.toUpperCase()} | Computer Score: ${computerScore}`);
}
}
Here is a minimalist version of the game as a complete rewrite:
function game(){
var usr, u, c, g, score=[0,0],last="";
const words=["rock","paper","scissors"];
while(usr=prompt(last+"\nScore (you:computer): "+score.join(":")+"\nYour choice:")) {
while((u=words.indexOf(usr.toLowerCase()))<0) usr=prompt("invalid choice, please enter again,\none of: "+words.join(", "));
c=Math.floor(Math.random()*3);
g=(3+u-c)%3; // who wins?
if(g) score[g-1]++;
last="you: "+words[u]+", computer: "+words[c]+" --> "
+["draw","you win!!!","you lost - sorry."][g];
}
}
game()

Categories