Rock-Paper-Scissors: the score is not recorded - javascript

I have created the function for the computer's choices and for the player's possible choices. However, for hours I've been trying to solve the issue of scorekeeping as it does not seem to work. I have set the requirements and I set global functions playerScore and computerScore = 0 and yet every time I call the gamescore function, the message which appears is "the tie" since for some reason the values of the two scores are always considered to be 0.
Any idea why might this be happening? I have done an extensive search online but in vain. I am still a beginner so on purpose, I use console.log and not innerHTML or any html/css style/button. The computerPlay() function is console-logged and every time go-live is refreshed, it gives a random choice so it works. For the second function, I do not know loops yet so I called it 5 times via console log to see the results. I also put specific playerSelection arguments so as to make the strings "You won, You lost, Draw again" cause if I did not, in all 5 times, the return was undefined and not one of these three strings/returns. If you refresh go live you will see the choices are changing randomly but the final sentence that should be given depending on the score after 5 rounds is always the same.
function computerPlay() {
let gameWords = ["Rock", "Paper", "Scissors"];
let randomWord = gameWords[Math.floor(Math.random() * gameWords.length)];
return randomWord;
};
console.log(computerPlay());
let playerScore = 0
let computerScore = 0
let draws = 0
function playRound(playerSelection, computerSelection) {
playerSelection = playerSelection.toLowerCase();
if (computerSelection === "Rock") {
if (playerSelection === "rock") {
return "Draw again."
draws++
} else if (playerSelection === "paper") {
return "You won!"
playerScore++;
} else if (playerSelection === "scissors") {
return "You lost!"
computerScore++
};
};
if (computerSelection === "Paper") {
if (playerSelection === "paper") {
return "Draw again."
draws++
} else if (playerSelection === "rock") {
return "You lost..."
computerScore++
} else if (playerSelection === "scissors") {
return "You won!"
playerScore++
};
};
if (computerSelection === "Scissors") {
if (playerSelection === "scissors") {
return "Draw again."
draws++
} else if (playerSelection === "paper") {
return "You lost..."
computerScore++
} else if (playerSelection === "rock") {
return "You won"
playerScore++
};
};
console.log(playerScore);
};
const computerSelection = computerPlay();
console.log(playRound("RoCk", computerSelection));
console.log(playRound("Scissors", computerSelection));
console.log(playRound("PAper", computerSelection));
console.log(playRound("paper", computerSelection));
console.log(playRound("PAPER", computerSelection));
function gameScore() {
if (playerScore > computerScore) {
return "You won the game!";
} else if (playerScore < computerScore) {
return "You lost, try again.";
} else if (playerScore === computerScore) {
return "It is a tie.";
}
}
console.log(gameScore());

You code returns and then increase counters:
return "Draw again."
draws++
as you return counter increase is not called.

Related

Scoreboard and determine winner Rock Paper Scissors (JavaScript)

I'm working on Rock Paper Scissors and I'm lost at how to keep and display scores as well as determine a winner when they reach a score of 5. Right now, I'm adding +1 to the playerScore or compScore depending on the single round result, but I don't know how to display or keep track of it. Here is my code so far. Any tips are greatly appreciated!
//choices array
const choices = ["rock", "paper", "scissors"];
//set scores to 0
let playerScore = 0;
let compScore = 0;
//Get random choice from comp
function getComputerChoice() {
const randomNum = Math.floor(Math.random() * 3) //Generate random num with Math.random(), to ensure it's between 0 and 3, multiply by 3. Use Math.floor to round to down to nearest num
switch (randomNum) { //Create switch statement to take randomNum variable to perform different action based on the condition (case)
case 0:
return "rock";
case 1:
return "paper";
case 2:
return "scissors";
}
}
//single round gameplay
function playRound(playerSelection, computerSelection) {
if (playerSelection == "rock" && computerSelection == "scissors") {
//Add 1 to playerScore
playerScore+= 1
return "You win! Rock beats scissors";
} else if (playerSelection == "rock" && computerSelection == "paper") {
//Add 1 to compScore
compScore+= 1
return "You lose. Paper beats rock";
} else if (playerSelection == "scissors" && computerSelection == "paper") {
playerScore+= 1
return "You win! Scissors beat paper";
} else if (playerSelection == "scissors" && computerSelection == "rock") {
compScore+= 1
return "You lose. Rock beats scissors";
} else if (playerSelection == "paper" && computerSelection == "rock") {
playerScore+= 1
return "You win! Paper beats rock";
} else if (playerSelection == "paper" && computerSelection == "scissors") {
compScore+= 1
return "You lose. Scissors beat paper";
} else if (playerSelection === computerSelection) {
return "It's a tie";
} else {
return "Try again";
}
}
function userInput() {
let ask = false;
//while ask is still false, continue looping
while (ask == false){
const selction = prompt("Rock Paper or Scissors?")
// if the prompt return is empty
if (selction == null){
//keep looping
continue;
}
const selctionLower = selction.toLowerCase();
//ask if array of choices [rock, paper, scissors] is in the user input
if (choices.includes(selctionLower)){
//then ask is true
ask = true;
return selctionLower;
}
}
}
function game() {
//loop
for (let i = 0; i < 5; i++) {
const playerSelection = userInput();
const computerSelection = getComputerChoice();
//call playRound function
console.log(playRound(playerSelection, computerSelection));
}
}
game()

