Stein, Papier, Schere in C #

Nov 21 2020

Ich mache ein Stein-, Papier- und Scherenspiel in C # und habe derzeit Probleme beim Anzeigen einer Nachricht, wenn jemand eine Eingabe eingibt, die nicht R, S oder P ist. Zum Beispiel versuche ich, die Standardeinstellung für den Schalter festzulegen Aussage zur Arbeit, habe aber kein Glück. Das ist es, was ich derzeit habe. Wenn ich weitere Probleme habe, lassen Sie es mich bitte wissen.

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
                {

                }

                }

            }

        }
    }
}

Bitte helfen Sie!

Antworten

2 RufusL Nov 21 2020 at 09:11

Hier ist eine Methode, die ich mit Konsolenanwendungen verwendet habe und die sehr hilfreich ist. Ich habe tatsächlich mehrere davon, um Typen (wie intoder double) vom Benutzer zu erhalten. Es wird eine Eingabeaufforderung angezeigt, die dem Benutzer angezeigt wird und eine optionale Validierungsmethode enthält, die für die Eingabe ausgeführt wird, um festzustellen, ob sie gültig ist.

Hier ist eine für die Eingabe von Zeichenfolgen:

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;
}

In Ihrem Fall würden Sie es einfach so nennen:

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();

Und hier ist die Beispielausgabe:

2 JamshaidK. Nov 21 2020 at 08:49

Ich würde vorschlagen, Ihre gültigen Züge in einem Array wie diesem zu deklarieren:

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

Wenn der Benutzer eine gültige oder nicht gültige Eingabe gegeben hat, bevor Ihre switch-Anweisung übereinstimmt, führen Sie die whileSchleife erneut aus, andernfalls fahren Sie mit der switchAnweisung fort. So etwas wie unten:

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

So sollte Ihre Hauptmethode aussehen:
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

Dies beantwortet Ihre Frage zwar nicht direkt, sollte jedoch die Logik / den Ablauf für ein Programm anzeigen, das Benutzereingaben anfordert und erneut fragt, ob sie eine ungültige Eingabe eingeben.

            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");
            }

Hier ist das Drucken von A / B wie das Auswählen Ihrer Hand, während das Drucken von C dem Anzeigen des Ergebnisses gleicht. Der defaultZweig verwendet continue( siehe Dokument ), um zum Anfang der Schleife zurückzukehren, und gibt daher kein C aus.

Bruno Nov 21 2020 at 10:01

Wenn Sie einen objektorientierteren Ansatz bevorzugen, finden Sie unten ein kleines Beispiel.

Verwendung: 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

Dies ist meine Sicht auf das RPS-Spiel und wie man mit Benutzereingaben umgeht. In Bezug auf das Design habe ich einige enumTypen definiert , um verschiedene Bewegungen oder Ergebnisse zu beschreiben.

public enum Move
{
    Rock,
    Scissors,
    Paper,
}

public enum Outcome
{
    Tie,
    Loss,
    Win,
}

Dann habe ich zwei Hilfsfunktionen, eine zum Behandeln der Benutzereingaben (der Teil, mit dem die Operation Probleme hatte) und die andere zum Entscheiden des Spiels, weil die Operation mir bei all den Wiederholungen Kopfschmerzen bereitet .

Im Geiste von C # -Funktionen wie int.TryParse(string, out int);ich habe die PlayerMove()Funktion so entworfen, dass sie truebei Erfolg zurückgegeben wird, und faseansonsten. Das eigentliche Ergebnis der Funktion wird der genannten outVariablen zugeordnet move.

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;
        }
    }
}

und nun soll das Spiel selbst über der // Main() goes hereangegebenen Stelle platziert werden.

Es gibt eine Variable keepPlaying, die verfolgt, wann zu beenden ist. Die Hauptspielschleife ist eine do { } while(keepPlaying);Schleife.

Die Schritte sind

  1. Fordern Sie den Benutzer auf
  2. Computer wählt Movezufällig
  3. Analysieren Sie Benutzereingaben und weisen Sie den Player zu Move
  4. Wenn der Benutzer keinen gültigen Zug gemacht hat, fahren Sie mit Schritt 1 fort
  5. Wenn der Benutzer gerade die Eingabetaste gedrückt hat, inputenthält er eine leere Zeichenfolge und das Spiel wird beendet.
  6. Entscheide über das Ergebnis des Spiels
  7. Zeigen Sie das Ergebnis an und passen Sie die Gewinn- / Unentschieden- / Verlustzahlen an.

Und der Hauptcode unten macht das Obige:

    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);
    }