C #의 가위 바위 보

Nov 21 2020

C #으로 가위 바위 보 게임을 만들고 있는데 현재 누군가가 R, S 또는 P가 아닌 입력을 입력하면 메시지를 표시하는 데 문제가 있습니다. 예를 들어, 스위치에서 기본값을 가져 오려고합니다. 성명은 작동하지만 운이 없습니다. 이것이 내가 현재 가지고있는 것입니다. 내가 만든 다른 문제가 있으면 알려주십시오.

using System;

namespace Rockpaperscissors
{
    class Program
    {
        static void Main(string[] args)
        {
            string inputPlayer, Computer;
            int randomnum;
            string loop;
            bool keepPlaying = true;

            while (keepPlaying)
            {

                int wins = 0;
                int Loses = 0;
                int ties = 0;


                while (keepPlaying)
                {

                    Random myRandomObject = new Random();
                    randomnum = myRandomObject.Next(1, 4);
                    Console.Write("To play: enter R for Rock, S for Scissors, P for Paper.");
                    inputPlayer = Console.ReadLine();
                    inputPlayer = inputPlayer.ToUpper();

                    switch (randomnum)
                    {

                        case 1:
                            Computer = "Rock";
                            Console.WriteLine("The computer played Rock");
                            if (inputPlayer == "R")
                            {
                                Console.WriteLine("Tie!!\n\n");
                                ties++;
                            }
                            else if (inputPlayer == "P")
                            {
                                Console.WriteLine("You win!!\n\n");
                                wins++;
                            }
                            else if (inputPlayer == "S")
                            {
                                Console.WriteLine("Computer wins!!\n\n");
                                Loses++;
                            }
                            break;
                        case 2:
                            Computer = "Paper";
                            Console.WriteLine("The computer played Paper");
                            if (inputPlayer == "P")
                            {
                                Console.WriteLine("Tie!!\n\n");
                                ties++;
                            }
                            else if (inputPlayer == "R")
                            {
                                Console.WriteLine("Computer wins!!\n\n");
                                Loses++;
                            }
                            else if (inputPlayer == "S")
                            {
                                Console.WriteLine("You win!!\n\n");
                                wins++;
                            }
                            break;
                        case 3:
                            Computer = "Scissors";
                            Console.WriteLine("The computer played Scissors");
                            if (inputPlayer == "S")
                            {
                                Console.WriteLine("Tie!!\n\n");
                                ties++;
                            }
                            else if (inputPlayer == "R")
                            {
                                Console.WriteLine("You win!!\n\n");
                                wins++;
                            }
                            else if (inputPlayer == "P")
                            {
                                Console.WriteLine("Computer wins!!\n\n");
                                Loses++;
                            }
                            break;
                        default:                      
                            Console.WriteLine("Please enter a correct entry");  
                            break;
                    }

                    Console.WriteLine("Scores:\tWins:\t{0},\tLoses:\t{1},\tties:\t{2}", wins, Loses, ties);

                Console.WriteLine("Would you like to continue playing? (y/n)");
                loop = Console.ReadLine();
                if (loop == "y")
                {
                    keepPlaying = true;

                }
                else if (loop == "n")
                {
                    keepPlaying = false;
                }
                else
                {

                }

                }

            }

        }
    }
}

도와주세요!

답변

2 RufusL Nov 21 2020 at 09:11

다음은 많은 도움이되는 콘솔 응용 프로그램과 함께 사용한 방법입니다. 나는 실제로 사용자로부터 유형 ( int또는 같은 double) 을 얻기 위해 몇 가지를 가지고 있습니다 . 사용자에게 표시되는 프롬프트를 받아들이고 입력에 대해 실행하여 유효한지 확인하는 선택적 유효성 검사기 메서드를 포함합니다.

다음은 문자열 입력을위한 것입니다.

public static string GetStringFromUser(string prompt, Func<string, bool> validator = null)
{
    var isValid = true;
    string result;

    do
    {
        if (!isValid)
        {
            WriteLineColor("Invalid input, please try again.", ConsoleColor.Red);
        }
        else isValid = false;

        Console.Write(prompt);
        result = Console.ReadLine();
    } while (validator != null && !validator.Invoke(result));

    return result;
}

