You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:10:56