C++猜拳游戏do while循环逻辑异常排查:期望仅平局时循环但胜负场景也触发循环
Fixing the Loop Issue in Your Rock-Paper-Scissors Game
Hey, let's get that loop behaving exactly how you want it—only replaying when there's a tie! You were right to suspect the winner function and the do-while loop, so let's break down the problems and fix them one by one.
The Key Problems in Your Code
- Default
playAgainvalue: You setint playAgain = 1;at the start ofwinner(), which means it returns 1 (triggering the loop) every single time—even when you win or lose. We need to flip this: default to 0 (don't loop) and only set it to 1 when there's a tie. - Accidental comparison instead of assignment: In your tie cases, you wrote
playAgain == 1;—that's a check to see ifplayAgainequals 1, not setting it to 1. You need to use a single equals sign=for assignment here. - Bonus bug: Re-seeding random numbers: Your
getComputerChoice()callssrand(seed)every time it runs, which can cause the computer to pick the same choice repeatedly. Move thesrandcall to the start ofmain()so it only runs once.
Fixed Code
Here's the full corrected code with all these fixes applied:
#include <iostream> #include <cstdlib> #include <ctime> using namespace std; const int ROCK = 1; const int PAPER = 2; const int SCISSORS = 3; int getComputerChoice(); int getUserChoice(); void displayChoice(int); int winner(int, int); // MAIN FUNCTION int main() { // Seed random number generator ONCE at the start unsigned seed = time(0); srand(seed); int computerChoice, userChoice; int playAgain; do { computerChoice = getComputerChoice(); userChoice = getUserChoice(); displayChoice(computerChoice); playAgain = winner(computerChoice, userChoice); } while (playAgain == 1); return (0); } // THIS GETS THE COMPUTER CHOICE (now without re-seeding every time) int getComputerChoice() { return (rand() % (SCISSORS - ROCK + 1)) + ROCK; } // THIS IS GOOD I THINK int getUserChoice() { int uChoice; cout << "Enter your choice of Rock, Paper, Scissors.\n" << "(1) For rock, (2) for paper, (3) for scissors: "; cin >> uChoice; while (uChoice < 1 || uChoice > 3) { cout << "\nPlease enter a number between 1 and 3. Try again, thank you: "; cin >> uChoice; // Removed recursive call here to avoid stack overflow risk } return uChoice; } // THIS IS GOOD I THINK. (Added text labels instead of just numbers for clarity) void displayChoice(int choice) { cout << "Computer Choice: "; if (choice == ROCK) cout << "Rock"; else if (choice == PAPER) cout << "Paper"; else if (choice == SCISSORS) cout << "Scissors"; cout << endl; } // FIXED WINNER FUNCTION int winner(int computerChoice, int userChoice) { int playAgain = 0; // Default to NOT replaying if (computerChoice == ROCK) { if (userChoice == SCISSORS) { cout << " You lose :( (The Rock smashes the Scissors) "; } else if (userChoice == PAPER) { cout << "You win! (Paper beats rock) "; } else if (userChoice == ROCK) { cout << "It's a tie. Play again."; playAgain = 1; // Correct assignment here } } else if (computerChoice == PAPER) { if (userChoice == ROCK) { cout << "You lose :( (Paper wraps rock)"; } else if (userChoice == SCISSORS) { cout << "You win! (Scissors cuts paper)"; } else if (userChoice == PAPER) { cout << "It's a tie. Play again."; playAgain = 1; // Correct assignment here } } else if (computerChoice == SCISSORS) { if (userChoice == ROCK) { cout << "You Win! (The rock smashes the scissors.)"; } else if (userChoice == PAPER) { cout << "You lose :(. (Scissors cuts paper.)"; } else if (userChoice == SCISSORS) { cout << "It's a tie. Play again."; playAgain = 1; // Correct assignment here } } cout << endl; return playAgain; }
Extra Improvements I Added
- Changed
displayChoice()to show "Rock"/"Paper"/"Scissors" instead of just numbers for better readability. - Fixed the recursive call in
getUserChoice()(recursion here could lead to stack overflow if the user enters bad input too many times—using a loop withcindirectly is safer).
内容的提问来源于stack exchange,提问作者MARRSVISTER
相关产品推荐
相关产品推荐