귀하의 경우에는 간단히 다음과 같이 부를 것입니다.

string playerInput = GetStringFromUser(
    "To play: enter R for Rock, S for Scissors, P for Paper: ",
    x => x.ToUpper() == "R" || x.ToUpper() == "S" || x.ToUpper() == "P");

Console.WriteLine($"You entered: {playerInput}");

Console.Write("\nPress any key to continue...");
Console.ReadKey();

다음은 샘플 출력입니다.

2 JamshaidK. Nov 21 2020 at 08:49

다음과 같은 배열로 유효한 이동을 선언하는 것이 좋습니다.

string[] validMoves = new string[3] { "R", "P", "S" };

그런 다음 switch 문이 일치하기 전에 사용자가 유효한 입력을 제공했거나 유효하지 않은 경우 while루프 를 다시 실행하고 그렇지 않으면 switch문을 계속하십시오 . 아래와 같이 :

if (!validMoves.Contains(inputPlayer))
{
    Console.WriteLine("Please select a valid move.");
    continue;
}

주요 방법은 다음과 같습니다.
static void Main(string[] args)
{

    string inputPlayer, Computer;
    int randomnum;
    string loop;
    bool keepPlaying = true;
    string[] validMoves = new string[3] { "R", "P", "S" };
    int wins = 0;
    int Loses = 0;
    int ties = 0;
    while (keepPlaying)
    {
      // while (keepPlaying) // You can get rid of this while loop as it is not helping you out.
      // { // second while loop opening
            Random myRandomObject = new Random();
            randomnum = myRandomObject.Next(1, 4);
            Console.Write("To play: enter R for Rock, S for Scissors, P for Paper.");
            inputPlayer = Console.ReadLine();
            inputPlayer = inputPlayer.ToUpper();

            if (!validMoves.Contains(inputPlayer))
            {
                Console.WriteLine("Please select a valid move.");
                continue;
            }

            switch (randomnum)
            {
                case 1:
                    Computer = "Rock";
                    Console.WriteLine("The computer played Rock");
                    if (inputPlayer == "R")
                    {
                        Console.WriteLine("Tie!!\n\n");
                        ties++;
                    }
                    else if (inputPlayer == "P")
                    {
                        Console.WriteLine("You win!!\n\n");
                        wins++;
                    }
                    else if (inputPlayer == "S")
                    {
                        Console.WriteLine("Computer wins!!\n\n");
                        Loses++;
                    }
                    break;
                case 2:
                    Computer = "Paper";
                    Console.WriteLine("The computer played Paper");
                    if (inputPlayer == "P")
                    {
                        Console.WriteLine("Tie!!\n\n");
                        ties++;
                    }
                    else if (inputPlayer == "R")
                    {
                        Console.WriteLine("Computer wins!!\n\n");
                        Loses++;
                    }
                    else if (inputPlayer == "S")
                    {
                        Console.WriteLine("You win!!\n\n");
                        wins++;
                    }
                    break;
                case 3:
                    Computer = "Scissors";
                    Console.WriteLine("The computer played Scissors");
                    if (inputPlayer == "S")
                    {
                        Console.WriteLine("Tie!!\n\n");
                        ties++;
                    }
                    else if (inputPlayer == "R")
                    {
                        Console.WriteLine("You win!!\n\n");
                        wins++;
                    }
                    else if (inputPlayer == "P")
                    {
                        Console.WriteLine("Computer wins!!\n\n");
                        Loses++;
                    }
                    break;
                default: // You can get rid of this default block, it won't ever hit.
                    Console.WriteLine("Please enter a correct entry");
                    break;
            }

            Console.WriteLine("Scores:\tWins:\t{0},\tLoses:\t{1},\tties:\t{2}", wins, Loses, ties);

            Console.WriteLine("Would you like to continue playing? (y/n)");
            loop = Console.ReadLine();
            
            if (loop == "y")
            {
                keepPlaying = true;
            }
            else if (loop == "n")
            {
                keepPlaying = false;
            }
        // } // second while loop closing

    }
}
1 LukeVo Nov 21 2020 at 08:15