Javascript output in alert is different in console, and counter is not working properly even when condition is met

I'm making a rock paper scissors games where the counter should add 1 if user wins, add 0.5 if it's a tie, and remains the same if user lost. But in the alert and what's shown in the console doesn't match. Sometimes its shown in the alert that I win and in the console its shown I lose or its a tie. And the counter doesn't add up correctly.
In the image above it's shown 3 wins, 1 tie, and 1 lose. It should show I've won 3.5 games but it shows 5.5. And there is only 5 games played so it should be impossible to win 5.5.
Here is the code:
let winCounter = 0;
// playRound function will play a game of rock, paper, scissors and returns the result
function playRound(playerSelection, computerSelection) {
let getPlayerInsensitive = playerSelection.toLowerCase();
if (getPlayerInsensitive === "rock" && computerSelection === "Rock") {
winCounter+=0.5;
return "It's a tie, both are Rock";
} else if (getPlayerInsensitive === "rock" && computerSelection === "Paper") {
winCounter = winCounter;
return "You Lose! Paper beats Rock";
} else if (getPlayerInsensitive === "rock" && computerSelection === "Scissors") {
winCounter+=1;
return "You win! Rock beats Scissors";
} else if (getPlayerInsensitive === "paper" && computerSelection === "Rock") {
winCounter+=1;
return "You win! Paper beats Rock";
} else if (getPlayerInsensitive === "paper" && computerSelection === "Paper") {
winCounter+=0.5;
return "It's a tie! Both are Paper";
} else if (getPlayerInsensitive === "paper" && computerSelection === "Scissors") {
winCounter = winCounter;
return "You lose! Scissors beats Paper";
} else if (getPlayerInsensitive === "scissors" && computerSelection === "Rock") {
winCounter = winCounter;
return "You lose! Rock beats Scissors";
} else if (getPlayerInsensitive === "scissors" && computerSelection === "Scissors") {
winCounter=0.5;
return "It's a tie! Both are Scissors";
} else if (getPlayerInsensitive === "scissors" && computerSelection === "Paper") {
winCounter+=1;
return "You win! Scissors beat Paper";
} else {
return "Check your spelling!";
}
}
// game function returns the winner after five rounds
function game() {
for (let i = 0; i < 5; i++) {
let getSelect = prompt("Choose Rock, Paper, or Scissors", "");
if (getSelect === null || getSelect === "") {
alert("You clicked Cancel!");
}
alert(playRound(getSelect, computerPlay()));
if (i < 5) {
console.log(playRound(getSelect, computerPlay()));
}
//outputs the winner of 5 games
if (i === 4) {
alert("You've played 5 games");
if (winCounter >= 3) {
alert(`You've won ${winCounter} out of 5 games. You win!`);
return `You've won ${winCounter} out of 5 games. You win!`;
} else if (winCounter === 2.5) {
alert(`You've won 2.5 out of 5 games. It's a tie!`);
return `You've won 2.5 out of 5 games. It's a tie!`;
} else if (winCounter < 2.5) {
alert(`You've won ${winCounter} out of 5 games. You lost!`);
return `You've won ${winCounter} out of 5 games. You lost!`;
}
}
}
}
console.log(game());
And here is the fiddle: https://jsfiddle.net/JaredDev/o62hr7as/125/
Why does it show different results in alert and console.log
It's because you called the computerPlay function twice, thus could returns different selection each time it is called,
alert(playRound(getSelect, computerPlay()));
if (i < 5) {
console.log(playRound(getSelect, computerPlay()));
}
you could change it to this, so it is called only once
const result = playRound(getSelect, computerPlay())
alert(result);
if (i < 5) {
console.log(result)
}
also why the score could be more than it should have, its because playRound function also called twice each turn
Caling code with random behaviour and side-effects twice
This piece of code produces an unintended result because the function computerPlay has random behaviour and the function playRound has has side-effects (modifies the winCounter).
alert(playRound(getSelect, computerPlay()));
if (i < 5) {
console.log(playRound(getSelect, computerPlay()));
}
You could correct this part of the problem by calling the function only once and assigning its result to a variable:
const result = playRound(getSelect, computerPlay());
alert(result);
if (i < 5) {
console.log(result);
}
Typo
You also have a typo:
} else if (getPlayerInsensitive === "scissors" && computerSelection === "Scissors") {
winCounter=0.5;
return "It's a tie! Both are Scissors";
This should say += not just =:
winCounter+=0.5;

Rock, Paper, Scissors: Scores remain at 0 on the first round

As you can tell by my messy code, I am still a beginner at JavaScript so I'm really sorry If this will hurt your eyes.
I am working on this Rock, Paper, Scissors project from The Odin Project where we would add a simple UI to it by applying DOM Methods. To be honest, I really don't know if I'm doing this right. I feel like the if statements shouldn't be inside the event listener but this is the only way I have found to make the tallying of scores work. By putting the code here I made it playable, but not quite right:
let playerScore = 0;
let computerScore = 0;
let scores = document.createElement('p');
let body = document.querySelector('body');
const results = document.createElement('div');
body.appendChild(results);
const buttons = document.querySelectorAll('button');
buttons.forEach((button) => {
button.addEventListener('click', () => {
let playerSelection = button.className;
let computerSelection = computerPlay();
let roundResult = playRound(playerSelection, computerSelection);
console.log(roundResult);
score();
gameEnd();
if (roundResult === 'playerWin') {
playerScore++;
} else if (roundResult === 'computerWin') {
computerScore++;
}
})
})
//computer pick
function computerPlay() {
const pick = ['rock', 'paper', 'scissors'];
return pick[Math.floor(Math.random() * pick.length)];
}
// Round Play
function playRound(playerSelection, computerSelection) {
//message that specifies the winner
let tie = `It's a tie you both picked ${playerSelection}`;
let playerWin = `You win this round! ${playerSelection} beats ${computerSelection}`;
let computerWin = `You lose this round! ${computerSelection} beats
${playerSelection}`;
if(playerSelection === computerSelection) {
results.innerHTML = tie;
return 'tie';
} else if (playerSelection === 'rock' && computerSelection === 'scisors') {
results.innerHTML = playerWin;
return 'playerWin';
} else if (playerSelection === 'paper' && computerSelection === 'rock') {
results.innerHTML = playerWin;
return 'playerWin';
} else if (playerSelection === 'scissors' && computerSelection === 'paper') {
results.innerHTML = playerWin;
return 'playerWin';
} else {
results.innerHTML = computerWin;
return 'computerWin';
}
}
function score() {
//new element where score would be seen
scores.innerHTML = `player: ${playerScore} | computer: ${computerScore}`;
body.appendChild(scores);
}
function gameEnd() {
if(playerScore === 5 || computerScore === 5) {
document.querySelector('.rock').disabled = true;
document.querySelector('.paper').disabled = true;
document.querySelector('.scissors').disabled = true;
if (playerScore > computerScore) {
alert('You win the game');
} else if (computerScore > playerScore) {
alert('Aww you lose');
}
}
}
<button class="rock">Rock</button>
<button class="paper">Paper</button>
<button class="scissors">Scissors</button>
Here's the problem, scores remain both at 0 after the first round. It would show who the winner is but it won't tally its score until I have picked for the next round. Where exactly did I go wrong with this one? (feels like in everything I'm genuinely sorry if my explanation sounds as confusing as my code.)
Anyways this is what the initial code looks like, before applying the DOM Methods.
I was initially trying to use this code but I cant even tally the scores with this one because I can't seem to get the return value of of the function playRound().
function computerPlay() {
const pick = ['rock', 'paper', 'scissors'];
return pick[Math.floor(Math.random() * pick.length)];
}
function playRound(playerSelection, computerSelection) {
if (playerSelection === computerSelection) {
alert(`It's a tie! you both picked ${playerSelection}`);
return "tie";
} else if (playerSelection !== "rock" && playerSelection !== "paper" &&
playerSelection !== "scissors"){
alert(`You sure about using ${playerSelection} on a game of "Rock, Paper,
Scissors"?`)
} else if (playerSelection === "rock" && computerSelection === "scissors") {
alert(`You win this round! ${playerSelection} beats ${computerSelection}`);
return "playerWin";
} else if (playerSelection === "paper" && computerSelection === "rock") {
alert(`You win this round! ${playerSelection} beats ${computerSelection}`);
return "playerWin";
} else if (playerSelection === "scissors" && computerSelection === "paper") {
alert(`You win this! ${playerSelection} beats ${computerSelection}`);
return "playerWin";
} else {
alert(`You lose this round! ${computerSelection} beats ${playerSelection}`);
return "botWin";
}
}
const computerSelection = computerPlay();
// to loop the game until 5 rounds
function game() {
let playerScore = 0;
let botScore = 0;
let gameWinner = '';
for (let i = 0; i < 5; i++) {
let playerSelection = prompt(`Round ${i+1}: Choose among "Rock, Paper, Scissors"
as your weapon`).toLowerCase();
let roundResult = playRound(playerSelection, computerPlay());
if (roundResult === "playerWin" ) {
playerScore++;
} else if (roundResult === "botWin" ) {
botScore++;
}
}
if (playerScore > botScore) {
gameWinner = 'You win!';
} else if (botScore > playerScore) {
gameWinner = 'You lose, Computer wins!';
} else {
gameWinner = 'Draw';
}
alert(`Player: ${playerScore} | Bot: ${botScore}`);
if (gameWinner === 'Draw') {
alert("There is no match winner, draw!");
} else {
alert(`${gameWinner}`);
}
}
game();
between these codes which is more likely to be fixed? or would it be better to completely throw this code and just start anew?
The problem is in this part of the code:
score();
gameEnd();
if (roundResult === 'playerWin') {
playerScore++;
} else if (roundResult === 'computerWin') {
computerScore++;
}
score() will update the score in the HTML page, but at that moment the scores have not been updated yet. That only happens later in that if ... else if block.
So the solution is to first update the score, and then to call score():
score();
gameEnd();
if (roundResult === 'playerWin') {
playerScore++;
} else if (roundResult === 'computerWin') {
computerScore++;
}
There is another issue related to this: at the end of the game (when a player reaches 5 points), gameEnd() will call alert. But alert does not allow the page to actually display the latest changes. Instead it blocks any update to it. I would display the game-over message in an HTML element instead of in an alert, just like you already do for the scores. Alternatively, you could delay the execution of alert with a timer, but I would just avoid using alert.
Here is what you can do in the function gameEnd where you currently use alert:
if (playerScore > computerScore) {
results.innerHTML += '<p><b>You win the game</b>';
} else if (computerScore > playerScore) {
results.innerHTML += '<p><b>Aww you lose</b>';
}

Making "Rounds" in a Rock-Paper-Scissors Game?

I know this is a very popular/simple game to make, but I'm having a bit of trouble. I have made a rock-paper-scissors game in javascript and I've managed to make it work so that it will prompt the player to choose rock, paper, or scissors, get the computer to randomly pick an option, and a means for it to say "you lose" or "you win". The problem is that I'm required to make 5 rounds. That's the issue I'm having. I, for some reason, cannot seem to get the code to prompt the user 5 times. It only prompts the user once and runs the same code each time. My code is as follows:
function playRound(playerSelection) {
let computerSelection = getComputerSelection();
if (playerSelection == "rock") {
addToList(playerSelection, computerSelection);
if (computerSelection == "rock") {
result = "It's a tie";
}
else if (computerSelection == "paper") {
result = "You lost! Paper beats Rock";
computerScore++;
}
else {
result = "You won! Rock beats Scissors";
playerScore++;
}
}
else if (playerSelection == "paper") {
addToList(playerSelection, computerSelection);
if (computerSelection == "rock") {
result = "You won! Paper beats Rock";
playerScore++;
}
else if (computerSelection == "paper") {
result = "It's a tie";
}
else {
result = "You lost! Scissors beats Paper";
computerScore++;
}
}
else {
addToList(playerSelection, computerSelection);
if (computerSelection == "rock") {
result = "You lost! Rock beats Scissors";
computerScore++;
}
else if (computerSelection == "paper") {
result = "You won! Scissors beats Rock";
playerScore++;
}
else
result = "It's a tie";
}
h1.textContent = result;
player.textContent = playerScore;
computer.textContent = computerScore;
game();
}
function game() {
if (playerScore === 5) {
end.style.display = "block";
message.textContent = "You Won!";
}
else if (computerScore === 5) {
end.style.display = "block";
message.textContent = "You Lost!";
}
}
I would appreciate any help or direction that is given. I have tried putting my "playRound" function outside of the loop, but it gives me the same issue. What would make it prompt twice?
Thank you!
That's because you are asking for player's prompt only once i.e. it is outside the playRound method.
Try moving the following snippet into playround method.
const computerSelection = computerPlay();
const playerSelection = window.prompt("Enter your choice: ").toLowerCase();
I'm no expert in JS, so please correct me if i'm wrong, but what seems to be the case is that this variable:
const playerSelection = window.prompt("Enter your choice: ").toLowerCase();
is only initialized a single time with that function's return. (because it is outside any function) Accessing the variable only recalls it's value it was initialized with, causing the main loop to run over and over again with only that initial value.
replacing that line with someing like:
function getPlayerSelection(){
return window.prompt("Enter your choice:").toLowerCase()
}
and replacing everywhere you use playerSelection with getPlayerSelection() should fix this issue.

My Console will only return two inputs or just one

This is my first time posting, I am having issues getting all selections to generate on the console. If I capitalise rock at the bottom it will only show the "Scissor" result. If I do not capitalise it, it will only show the other two results, but not scissors. Any guidance would be helpful.
function computerPlay() {
let selection = ["Rock", "Paper", "Scissors"];
let computerSelection = selection[Math.floor(Math.random() * selection.length)];
return computerSelection;
}
function playRound(playerSelection, computerSelection) {
if (playerSelection === "Rock") {
if (computerSelection === "Scissors")
return "You win mate, cheers!";
} else if (computerSelection === "Paper") {
return "You lost lad";
} else {
return "Draw";
}
}
const playerSelection = "rock"
const computerSelection = computerPlay()
console.log(playRound(playerSelection, computerSelection))
The problem is that if the player selection matches "Rock", you ignore the else if and else blocks and go to see if the computer selected Scissors. If that is the case you return "You win mate, cheers!", otherwise you don't return anything, that's why you are getting undefined. If the player does not play Rock then you go into either else if or else statement but the player never wins.
Here's what your playRound function might look like to work properly:
function playRound(player, comp) {
const selection = ["Rock", "Paper", "Scissors"];
pl = selection.indexOf(player);
co = selection.indexOf(comp);
if (co === pl) {
return 'Draw';
} else if (co - pl == 1) {
return 'You lost lad'
} else {
return 'You win mate, cheers!'
}
}
Here's a jsfiddle with a working code sample: https://jsfiddle.net/qjp1y1mg/
This code works fine for me. Try this. It is your code, but something was wrong (a bracket in a wrong place) and I have changed it.
function playRound(playerSelection, computerSelection) {
if (playerSelection === "Rock"){
if (computerSelection === "Scissors")
return "You win mate, cheers!";
else if (computerSelection === "Paper"){
return "You lost lad";
}
else {return "Draw";}
}
}
In your code this bracket was wrong. Because you are excluding other occurrences
if (playerSelection === "Rock") {
if (computerSelection === "Scissors")
return "You win mate, cheers!";
**}**
You're missing a curly bracket after the first inner if statement. The indentation of the code should be a sign that it is not nested the way you want it.
function playRound(playerSelection, computerSelection) {
if (playerSelection === "Rock") {
if (computerSelection === "Scissors"{
return "You win mate, cheers!";
} else if (computerSelection === "Paper") {
return "You lost lad";
} else {
return "Draw";
}
}
}
Here it is fixed. In future scan through your code and ask yourself which opening brackets correspond to whch closing brackets.

Categories