C #의 가위 바위 보
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
{
}
}
}
}
}
}
도와주세요!
답변
다음은 많은 도움이되는 콘솔 응용 프로그램과 함께 사용한 방법입니다. 나는 실제로 사용자로부터 유형 ( 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();
다음은 샘플 출력입니다.

다음과 같은 배열로 유효한 이동을 선언하는 것이 좋습니다.
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
}
}
이것이 귀하의 질문에 직접 답하지는 않지만 사용자의 입력을 요청하고 잘못된 입력을 다시 입력하는지 다시 묻는 프로그램의 논리 / 흐름을 보여줍니다.
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를 인쇄하지 않습니다

보다 객체 지향적 인 접근 방식을 선호한다면 아래에 작은 예가 있습니다.
사용법 : 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;
}
}
}
이것은 RPS 게임에 대한 나의 견해와 사용자 입력을 처리하는 방법입니다. 현명한 디자인으로 enum
여러 가지 움직임이나 결과를 설명하기 위해 몇 가지 유형을 정의했습니다 .
public enum Move
{
Rock,
Scissors,
Paper,
}
public enum Outcome
{
Tie,
Loss,
Win,
}
그럼 난이 개 도우미 기능, 사용자 입력합니다 (일부 처리하는 일이 영업 이익은 때문에, 게임을 결정하는 다른에 문제가 있었다를) 영업 이익은 나에게 모든 반복과 두통을 제공합니다.
C # 함수의 정신에 따라 성공 하면 반환 int.TryParse(string, out int);
되도록 PlayerMove()
함수를 설계했습니다 . 함수의 실제 결과는 라는 변수에 할당됩니다 .true
fase
out
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;
}
}
}
이제 게임 자체 // Main() goes here
가 표시된 곳에 배치 됩니다.
keepPlaying
종료시기를 추적 하는 변수 가 있습니다 . 메인 게임 루프는 do { } while(keepPlaying);
루프입니다.
단계는
- 사용자에게 프롬프트
- 컴퓨터가
Move
무작위로 선택 - 사용자 입력 구문 분석 및 플레이어 할당
Move
- 사용자가 유효한 이동을하지 않은 경우 1 단계로 이동합니다.
- 사용자가 방금 Enter 키를 누르면
input
빈 문자열이 포함되고 게임이 종료됩니다. - 게임 결과 결정
- 결과를 표시하고 승패 / 승패 수를 조정합니다.
그리고 위의 주요 코드는 다음과 같습니다.
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);
}