이것이 귀하의 질문에 직접 답하지는 않지만 사용자의 입력을 요청하고 잘못된 입력을 다시 입력하는지 다시 묻는 프로그램의 논리 / 흐름을 보여줍니다.

            while (true)
            {
                Console.WriteLine("1. Print A then C");
                Console.WriteLine("2. Print B then C");
                Console.Write("Enter option: ");

                var input = Console.ReadLine();
                switch (input)
                {
                    case "1":
                        Console.WriteLine("A");
                        break;
                    case "2":
                        Console.WriteLine("B");
                        break;
                    default:
                        Console.WriteLine("Invalid Input. Please try again");
                        continue;
                }

                Console.WriteLine("C");
            }

여기서 A / B를 인쇄하는 것은 손을 선택하는 것과 같고 C를 인쇄하는 것은 결과를 보여주는 것과 같습니다. default가지 용도 continue( 문서를 참조하십시오 ) 루프의 처음으로 돌아갑니다 그래서 C를 인쇄하지 않습니다

Bruno Nov 21 2020 at 10:01

보다 객체 지향적 인 접근 방식을 선호한다면 아래에 작은 예가 있습니다.

사용법 : dotnet run "Your Name"

Program.cs

using System;

namespace RockPaperScissors
{
    partial class Program
    {
        static void Main(string[] args)
        {           
            StartGame(args);
        }

        static void StartGame(string[] args)
        {
            var playerName = (args.Length == 1) ? args[0] : "Player 1";         
            
            var player1 = new Player(playerName);
            var player2 = new ComputerPlayer();

            var game = new RPSGame(player1, player2);

            game.Init();

            while (true)
            {
                game.DisplayAvailablePlay();
                game.ReadPlayerInput();

                if (!game.IsValidPlay())
                    continue;

                game.Play();

                game.DisplayResult();
            }
            
        }
    }
}

RPSGame.cs

using System;

namespace RockPaperScissors
{
    internal partial class RPSGame
    {
        public RPSGame(Player firstPlayer, ComputerPlayer secondPlayer)
        {
            Player1 = firstPlayer;
            Player2 = secondPlayer;
        }

        internal GameStatus CurrentGameStatus = GameStatus.UnStarted;     
        internal int MatchDraws = 0;

        internal IPlayer Player1 { get; }
        internal IPlayer Player2 { get; }
        public IPlayer CurrentPlayer { get; private set; }
        public IPlayer Winner { get; private set; }


        internal void Init()
        {
            SetStatus(GameStatus.Started);
            SetCurrentPlayer(Player1);
            Console.CancelKeyPress += Console_CancelKeyPress;
        }

        public void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            this.SetStatus(GameStatus.Ended);
            e.Cancel = true;
            Environment.Exit(1);
        }

        internal void DisplayAvailablePlay()
        {
            Console.WriteLine("To play: enter R for Rock, S for Scissors, P for Paper.");
            Console.WriteLine("Press (Ctrl+C or Ctrl+Break) to Exit the game.");
        }

        internal void ReadPlayerInput()
        {
            var playerSelectedKey = Console.ReadKey(false);
            CurrentPlayer.SetSelectKey(playerSelectedKey.Key);
        }

        internal void DisplayResult()
        {
            if (Winner != null)
            {
                Console.WriteLine();
                Console.WriteLine("The Winner is:" + this.Winner.Name);
                Console.WriteLine("Played:" + GetDisplayName(this.Winner.SelectedKey));

            } else
            {
                Console.WriteLine("Draw!");
                Console.WriteLine("You both Played:" + GetDisplayName(this.Player1.SelectedKey));
            }
            Console.WriteLine($"Your Score: wins({Player1.AmountWins}), losses({Player1.AmountLoss}), draws({MatchDraws})");
        }

        private string GetDisplayName(ConsoleKey selectedKey)
        {
            return Enum.GetName(typeof(ConsoleKey), selectedKey);
        }

