javascript - Struggling to use for loop to repeat a function 5 times - Stack Overflow

I am currently building a program that allows the user to play rock-paper-scissors against the computer

I am currently building a program that allows the user to play rock-paper-scissors against the computer through the console log. The goal is for the game to terminate after five rounds.

I was able to set up one round of the game, but I am struggling to loop it. The for loop is in line 14 of the code.

I have tried placing getComputerChoice() and getHumanChoice() both inside and outside the for loop and outside of playGame(). I was expecting the game to ask for user input, display console message with a winner and increment the round winner's score, then repeat four more times before terminating and displaying a console message with the overall winner.

Instead, after accepting user input, no message displays in the console. There is also no error or warning to indicate issues with the code.

function playGame() {
  var humanScore = 0;
  var computerScore = 0;

  for (let i = 0; i < 5; i++) {
    function getComputerChoice() {
      let result = Math.ceil(Math.random() * 3);
      if (result === 1) {
        return "rock";
      } else if (result === 2) {
        return "paper";
      } else {
        return "scissors"
      }
    }

    const computerChoice = getComputerChoice();

    function getHumanChoice() {
      let humanResult = prompt("Let's play Rock, Paper, Scissors! Enter your choice:");
      if (humanResult.toLowerCase() === "rock") {
        return "rock";
      } else if (humanResult.toLowerCase() === "paper") {
        return "paper";
      } else if (humanResult.toLowerCase() === "scissors") {
        return "scissors";
      } else {
        return "to not follow the rules";
      }
    };

    const humanChoice = getHumanChoice();

    function playRound(humanChoice, computerChoice) {
      if (humanChoice === "rock" && computerChoice === "paper") {
        computerScore++;
        console.log(`Paper beats rock! AI wins! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "rock" && computerChoice === "scissors") {
        humanScore++;
        console.log(`Rock beats scissors! You win! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice == "rock" && computerChoice === "rock") {
        console.log("Y'all both picked rock! Let's try again!");
      } else if (humanChoice === "paper" && computerChoice === "scissors") {
        computerScore++;
        console.log(`Scissors beats paper! AI wins! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "paper" && computerChoice === "rock") {
        humanScore++;
        console.log(`Paper beats rock! You win! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "paper" && computerChoice === "paper") {
        console.log("Y'all both picked paper! Let's try again!");
      } else if (humanChoice === "scissors" && computerChoice === "scissors") {
        console.log("Y'all both picked scissors! Let's try again!");
      } else if (humanChoice === "scissors" && computerChoice === "rock") {
        computerScore++;
        console.log(`Rock beats scissors! AI wins! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "scissors" && computerChoice === "paper") {
        humanScore++;
        console.log(`Scissors beats paper! You win! AI:${computerScore} Human:${humanScore}`);
      } else {
        console.log("Try again! That's not a choice.");
      }
    }
  }
};

playGame();

I am currently building a program that allows the user to play rock-paper-scissors against the computer through the console log. The goal is for the game to terminate after five rounds.

I was able to set up one round of the game, but I am struggling to loop it. The for loop is in line 14 of the code.

I have tried placing getComputerChoice() and getHumanChoice() both inside and outside the for loop and outside of playGame(). I was expecting the game to ask for user input, display console message with a winner and increment the round winner's score, then repeat four more times before terminating and displaying a console message with the overall winner.

Instead, after accepting user input, no message displays in the console. There is also no error or warning to indicate issues with the code.

function playGame() {
  var humanScore = 0;
  var computerScore = 0;

  for (let i = 0; i < 5; i++) {
    function getComputerChoice() {
      let result = Math.ceil(Math.random() * 3);
      if (result === 1) {
        return "rock";
      } else if (result === 2) {
        return "paper";
      } else {
        return "scissors"
      }
    }

    const computerChoice = getComputerChoice();

    function getHumanChoice() {
      let humanResult = prompt("Let's play Rock, Paper, Scissors! Enter your choice:");
      if (humanResult.toLowerCase() === "rock") {
        return "rock";
      } else if (humanResult.toLowerCase() === "paper") {
        return "paper";
      } else if (humanResult.toLowerCase() === "scissors") {
        return "scissors";
      } else {
        return "to not follow the rules";
      }
    };

    const humanChoice = getHumanChoice();

    function playRound(humanChoice, computerChoice) {
      if (humanChoice === "rock" && computerChoice === "paper") {
        computerScore++;
        console.log(`Paper beats rock! AI wins! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "rock" && computerChoice === "scissors") {
        humanScore++;
        console.log(`Rock beats scissors! You win! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice == "rock" && computerChoice === "rock") {
        console.log("Y'all both picked rock! Let's try again!");
      } else if (humanChoice === "paper" && computerChoice === "scissors") {
        computerScore++;
        console.log(`Scissors beats paper! AI wins! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "paper" && computerChoice === "rock") {
        humanScore++;
        console.log(`Paper beats rock! You win! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "paper" && computerChoice === "paper") {
        console.log("Y'all both picked paper! Let's try again!");
      } else if (humanChoice === "scissors" && computerChoice === "scissors") {
        console.log("Y'all both picked scissors! Let's try again!");
      } else if (humanChoice === "scissors" && computerChoice === "rock") {
        computerScore++;
        console.log(`Rock beats scissors! AI wins! AI:${computerScore} Human:${humanScore}`);
      } else if (humanChoice === "scissors" && computerChoice === "paper") {
        humanScore++;
        console.log(`Scissors beats paper! You win! AI:${computerScore} Human:${humanScore}`);
      } else {
        console.log("Try again! That's not a choice.");
      }
    }
  }
};

playGame();

Share Improve this question edited Mar 12 at 15:43 mplungjan 179k28 gold badges182 silver badges240 bronze badges asked Mar 12 at 15:36 Jessi B.Jessi B. 11 silver badge 6
  • 3 You never seem to call playRound() (actually, this code doesn't even call playGame()) – mykaf Commented Mar 12 at 15:41
  • 1 "after accepting user input" - the code (originally posted) would not prompt for user input, so either this is not your code or not complete (also "loop on line 14" - no loop there) – fdomn-m Commented Mar 12 at 15:46
  • function getHumanChoice() { let humanResult = prompt("Let's play Rock, Paper, Scissors! Enter your choice:",""); return ['rock','paper','scissors'].includes(humanResult.toLowerCase()) || "to not follow the rules";} – mplungjan Commented Mar 12 at 15:46
  • 1 In the edit, playRound() still isn't called - so it prompts 5 times then quits. – fdomn-m Commented Mar 12 at 15:47
  • Add playRound(humanChoice, computerChoice); (or remove the function declaration and just have that code run after prompting for humanChoice) – fdomn-m Commented Mar 12 at 15:49
 |  Show 1 more comment

2 Answers 2

Reset to default 1

Your issues are explained in the comments, not calling functions etc

Here is a working version, best out of 5 - it leaves the game when one of you wins, but also stops after 5 tries. I moved the functions outside and call them in the loop

function getHumanChoice() {
  let humanResult = prompt("Let's play Rock, Paper, Scissors! Enter your choice:");
  if (humanResult.toLowerCase() === "rock") {
    return "rock";
  } else if (humanResult.toLowerCase() === "paper") {
    return "paper";
  } else if (humanResult.toLowerCase() === "scissors") {
    return "scissors";
  } else {
    return "to not follow the rules";
  }
};

function getComputerChoice() {
  let result = Math.ceil(Math.random() * 3);
  if (result === 1) {
    return "rock";
  } else if (result === 2) {
    return "paper";
  } else {
    return "scissors"
  }
}
let humanScore = 0;
let computerScore = 0;


function playRound(humanChoice, computerChoice) {
  if (humanChoice === "rock" && computerChoice === "paper") {
    computerScore++;
    console.log(`Paper beats rock! AI wins! AI:${computerScore} Human:${humanScore}`);
  } else if (humanChoice === "rock" && computerChoice === "scissors") {
    humanScore++;
    console.log(`Rock beats scissors! You win! AI:${computerScore} Human:${humanScore}`);
  } else if (humanChoice == "rock" && computerChoice === "rock") {
    console.log("Y'all both picked rock! Let's try again!");
  } else if (humanChoice === "paper" && computerChoice === "scissors") {
    computerScore++;
    console.log(`Scissors beats paper! AI wins! AI:${computerScore} Human:${humanScore}`);
  } else if (humanChoice === "paper" && computerChoice === "rock") {
    humanScore++;
    console.log(`Paper beats rock! You win! AI:${computerScore} Human:${humanScore}`);
  } else if (humanChoice === "paper" && computerChoice === "paper") {
    console.log("Y'all both picked paper! Let's try again!");
  } else if (humanChoice === "scissors" && computerChoice === "scissors") {
    console.log("Y'all both picked scissors! Let's try again!");
  } else if (humanChoice === "scissors" && computerChoice === "rock") {
    computerScore++;
    console.log(`Rock beats scissors! AI wins! AI:${computerScore} Human:${humanScore}`);
  } else if (humanChoice === "scissors" && computerChoice === "paper") {
    humanScore++;
    console.log(`Scissors beats paper! You win! AI:${computerScore} Human:${humanScore}`);
  } else {
    console.log("Try again! That's not a choice.");
  }
}


function playGame() {

  for (let i = 0; i < 5; i++) {
    const humanChoice = getHumanChoice();
    const computerChoice = getComputerChoice();
    playRound(humanChoice, computerChoice);
    const diff = computerScore-humanScore;
    if (Math.abs(diff) >= 3) {
      console.log(`${diff>0 ? 'You win!': 'Computer wins'}  AI:${computerScore} Human:${humanScore}`)
      return;
    }  
  }
};

playGame();

Or DRYer (and added Lizard and Spock, because I am worth it) It will play until best of 5 regardless of how long that takes by ignoring rounds that result in a tie.

const title = ["Rock", "Paper", "Scissors"]; // or ["Rock", "Paper", "Scissors", "Lizard", "Spock"]
const CHOICES = title.map(item => item.toLowerCase());
const maxTries = 5; // Sanity limit, but not for ties
const SCORES = { human: 0, computer: 0 };

const getWinningChoices = (choiceIndex) => {
  const n = CHOICES.length;
  if (n === 3) { // RPS
    return [CHOICES[(choiceIndex + 2) % 3]];
  } else if (n === 5) { // RPSLS
    const WINNING_OFFSETS = {
      0: [2, 3], 1: [0, 4], 2: [1, 3], 3: [4, 1], 4: [2, 0]
    };
    return WINNING_OFFSETS[choiceIndex].map(index => CHOICES[index]);
  }
  throw new Error("Unsupported number of choices");
};

const getHumanChoice = () => {
  const input = prompt(`Let's play ${title.join(', ')}! Enter your choice:`).toLowerCase();
  return CHOICES.includes(input) ? input : 'invalid';
};

const getComputerChoice = () => CHOICES[Math.floor(Math.random() * CHOICES.length)];

const getResultMessage = (human, computer) => {
  if (human === computer) return `Both picked ${title[CHOICES.indexOf(human)]}! Try again!`;
  if (human === 'invalid') return "Try again! Invalid choice.";
  
  const humanIndex = CHOICES.indexOf(human);
  const computerIndex = CHOICES.indexOf(computer);
  const humanWins = getWinningChoices(humanIndex).includes(computer);
  
  humanWins ? SCORES.human++ : SCORESputer++;
  const winner = humanWins ? 'You win' : 'AI wins';
  const humanTitle = title[humanIndex];
  const computerTitle = title[computerIndex];
  const beatsMessage = humanWins 
    ? `${humanTitle} beats ${computerTitle}` 
    : `${computerTitle} beats ${humanTitle}`;
  const scores = `AI:${SCORESputer} Human:${SCORES.human}`;
  return `${beatsMessage}! ${winner}! ${scores}`;
};

const playRound = (human, computer) => console.log(getResultMessage(human, computer));

const playGame = () => {
  const winsNeeded = Math.ceil(maxTries / 2); // e.g., 3 wins for best of 5
  let decisiveRounds = 0;

  while (SCORES.human < winsNeeded && SCORESputer < winsNeeded) {
    const human = getHumanChoice();
    const computer = getComputerChoice();
    const result = getResultMessage(human, computer);
    console.log(result);
    if (human !== computer && human !== 'invalid') { // Only increment if not a tie or invalid
      decisiveRounds++;
    }
    if (decisiveRounds >= maxTries) break; // Safety net to prevent infinite loops
  }

  const finalMessage = SCORES.human > SCORESputer 
    ? "You win the game!" 
    : "Computer wins the game!";
  console.log(`${finalMessage} Final score - AI:${SCORESputer} Human:${SCORES.human}`);
};

playGame();

Firstly, the main problem is that you never call playRound(), so all the playGame function does is prompt for input 5 times and then stop. This is a fairly obvious omission. Once you fix that, it seems to work as intended.

Secondly your code is badly laid-out, making it hard to see the wood for the trees. Aside from specialised cases there's rarely a good reason for functions to be declared inside other functions, and certainly not to be interspersed amongst your main logic - which then makes that logic a lot harder to follow when reading and debugging the code. So the first step I took was to move all the function declarations to be independent, and out of the way of the logic in the playGame function.

Thirdly, although this isn't a functional problem in that your current code would work with the modification mentioned in point 1, there's a huge amount of unnecessary repetition of nearly-identical code, which could actually be made shorter, more readable and more maintainable by better use of variables and objects. So I've made a version of the code using that approach, to show how it could be done with far less code. The first snippet in mplungjan's answer is far closer to your original, with only the most essential fixes.

function getComputerChoice() {
  let result = Math.floor(Math.random() * 3);
  return choices[result];
}

function getHumanChoice() {
  let humanResult = prompt(
    "Let's play Rock, Paper, Scissors! Enter your choice:",
  )
  if (choices.includes(humanResult.toLowerCase())) {
    return humanResult.toLowerCase();
  } else {
    return false;
  }
}

function playRound(chosenValues) {
  var hChoice = choices.indexOf(chosenValues["human"]);
  var cChoice = choices.indexOf(chosenValues["computer"]);
  var winner = "";
  var loser = "";

  if (hChoice == cChoice) {
    console.log(`Y'all both picked ${chosenValues["human"]}! Let's try again!`);
    return;
  }
  
  if (hChoice == 0 && cChoice == 2) {
    winner = "human";
    loser = "computer";
  } else if (cChoice == 0 && hChoice == 2) {
    winner = "computer";
    loser = "human";
  } else if (hChoice > cChoice) {
    winner = "human";
    loser = "computer";
  } else if (cChoice > hChoice) {
    winner = "computer";
    loser = "human";
  }

  scores[winner]++;
  console.log(`${chosenValues[winner]} beats ${chosenValues[loser]}! Computer: ${scores["computer"]} Human: ${scores["human"]}`);
}

function playGame() {
  for (let i = 0; i < 5; i++) {
    const computerChoice = getComputerChoice();
    const humanChoice = getHumanChoice();

    if (humanChoice !== false) {
      var chosenValues = {
        "human": humanChoice,
        "computer": computerChoice
      };
      playRound(chosenValues);
    } else {
      console.log("Invalid or cancelled human choice, no round played");
    }
  }
}

var scores = {
  "human": 0,
  "computer": 0
}
var choices = ["rock", "paper", "scissors"];
playGame();

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744743798a4591187.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信