I am practicing the rock-paper-scissors assignment.
When I call playRound function manually it returns normal (e.g tie true false tie tie).
But when I call playRound function with iteration through game function it returns (true true true true) or (false false false false false) or (tie tie tie tie tie), instead of something like (false tie false true tie). I used the if-else clause and now I used switch yet still the same output. please how will I solve the issue?
function getComputerPlay() {
let selectAny = ["paper", "rock", "scissors"];
let randomReturn = Math.floor(Math.random() * selectAny.length);
return selectAny[randomReturn];
}
function getUserSelect(choice) {
let userSelect = choice.toLowerCase();
if (userSelect === "rock" || userSelect === "paper" || userSelect === "scissors") return userSelect;
return "Not valid";
}
function playRound(playSelection, computerSelection) {
if (playSelection === computerSelection) return "Tie!.";
if (playSelection === "paper") {
if (computerSelection === "rock") {
return true;
}
else {
return false;
}
}
if (playSelection === "rock") {
if (computerSelection === "scissors") {
return true;
}
else {
return false;
}
}
if (playSelection === "scissors") {
if (computerSelection === "rock")
return false;
} else {
return true;
}
}
function game(playSelection, computerSelection) {
let win = 0;
let lost = 0;
let tie = 0;
for (let i = 0; i < 5; i++) {
let playRoundReturn = playRound(playSelection, computerSelection);
switch (playRoundReturn) {
case true:
win++;
break;
case false:
lost++;
break;
default:
tie++;
break;
}
}
console.log(win, lost, tie);
return "You won " + win + "times, lost " + lost + "times and draw " + tie + "time";
}
let playSelection = getUserSelect("rock");
let computerSelection = getComputerPlay();
let play = game(playSelection, computerSelection); //called playRound with iteration through game()
//let pl = playRound(playSelection, computerSelection); //called playRound manually
console.log(play);
This is because the playSelection is always 'rock', and the computerSelection only runs the random gen once, so will always be the same value for all 5 rounds.
Move the random generator into the for loop, e.g.
let playRoundReturn = playRound(playSelection, getComputerPlay());
Related
const playerText = document.querySelector("#playerText");
const computerText = document.querySelector("#computerText");
const resultText = document.querySelector("#resultText");
const choiceBtns = document.querySelectorAll(".choiceBtn");
let player;
let computer;
let playerScore = 0;
let computerScore = 0;
let ifresult = "";
choiceBtns.forEach(button => button.addEventListener("click", () => {
player = button.textContent;
computerSelection();
playerText.textContent = "Player: " + player;
computerText.textContent = "Computer: " + computer;
resultText.textContent = "Result: " + result();
}));
function computerSelection(){
const randNum = Math.floor(Math.random() * 3) + 1;
switch(randNum){
case 1:
computer = "rock";
break;
case 2:
computer = "paper";
break;
case 3:
computer = "scissors";
break;
}
}
function result() {
if ((player === "paper" && computer === "rock") ||
(player === "scissors" && computer === "paper") ||
(player === "rock" && computer === "scissors")) {
playerScore += 1;
return ("You win! ");
}
if (playerScore == 2) {
return ("Winner winner chicken dinner! You won the game!");
}
else if (player == computer) {
return ("Draw!");
}
else {
computerScore += 1;
display ("you lose");
if (computerScore == 5) {
return ("You lost the game. ");
}
}
}
Everything in this function works except this final if statement in the else bracket.
if (computerScore == 5) {
return ("You lost the game. ");
I am getting the error,
"unreachable code detected ts(7027)".
If I delete the "return ("You lose!");" how would i display i lost the game? The second return "return ("You lost the game.");" returns that statement if i lose 5 times. Thanks for the help
In your final else statement, you're returning a value before the if condition is run.
return ("You lose!");
if (computerScore == 5) { // this code is unreachable
You need to remove this return.
} else {
computerScore += 1;
if (computerScore == 5) {
return ("You lost the game.");
}
}
Avoid such mistakes by adding a good extension into your VS Code. Image below demonstrates how my plugin detected the mistake. I am using Tabnine.
2. Be careful when returning values to close the if statement and then start new one.
3. There are some logic issues that makes this function a bit hard to read and unscalable.
4. Using your params I have cleaned and fixed it. I think your level of programming will fit into this solution. Since you are learning then it's OK to write longer code and with time your skill will come.
5. You can test this game, change the function values under the script.
// DEFINE VARIABLES
let player = undefined
let computer = undefined
let playerScore = 0
let computerScore = 0
let returnText = undefined
const theGame = (player, computer) => {
// PLAYER HAS PAPER
if (player === 'paper' && computer === 'rock') {
playerScore++
returnText = 'You win!'
checkScore(playerScore, computerScore)
return returnText
} else if (player === 'paper' && computer === 'paper') {
returnText = 'Draw!'
return returnText
} else if (player === 'paper' && computer === 'scissors') {
computerScore++
returnText = 'You lose!'
checkScore(playerScore, computerScore)
return returnText
}
// PLAYER HAS ROCK
if (player === 'rock' && computer === 'rock') {
returnText = 'Draw!'
return returnText
} else if (player === 'rock' && computer === 'paper') {
computerScore++
returnText = 'You lose!'
checkScore(playerScore, computerScore)
return returnText
} else if (player === 'rock' && computer === 'scissors') {
playerScore++
returnText = 'You win!'
checkScore(playerScore, computerScore)
return returnText
}
// PLAYER HAS SCISSORS
if (player === 'scissors' && computer === 'rock') {
computerScore++
returnText = 'You lose!'
checkScore(playerScore, computerScore)
return returnText
} else if (player === 'scissors' && computer === 'paper') {
playerScore++
returnText = 'You win!'
checkScore(playerScore, computerScore)
return returnText
} else if (player === 'scissors' && computer === 'scissors') {
returnText = 'Draw!'
return returnText
}
}
// CHECK SCRORE FUNCTION
const checkScore = (playerScore, computerScore) => {
let winningScore = 3
let result = undefined
if (playerScore === winningScore) {
result = 'Winner winner chicken dinner! You won the game!'
} else if (computerScore === winningScore) {
result = 'Winner winner chicken dinner! You won the game!'
} else {
// For testing
console.log('Player score: ', playerScore, 'Computer score: ', computerScore)
return playerScore, computerScore
}
// For testing
console.log(result)
return result
}
// TESTING
theGame('paper', 'rock')
Everything you put after a return statement will not be executed.
If the last else statement is reached, the function will return “You lose!” and its execution will stop.
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>';
}
Currently working on TOP rock paper scissors game and I'm having some trouble. The function playRound is showing up as undefined in the console. I'm not sure why as all my other function are working. Maybe i did something wrong in the other functions but I'm not sure. I feel like I'm so close yet so far from this thing working. Maybe it's just common beginner mistakes not sure. Any help would be appreciated.
function computerPlay() {
var pickRandom = ["Rock", "Paper", "Scissors"];
var randomMove = pickRandom[Math.floor(Math.random() * 3)];
if (randomMove == "Rock") {
randomMove.value = 0;
} else if (randomMove == "Paper") {
randomMove.value = 1;
} else if (randomMove == "Scissors") {
randomMove.value = 2;
}
return randomMove;
}
console.log(computerPlay());
var playerSelection = prompt("pick rock paper or scissors");
function userPlay() {
if (playerSelection == "rock") {
playerSelection.value = 0;
} else if (playerSelection == "paper") {
playerSelection.value = 1;
} else if (playerSelection == "scissors") {
playerSelection.value = 2;
}
return playerSelection;
}
console.log(userPlay());
function playRound(playerPick, computerSelection) {
if (playerPick == 0 && computerSelection == 2) {
alert("you win!!!");
} else if (playerPick == 0 && computerSelection == 1) {
alert("you lose hahahahaha!!!");
} else if (playerPick == computerSelection) {
alert("its a tie");
}
}
const playerPick = userPlay();
const computerSelection = computerPlay();
console.log(playRound(playerPick, computerSelection));
You shouldn't run it in console.log, as it doesn't have a return keyword, so it will return undefined. Just run it normally and it will be fine.
You are close. I cleaned it up a bit, added a function that maps variants of human input to a normalized value, and replaced the (incomplete) conditions in playRound with an object that captures all of the win conditions in an object (see beats)...
function normalizePlay(play) {
const variants = { r: 'rock', rock: 'rock', p: 'paper', paper: 'paper', s: 'scissors', scissors: 'scissors' };
return variants [play.toLowerCase()];
}
function computerPlay() {
var pickRandom = ["rock", "paper", "scissors"];
return pickRandom[Math.floor(Math.random() * 3)];
}
function playRound(human, computer) {
const beats = { rock: 'scissors', scissors: 'paper', paper: 'rock' }
let result;
if (human === computer) {
result = 'tie';
}
else if (beats[human] === computer) {
result = 'you win';
}
else result = 'computer wins';
console.log(`you picked ${human}, computer picked ${computer}... ${result}`)
}
const human = normalizePlay(prompt("pick rock paper or scissors (or r, p, s)"));
const computer = computerPlay();
playRound(human, computer);
function computerPlay() {
var pickRandom = ["Rock", "Paper", "Scissors"];
var randomMove = pickRandom[Math.floor(Math.random() * 3)];
if (randomMove == "Rock") {
return 0;
} else if (randomMove == "Paper") {
return 1;
} else if (randomMove == "Scissors") {
return 2;
}
}
var playerSelection = prompt("pick Rock, Paper or Scissors");
function userPlay() {
if (playerSelection == "Rock") {
return 0;
} else if (playerSelection == "Paper") {
return 1;
} else if (playerSelection == "Scissors") {
return 2;
}
}
function playRound(playerPick, computerSelection) {
console.log("player", playerPick)
console.log("computerSelection", computerSelection)
if (playerPick == 0 && computerSelection == 2) {
console.log("you win!!!");
} else if (playerPick == 0 && computerSelection == 1) {
console.log("you lose hahahahaha!!!");
} else if (playerPick == computerSelection) {
console.log("its a tie");
}
}
const playerPick = userPlay();
const computerSelection = computerPlay();
playRound(playerPick, computerSelection);
You you just needed to return the numbers from computerPlay and userPlay. Also, be careful with case sensitivity when using the prompt.
I just created a five rounds rock-paper-scissors game using vanilla JavaScript. The program runs just fine so far except for the fact every time I start the game for the very first time it will take any user input as invalid no matter what and won't count that round.
This is my code:
// Global variables
let playerWins = 0;
let computerWins = 0;
let array = [];
let validInput = 0;
let newRound = "";
// This function generates a computer selection
const computerPlay = () => {
array = ["rock", "paper", "scissors"]
return array[Math.floor(Math.random() * array.length)];
}
// This function stores player selection
const playerSelection = (selection) => {
selection = prompt("Enter: 'Rock', 'Paper' or 'Scissors'").toLowerCase();
validInput = array.indexOf(selection);
console.log(validInput);
// This loop will validate user input is correct
while (validInput === -1) {
alert("Invalid input, try again");
selection = prompt("Enter 'Rock', 'Paper' or 'Scissors'").toLowerCase();
validInput = array.includes(selection);
}
return selection;
}
// This function plays a single round of Rock-Paper-Scissors
const playRound = (playerSelection, computerPlay) => {
// If both players select the same item
if (playerSelection === computerPlay) {
return alert("It's a tie!");
}
// If player selects "Rock"
if (playerSelection === "rock") {
if (computerPlay === "scissors") {
playerWins += 1;
return alert("Rock crushes scissors: YOU WIN!!!");
} else {
computerWins += 1;
return alert("Paper covers rock: YOU LOOSE!!!");
}
}
// If player selects "Paper"
if (playerSelection === "paper") {
if (computerPlay === "rock") {
playerWins += 1;
return alert("Paper covers rock: YOU WIN!!!");
} else {
computerWins += 1;
return alert("Scissors cuts paper: YOU LOOSE!!!");
}
}
// If player selects "Scissors"
if (playerSelection === "scissors") {
if (computerPlay === "rock") {
computerWins += 1;
return alert("Rock crushes scissors: YOU LOOSE!!!");
} else {
playerWins += 1;
return alert("Scissors cuts paper: YOU WIN!!!");
}
}
}
// This function keeps score and reports a winner or loser at the end
const trackWins = (pw, cw) => {
alert("COMPUTER WINS: " + cw + "\nPLAYER WINS: " + pw)
if (pw > cw) {
alert("YOU WIN THIS ROUND, CONGRAX!!!")
} else if (cw > pw) {
alert("YOU LOOSE THIS ROUND, SO BEST LUCK FOR THE NEXT TIME :_(")
} else {
alert("IT'S A TIE")
}
}
// This function creates a 5 round game
const game = () => {
for (let i = 0; i < 5; i++) {
playRound(playerSelection(), computerPlay());
}
trackWins(playerWins, computerWins);
}
do {
game();
newRound = prompt("Do yo want to play another round? Type 'y' to continue or any other key to exit").toLowerCase();
} while (newRound === "y");
alert("It was a good game, bye for now!")
I will appreciate any ideas to fix this problem or improve my script, thank you in advance!
Your posted code can be simplified to better reflect question - say, you have an array, and a variable that stores user input. How do you test if the input value is in the array?
var arr=['Rock','Paper','Scissors'];
var inp='Rock'; //user input
You could use a while loop, but there's a much faster way:
var options={'rock':0,'paper':1,'scissors':2}
var inp='Rock'; //user input
var ninp=inp.toLowerCase().trim(); //normalize input
var pick=(options[ninp]);
if (pick==null) // invalid selection
if (pick==0) //rock
if (pick==1) //paper
if (pick==2) //scissors
The code can be further cleaned up with a switch:
switch (pick){
case 0: ... break; //rock
case 1: ... break; //paper
case 2: ... break; //scissors
default: //invalid
}
In the follow code:
I have tried passing whatThrow an argument as well. I don't seem to spot what is wrong.
var ranThrow = ["empty", "rock", "paper", "scissors"];
var ranNum = Math.random();
var postRanNum = (ranNum * 3) + 1;
var roundPostRanNum = Math.floor(postRanNum);
var compThrow = ranThrow[roundPostRanNum];
var whatThrow = prompt("Rock, Papper or Scissors?", "rock");
var rpsGame = function () {
if (whatThrow === "rock" && compThrow === "rock") {
return "You tie!";
}
else if (whatThrow === "rock" && compThrow === "paper") {
return "You lose!";
}
else if (whatThrow === "rock" && compThrow === "scissor") {
return "You win!";
}
else {
return "Error";
}
};
rpsGame();
console.log("The computer threw" + " " + compThrow);
The value isn't ignored inside the function, it's the code that is calling the function that is ignoring what the function returns.
If you show the return value, you will see that the function uses the value:
console.log(rpsGame());