        internal void Play()
        {          
            ((ComputerPlayer)Player2).GenerateRandomChoice();
            SetWinner(Player1, Player2);
        }

        private void SetWinner(IPlayer player1, IPlayer player2)
        {
            var differenceInState = player1.SelectedKey - player2.SelectedKey;
            var generatedGameState = (GameState)Math.Abs(differenceInState);

            switch (generatedGameState)
            {
                case GameState.RockScissor:
                    Winner = (differenceInState < 0) ? player1 : player2;
                    break;
                case GameState.RockPaper:
                    Winner = (differenceInState < 0) ? player1 : player2;
                    break;
                case GameState.PaperScissor:
                    Winner = (differenceInState < 0) ? player2 : player1;
                    break;
                default:
                    Winner = null;
                    break;
            }

            UpdateStatistics();
            SetStatus(GameStatus.Ended);
        }

        private void UpdateStatistics()
        {
            if (Winner == Player1)
            {
                Player1.AmountWins++;
                Player2.AmountLoss++;
            }
            else if (Winner == Player2)
            {
                Player2.AmountWins++;
                Player1.AmountLoss++;
            }
            else
            {
                MatchDraws++;
            }
        }

        internal bool IsValidPlay()
        {
            switch (CurrentPlayer.SelectedKey)
            {
                case ConsoleKey.R:
                case ConsoleKey.P:
                case ConsoleKey.S:
                    return true;
            }
            return false;
        }

        private void SetCurrentPlayer(IPlayer currentPlayer)
        {
            this.CurrentPlayer = currentPlayer;
        }

        private void SetStatus(GameStatus status)
        {
            this.CurrentGameStatus = status;
        }

    }

}

BasePlayer.cs

using System;

namespace RockPaperScissors
{
    class BasePlayer :  IPlayer
    {
        public ConsoleKey SelectedKey { get; set; }
        public string Name { get; set; }
        public int AmountWins { get; set; }
        public int AmountLoss { get; set; }

        public void SetSelectKey(ConsoleKey playerSelectedKey)
        {
            SelectedKey = playerSelectedKey;
        }
    }

}

ComputerPlayer.cs

using System;

namespace RockPaperScissors
{
    class ComputerPlayer : BasePlayer
    {        
        public ComputerPlayer()
        {
            Name = "Computer Player";
            GenerateRandomChoice();
        }

        public void GenerateRandomChoice()
        {
            var rnd = new Random();
            var choice = rnd.Next(1, 4);
            switch(choice)
            {
                case 1:
                    SetSelectKey(ConsoleKey.R);
                    break;
                case 2:
                    SetSelectKey(ConsoleKey.P);
                    break;
                case 3:
                    SetSelectKey(ConsoleKey.S);
                    break;
            }
        }

    }

}

GameState.cs

namespace RockPaperScissors
{
    public enum GameState
    {
        RockScissor = 1,
        RockPaper = 2,
        PaperScissor = 3,
    }
}

GameStatus.cs

namespace RockPaperScissors
{
    public enum GameStatus
    {
        UnStarted = 0,
        Started = 1,
        Ended = -1
    }
}

IPlayer.cs

using System;

namespace RockPaperScissors
{
    interface IPlayer
    {
        public string Name { get; set; }

        public int AmountWins { get; set; }
        public int AmountLoss { get; set; }

        public ConsoleKey SelectedKey { get; set; }

        void SetSelectKey(ConsoleKey playerSelectedKey);
    }
}

Player.cs

using System;

namespace RockPaperScissors
{
    class Player : BasePlayer
    {        
        public Player(string name)
        {
            Name = name;
        }
    }
}
JohnAlexiou Nov 22 2020 at 03:57

이것은 RPS 게임에 대한 나의 견해와 사용자 입력을 처리하는 방법입니다. 현명한 디자인으로 enum여러 가지 움직임이나 결과를 설명하기 위해 몇 가지 유형을 정의했습니다 .

public enum Move
{
    Rock,
    Scissors,
    Paper,
}

