javascriptfunctionconditional-statementsscopegame-development

How to insert some functions inside other function to track score for a game?


I am new to javascript and I'm trying to do the rock-paper-scrissors game from the odin project: https://www.theodinproject.com/lessons/foundations-rock-paper-scissors. The functions that get an input from user and a random answear from the computer work and also the game when I want to play 5 rounds, but without score. When I want to add score for each player, I only receive the last answear from function playround(), not even game over in the end. I think it is about how and where to declare variables that have functions values (playerSelection = getPlayerChoice(); computerSelection = getComputerChoice()). Here is my code:

//get input from the player
function getPlayerChoice() {
   let playerInput = prompt("Choose rock, paper or scrissors.");
   let playerChoice = playerInput.toLowerCase();
   if (playerChoice === "rock") {
       playerChoice = "Rock";
 } else if (playerChoice === "paper") {
       playerChoice = "Paper";
 } else if (playerChoice === "scrissors") {
       playerChoice = "Scrissors";
 } else {
     alert("Choose one of these objects");
     getPlayerChoice();
  }
     return playerChoice;
    }

//get random input from the computer
function getComputerChoice() {
  const comChoice = ["Rock", "Paper", "Scrissors"];
  const comResult = Math.floor(Math.random() * comChoice.length);
    return comChoice[comResult];
   }

//play one round using the functions and assign them to two variables 
and checks the winner
function playRound() {
  const playerSelection = getPlayerChoice();
  const computerSelection = getComputerChoice();
  let response = "";
    if (playerSelection === computerSelection) {
        response += "It's a tie";
  } else if ((playerSelection === "Rock" && computerSelection === "Scrissors") ||
             (playerSelection === "Paper" && computerSelection === "Rock") ||
             (playerSelection === "Scrissors" && computerSelection === "Paper")) {
        response += `You win. ${playerSelection} beats ${computerSelection}`;
  } else if ((playerSelection === "Rock" && computerSelection === "Paper") ||
             (playerSelection === "Paper" && computerSelection === "Scrissors") ||
             (playerSelection === "Scrissors" && computerSelection === "Rock")) {
        response += `You lose. ${playerSelection} beats ${computerSelection}`;
      }
      return response;
    }

//playing a game of 5 rounds and get score
function game() {
  let playerScore = 0;
  let computerScore = 0;
  for (let i = 0; i < 5; i++) {
    let playerSelection = getPlayerChoice();
    let computerSelection = getComputerChoice();
    console.log(playRound());
    if (playRound() === `You win. ${playerSelection} beats ${computerSelection}`) {
        playerScore++;
        console.log(`Player score: ${playerScore}`)
      } else if (playRound() === `You lose. ${playerSelection} beats ${computerSelection}`) {
        computerScore++;
        console.log(`Computer score: ${computerScore}`)
    }
      console.log("---------");
   }

    if (playerScore > computerScore) {
       console.log("You win.")
    } else if (playerScore < computerScore) {
       console.log("You lose.")
    } else if (playerScore === computerScore) {
       console.log("Drawn")
    }
     console.log("Game Over")
   }

    game();

I saw some solutions on youtube, but they use more functions and I want to keep mine and to understand the concepts from JS. I think the problem is playRound() where I already use two functions as variables and the return response involves the values of the parameters. I try to use playRound() inside game() and I don't know how to use that response from my playRound() to add a score: if the user win, he gets 1 point, if the computer wins, it gets 1 point at each round and then add a message score that says who is the winner of the game in the end. Do you have any suggestions for my code? It works if I don't use score for the game, but I want to add this. P.s. there is also an error about getPlayerChoice() where it can't read the properties of null reading toLowerCase(), but only if I press cancel on the prompt. I want to make the game also in html, so I find a little difficult the solution for this error, even if I found it, but I don't feel safe just to copy, maybe you have an easier solution or an explanation for the solution.


Solution

  • I suggest you that use playerscore and computer score and player and computer selection as an array(player and computer selection) in global scope and then do the score counting in playRound function and second is that don't call playRound multiple times cause it decreases the performance very much. And another in your code is that you get the player and computer selection both in playRound and game functions.
    So the code will be like this :

    var computerSelections = []; // an array of computer selections
    var playerSelections = []; // **   **    ** player    **
    var playerScore = 0; // player and computer score should be in global scope
    var computerScore = 0;
    //get input from the player
    function getPlayerChoice() {
        let playerInput = prompt("Choose rock, paper or scrissors.");
        let playerChoice = playerInput.toLowerCase();
        if (playerChoice === "rock") {
            playerChoice = "Rock";
        } else if (playerChoice === "paper") {
            playerChoice = "Paper";
        } else if (playerChoice === "scrissors") {
            playerChoice = "Scrissors";
        } else {
            alert("Choose one of these objects");
            getPlayerChoice();
        }
        return playerChoice;
    }
    
    //get random input from the computer
    function getComputerChoice() {
        const comChoice = ["Rock", "Paper", "Scrissors"];
        const comResult = Math.floor(Math.random() * comChoice.length);
        return comChoice[comResult];
    }
    function playRound(playerSelection,computerSelection) {
        let response = "";
        if (playerSelection === computerSelection) {
            response += "It's a tie";
        } else if ((playerSelection === "Rock" && computerSelection === "Scrissors") ||
            (playerSelection === "Paper" && computerSelection === "Rock") ||
            (playerSelection === "Scrissors" && computerSelection === "Paper")) {
            response += `You win. ${playerSelection} beats ${computerSelection}`;
        } else if ((playerSelection === "Rock" && computerSelection === "Paper") ||
            (playerSelection === "Paper" && computerSelection === "Scrissors") ||
            (playerSelection === "Scrissors" && computerSelection === "Rock")) {
            response += `You lose. ${playerSelection} beats ${computerSelection}`;
        }
        return response;
    }
    //playing a game of 5 rounds and get score
    function game() {
        for (let i = 0; i < 5; i++) {
            let thisplayerSelection = getPlayerChoice();
            let thiscomputerSelection = getComputerChoice();
            var response = playRound(thisplayerSelection,thiscomputerSelection); // added 2 parameters to defined playRound, playerSelection and computerSelection
            // response variable is defined only in game function scope and is diffrent from playRound's response
            if (response === `You win. ${thisplayerSelection} beats ${thiscomputerSelection}`) {
                playerScore++;
                console.log(`Player score: ${playerScore}`)
            } else if (response === `You lose. ${thisplayerSelection} beats ${thiscomputerSelection}`) {
                computerScore++;
                console.log(`Computer score: ${computerScore}`)
            }
            console.log("---------");
            playerSelections.push(thisplayerSelection);
            computerSelections.push(thiscomputerSelection);
        }
    
        if (playerScore > computerScore) {
            console.log("You win.")
        } else if (playerScore < computerScore) {
            console.log("You lose.")
        } else if (playerScore === computerScore) {
            console.log("Drawn")
        }
        console.log("Game Over")
    }
    
    game();
    

    And I did some other changes please read the comments.