C#石头剪刀布游戏计分异常:仅显示单轮得分无法累计总场次
问题描述
我用C#开发了一款石头剪刀布(Rock, Paper, Scissors)游戏,游戏循环运行功能正常,但当玩家选择不再继续游戏时,系统仅显示当前单轮得分统计,无法展示所有场次的累计结果(预期应显示类似“玩家1胜3局,电脑胜2局,平局4局”的内容)。请问我在代码中遗漏了什么?
原始代码
//RPSGame using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; class RPSGame { private string playerMove; private string computerMove; private int draws; private int playerWins; private int computerWins; // Constructor to Create a New Rock, Paper, Scissors Game Object public RPSGame() { //Setting up game by asking user for their response Console.WriteLine("Hey do you want to play a game? y or n: "); playerMove = Console.ReadLine(); if (playerMove == "N" || playerMove == "n") { Console.WriteLine("Awe ok, No game for you then! Here is your score: "); } else if (playerMove == "Y" || playerMove == "y") { Console.WriteLine("Pick R for Rock, S for Scissors or P for Paper"); } else Console.WriteLine("Invalid Response, y or n only!"); } public int Draws { get { return draws; } } public int PlayerWins { get { return playerWins; } } public int ComputerWins { get { return computerWins; } } public string PlayerMove // Property to set or return player's move { get { return playerMove; } set { playerMove = value.ToUpper(); } } public string ComputerMove // Property to return computer's move { get { return computerMove; } } public void GetComputerMove() { Random rand = new Random(); int move = rand.Next(3) + 1; // Random number from 1 to 3 if (move == 1) computerMove = "R"; else if (move == 2) computerMove = "P"; else computerMove = "S"; } public string DisplayMoves() { string moves = ""; string cMove = "", pMove = ""; bool invalidMove = false; if (playerMove == "R") pMove = "Rock"; else if (playerMove == "P") pMove = "Paper"; else if (playerMove == "S") pMove = "Scissors"; else { pMove = "\nInvalid entry...Must enter an R, P, or S."; invalidMove = true; } if (computerMove == "R") cMove = "Rock"; else if (computerMove == "P") cMove = "Paper"; else cMove = "Scissors"; if (invalidMove) moves = pMove; else moves = ("\nPlayer's Move: " + pMove + "\nComputer's Move: " + cMove + "\n"); return moves; } public string DetermineWinner() { // R = Rock P = Paper S = Scissors string message = ""; if (playerMove == computerMove) { message = ("It's a draw!"); draws++; } else if (playerMove == "R" && computerMove == "P") { message = ("Computer Wins! Paper Covers Rock!"); computerWins++; } else if (playerMove == "R" && computerMove == "S") { message = "Player Wins! Rock Smashes Scissors!"; playerWins++; } else if (playerMove == "P" && computerMove == "R") { message = "Player Wins! Paper Covers Rock!"; playerWins++; } else if (playerMove == "P" && computerMove == "S") { message = "Computer Wins! Scissors Cut Paper!"; computerWins++; } else if (playerMove == "S" && computerMove == "R") { message = "Computer Wins! Rock Smashes Scissors!"; computerWins++; } else if (playerMove == "S" && computerMove == "P") { message = "Player Wins! Sciccors Cut Paper!"; playerWins++; } return message; } public string ShowStats() { string stats = ("Draws: " + draws + "\n" + "Player Wins: " + playerWins + "\n" + "Computer Wins: " + computerWins + "\n"); return stats; } } //Program internal class Program { static void Main(string[] args) { bool gameLoop = true; string answer; while (gameLoop) { RPSGame game = new RPSGame(); game.PlayerMove = Console.ReadLine(); game.GetComputerMove(); Console.WriteLine("------------------------"); Console.WriteLine("Player Move: " + game.PlayerMove); Console.WriteLine("Computer Move: " + game.ComputerMove); Console.WriteLine(game.DisplayMoves); Console.WriteLine(game.DetermineWinner()); Console.WriteLine("------------------------"); Console.WriteLine(" "); Console.WriteLine("Do you want to play again y or n: "); Console.WriteLine(" "); answer = Console.ReadLine(); answer = answer.ToUpper(); if (answer == "Y") { gameLoop = true; // Console.Clear(); } else { gameLoop = false; Console.WriteLine(); Console.WriteLine("------------------------"); Console.Write(game.ShowStats()); Console.WriteLine("------------------------"); } } } }
问题原因
核心问题是每次循环都创建了新的RPSGame实例,导致每一轮的统计数据(draws、playerWins、computerWins)都是独立的,之前轮次的统计会被丢弃,退出时只能显示当前这一轮的结果。
另外代码还有两个小问题:
Console.WriteLine(game.DisplayMoves);未调用方法,应写成game.DisplayMoves(),否则会输出方法的类型信息而非实际内容。- 构造函数里的交互逻辑和Main方法的流程冲突,导致首次启动时的提示重复且混乱。
修复方案
1. 调整RPSGame实例的作用域
将RPSGame的实例化移到while循环外部,让所有游戏轮次共享同一个实例,统计数据会累计保存。
2. 重构RPSGame构造函数
移除构造函数里的用户交互逻辑,仅负责初始化变量:
public RPSGame() { draws = 0; playerWins = 0; computerWins = 0; playerMove = ""; computerMove = ""; }
3. 修改Main方法的流程
调整启动提示和循环逻辑,确保统计数据累计:
internal class Program { static void Main(string[] args) { bool gameLoop = true; string answer; // 游戏实例放在循环外,保留累计统计 RPSGame game = new RPSGame(); // 首次启动询问是否开始游戏 Console.WriteLine("Hey do you want to play a game? y or n: "); answer = Console.ReadLine()?.ToUpper() ?? ""; if (answer != "Y") { Console.WriteLine("Awe ok, No game for you then!"); return; } while (gameLoop) { Console.WriteLine("Pick R for Rock, S for Scissors or P for Paper"); game.PlayerMove = Console.ReadLine()?.ToUpper() ?? ""; game.GetComputerMove(); Console.WriteLine("------------------------"); Console.WriteLine("Player Move: " + game.PlayerMove); Console.WriteLine("Computer Move: " + game.ComputerMove); // 调用DisplayMoves方法 Console.WriteLine(game.DisplayMoves()); Console.WriteLine(game.DetermineWinner()); Console.WriteLine("------------------------"); Console.WriteLine("\nDo you want to play again y or n: "); answer = Console.ReadLine()?.ToUpper() ?? ""; if (answer != "Y") { gameLoop = false; Console.WriteLine("\n------------------------"); Console.Write(game.ShowStats()); Console.WriteLine("------------------------"); } } } }
4. 可选优化:修复拼写错误
将DetermineWinner方法里的Sciccors改为Scissors,修正提示文本错误。
修复后效果
玩家每玩一轮,统计数据会累计到同一个RPSGame实例中,退出游戏时会显示所有场次的累计胜负平结果,符合预期。
内容的提问来源于stack exchange,提问作者Deasjia Shannon
相关产品推荐
相关产品推荐