public enum Outcome
{
    Tie,
    Loss,
    Win,
}

그럼 난이 개 도우미 기능, 사용자 입력합니다 (일부 처리하는 일이 영업 이익은 때문에, 게임을 결정하는 다른에 문제가 있었다를) 영업 이익은 나에게 모든 반복과 두통을 제공합니다.

C # 함수의 정신에 따라 성공 하면 반환 int.TryParse(string, out int);되도록 PlayerMove()함수를 설계했습니다 . 함수의 실제 결과는 라는 변수에 할당됩니다 .truefaseoutmove

static class Program 
{
    static readonly Random rng = new Random();

    // .. Main() goes here ==============

    /// <summary>
    /// Parses user input and decides what move was chosen if any.
    /// </summary>
    /// <param name="input">The user input.</param>
    /// <param name="move">The user move (output).</param>
    /// <returns>False if a move wasn't selected, true otherwise.</returns>
    static bool PlayerMove(string input, out Move move)
    {
        input = input.Trim().ToUpper();
        move = 0;
        if (string.IsNullOrWhiteSpace(input) || input.Length==0)
        {
            return false;
        }
        switch (input[0])
        {
            case 'R':
                move = Move.Rock;
                return true;
            case 'P':
                move = Move.Paper;
                return true;
            case 'S':
                move = Move.Scissors;
                return true;
            default:
                return false;
        }
    }

    /// <summary>
    /// Pick which combinations of plays wins for player, has a tie or a loss.
    /// </summary>
    /// <param name="player">The player move.</param>
    /// <param name="computer">The computer move.</param>
    /// <returns>The outcome of the game [Tie,Win,Loss]</returns>
    static Outcome DecideGame(Move player, Move computer)
    {
        if (player==computer)
        {
            return Outcome.Tie;
        }
        else if ((player==Move.Rock && computer==Move.Scissors)
            || (player==Move.Scissors && computer==Move.Paper)
            || (player==Move.Paper && computer==Move.Rock))
        {
            return Outcome.Win;
        }
        else
        {
            return Outcome.Loss;
        }
    }
}

이제 게임 자체 // Main() goes here가 표시된 곳에 배치 됩니다.

keepPlaying종료시기를 추적 하는 변수 가 있습니다 . 메인 게임 루프는 do { } while(keepPlaying);루프입니다.

단계는

  1. 사용자에게 프롬프트
  2. 컴퓨터가 Move무작위로 선택
  3. 사용자 입력 구문 분석 및 플레이어 할당 Move
  4. 사용자가 유효한 이동을하지 않은 경우 1 단계로 이동합니다.
  5. 사용자가 방금 Enter 키를 누르면 input빈 문자열이 포함되고 게임이 종료됩니다.
  6. 게임 결과 결정
  7. 결과를 표시하고 승패 / 승패 수를 조정합니다.

그리고 위의 주요 코드는 다음과 같습니다.

    static void Main(string[] args)
    {
        bool keepPlaying = true;
        int wins = 0, losses = 0, ties = 0;
        do
        {
            Console.WriteLine();
            Console.WriteLine($"Win={wins}, Loss={losses}, Tie={ties}"); Console.Write("To play: enter R for Rock, S for Scissors, P for Paper."); var input = Console.ReadLine(); var computer = (Move)rng.Next(0, 3); // Parse input and decide if the user made a move // or wants to quit (invalid input or none). if (PlayerMove(input, out Move player)) { Console.Write($"Player: {player}, Computer: {computer} => ");
                // Decide the outcome of the game here
                Outcome game = DecideGame(player, computer);
                switch (game)
                {
                    case Outcome.Tie:
                        ties++;
                        Console.WriteLine("Tie");
                        break;
                    case Outcome.Loss:
                        losses++;
                        Console.WriteLine("loss");
                        break;
                    case Outcome.Win:
                        wins++;
                        Console.WriteLine("Win");
                        break;
                    default:
                        throw new NotSupportedException();
                }
            }
            else
            {
                // stop when user just pressed enter.
                keepPlaying = input.Length>0;
            }
        } while (keepPlaying);
    }