So I made a basic game for a school assignment. One of the requirements is, to let program choose who is playing first, either the computer or the player. So I wrote an if/else statement then put my code inside of it. The code works, but then I added code which limits what numbers the player can input. Those numbers range from 1-3. If a players inputs a number less than one or greater than three they get an error message. After my if/else executed which picks the player who goes first, it stops working and only picks the player and not the computer. Is there a way to fix this?
int chips = 21, user, computer;
int pickPlayer;
Random rn = new Random();
pickPlayer = rn.Next(1, 5);
if (pickPlayer == 1 || pickPlayer == 2 || pickPlayer == 3 )
{
//Player goes First
while (chips > 0)
{
Console.WriteLine("There are {0} Chips Choose Either 1,2,3 chips", chips);
user = Convert.ToInt32(Console.ReadLine());
if (user > 3 || user <= 0)
{
Console.WriteLine("You can only take between 1 and 3 chips. Try again");
}
else
{
chips = chips - user;
Random rnd = new Random();
/*if (chips <= 0)
{
Console.WriteLine("You Lose");
Console.ReadLine();
} */
}
if (chips <= 0)
{
Console.WriteLine("You Lose");
Console.ReadLine();
}
}
}
else
{
//Computer goes first
while (chips > 0)
{
Console.WriteLine("There are {0} Chips Choose Either 1,2,3 or 4 chips", chips);
Random rnd = new Random();
computer = rnd.Next(1, 4);
user = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Computer picks {0} chips", computer);
chips = chips - computer;
if (chips <= 0)
{
Console.WriteLine("You Lose");
Console.ReadLine();
}
else
{
if (user > 3 || user <= 0)
{
Console.WriteLine("You can only take between 1 and 3 chips. Try again");
}
else
{
chips = chips - user;
/*if (chips <= 0)
{
Console.WriteLine("You Win");
Console.ReadLine();
} */
}
if (chips <= 0)
{
Console.WriteLine("You Win");
Console.ReadLine();
}
}
}
}
Try this.
I corrected the algorithm and I refactored the code using anonymous methods and changing names but you can create class methods instead.
I used int.TryParse instead of Convert so it returns only a number or 0 in case of error.
Random random = new Random();
int chipsStart = 21;
int chipsCurrent = chipsStart;
int playerTake;
int computerTake;
bool playerFirst = random.Next(0, 2) == 0;
Func<bool> processPlayer = () =>
{
Console.WriteLine("There are {0} Chips Choose Either 1,2,3 chips", chipsCurrent);
do
{
int.TryParse(Console.ReadLine(), out playerTake);
}
while ( playerTake == 0 );
if ( playerTake < 1 || playerTake > 3 )
Console.WriteLine("You can only take between 1 and 3 chips. Try again");
else
chipsCurrent = chipsCurrent - playerTake;
if ( chipsCurrent > 0 )
return true;
else
{
Console.WriteLine("You Lose");
return false;
}
};
Func<bool> processComputer = () =>
{
computerTake = random.Next(1, 4);
Console.WriteLine("Computer picks {0} chips", computerTake);
chipsCurrent = chipsCurrent - computerTake;
if ( chipsCurrent > 0 )
return true;
else
{
Console.WriteLine("You Win");
return false;
}
};
if ( playerFirst )
while ( true )
{
if ( !processPlayer() ) break;
if ( !processComputer() ) break;
}
else
while ( true )
{
if ( !processPlayer() ) break;
if ( !processComputer() ) break;
}
Console.ReadLine();
My assignment is to write the program in such a way that the computer's random selection is displayed before player 2 needs to input their selection. I'm having trouble getting the computer's random selection linking to my if statements. Here's my code so far:
public static void Main(string[] args) {
Random random = new Random();
int computer = random.Next(1, 4);
int player2 = 0;
string response;
string willYouPlayAgian;
Console.Write("Do you want to play Rock, Paper, Scissors? ");
willYouPlayAgian = Console.ReadLine();
willYouPlayAgian = willYouPlayAgian.ToUpper();
while (willYouPlayAgian == "YES") {
if (computer == 1)
{
Console.WriteLine("Player 1 <Compter> selection - Rock" + "\n");
}
if (computer == 2)
{
Console.WriteLine("\nPlayer 1 <Compter> selection - Paper" + "\n");
}
if (computer == 3)
{
Console.WriteLine("\nPlayer 1 <Compter> selection - Scissors" + "\n");
}
Console.Write("Player 2 selection (1=Rock, 2=Paper, 3=Scissors): ");
response = Console.ReadLine();
player2 = int.Parse(response);
if (computer == player2)
Console.WriteLine("\nDraw. No winner.");
else
if (computer == 1 && player2 == 2)
Console.WriteLine("\nPaper smothers Rock. Player 2 wins!!!");
else
if (computer == 1 && player2 == 3)
Console.WriteLine("\nRock destroys Scissors. Player 1 wins!!!");
else
if (computer == 2 && player2 == 1)
Console.WriteLine("\nPaper smothers Rock. Player 1 wins!!!");
else
if (computer == 2 && player2 == 3)
Console.WriteLine("\nScissors slices Paper. Player 2 Wins!!!");
else
if (computer == 3 && player2 == 1)
Console.WriteLine("\nRock destroys Scissors. Player 2 wins!!!");
else
if (computer == 3 && player2 == 2)
Console.WriteLine("\nScissors slices Paper. Player 1 wins!!!");
Console.Write("\nDo you want to play Rock, Paper, Scissors? ");
willYouPlayAgian = Console.ReadLine();
willYouPlayAgian = willYouPlayAgian.ToUpper();
}
Move this line down into the whileloop:
int computer = random.Next(1, 4);
Like this:
while (willYouPlayAgian == "YES")
{
int computer = random.Next(1, 4);
if (computer == 1)
{
I recently started making a RPS game console app it worked and I decided to give myself more of a challenge and decided it will be cool if it had a win rate for both computer and player and for some reason it's not showing the win rates on the left side
EDIT: So I got it to show left but the percents remain at 0 any idea how to fix this?
abstract class Participant
{
public int wins;
int _winRate;
public int winRate
{
get
{
return _winRate;
}
set
{
if (value < 0 || value > 100)
{
throw new Exception("value cannot be less than 0 or greater than 100");
}
_winRate = value;
}
}
public abstract string Choice();
public abstract void PrintWinRate();
}
class Computer : Participant
{
string[] Rock_Paper_Scissor = {"rock","paper","scissor"};
Random rand = new Random();
public override string Choice()
{
string element = Rock_Paper_Scissor[rand.Next(3)];
return element;
}
public override void PrintWinRate()
{
winRate = (wins / Game_Logic.gamesPlayed) * 100;
string _winRate = "computer win rate: "+winRate.ToString()+"%".PadRight(10);
Console.WriteLine(_winRate);
}
}
class Player : Participant
{
public override string Choice()
{
string playerChoice = Console.ReadLine().Trim();
return playerChoice;
}
public override void PrintWinRate()
{
winRate = (wins / Game_Logic.gamesPlayed) * 100;
string _winRate = "player win rate: " + winRate.ToString()+"%".PadRight(10);
Console.WriteLine(_winRate);
}
}
class Game_Logic
{
public static int gamesPlayed;
static void Main()
{
Console.BackgroundColor = ConsoleColor.Red;
Console.ForegroundColor = ConsoleColor.Black;
Computer comp = new Computer();
Player player = new Player();
string computerChoice;
string playerChoice;
ConsoleKeyInfo input;
bool playAgain;
int computerWins = comp.wins;
int playerWins = player.wins;
do
{
Console.Clear();
computerChoice = comp.Choice();
playerChoice = player.Choice();
Console.Clear();
while (playerChoice == computerChoice)
{
computerChoice = comp.Choice();
}
Console.WriteLine("Player: "+ playerChoice);
Console.WriteLine("\n"+"Computer: " + computerChoice);
if (playerChoice == "rock" && computerChoice == "scissor" || playerChoice == "paper" && computerChoice == "rock")
{
playerWins++;
Console.WriteLine("\n" + "You won!");
}
else if (playerChoice == "scissor" && computerChoice == "rock" || playerChoice == "rock" && computerChoice == "paper")
{
computerWins++;
Console.WriteLine("\n" + "Computer won!");
}
else if (playerChoice == "scissor" && computerChoice == "paper")
{
playerWins++;
Console.WriteLine("\n" + "You won!");
}
else if (playerChoice == "paper" && computerChoice == "scissor")
{
computerWins++;
Console.WriteLine("\n" + "Computer won!");
}
else
{
Console.WriteLine("\n" + "invalid value");
}
Game_Logic.gamesPlayed++;
Console.WriteLine("\n"+"Play again? <y/n>");
Console.WriteLine("\n");
comp.PrintWinRate();
player.PrintWinRate();
input = Console.ReadKey(true);
playAgain = input.KeyChar == 'y';
} while (playAgain);
}
}
First things first, I think there is a problem with the increment logic, not being able to increment the actual values of participant object. playerWins and computerWins are local variables of your main, and considered as new variable, not just as reference of your participant objects. Change the following lines:
playerWins++ to player.wins++ //Change the actual values of participant
computerWins++ to comp.wins++
Next, when you say left? What format specifically would you want? For now try the following lines:
string _winRate = string.Format("player win rate: {0}%", winRate);
Your game is displaying the scores but instantly clears the screen or exits.
Placing the 'PrintWinRate' calls before 'Console.ReadKey' should give you the desired behaviour!
Like this:
Console.WriteLine("\n" + "Play again? <y/n>");
Console.WriteLine("\n");
comp.PrintWinRate();
player.PrintWinRate();
input = Console.ReadKey(true);
Edit: There also seems to be a bug in the calculation for winRate.
You might want to change your value type for 'wins' from 'int' to 'float' so that it can store the fractional part of the calculation. As it is, when you expect a player to have 50% winRate it will show 0. This is because 'int' data types can not hold fractional values and will cut that part off, leaving the whole number - in this case 0.
This code should be closer to what you want:
winRate = (int)((wins / Game_Logic.gamesPlayed) * 100);
Remember to change 'wins' in your base class 'Participant' to be a float!
I am using the following method which works but wondering if there is a better algorithm to perform the test. Is there a better way to do it? Doing this in C# but putting syntax aside, believe the algorithm is going to be the same across OOP languages. Thank you.
public String play(int userInput)
{ //ComputerIn is a randomly generated number between 1-3
ComputerIn = computerInput();
if (ComputerIn == userInput)
return "Draw";
else if (ComputerIn == 1 && userInput == 2)
return "Win";
else if (ComputerIn == 2 && userInput == 3)
return "Win";
else if (ComputerIn == 3 && userInput == 1)
return "Win";
else if (ComputerIn == 1 && userInput == 3)
return "Lose";
else if (ComputerIn == 2 && userInput == 1)
return "Lose";
else
return "Lose";
}
if ((ComputerIn) % 3 + 1 == userInput)
return "Win";
else if ((userInput) % 3 + 1 == ComputerIn)
return "Lose"
else
return "Draw"
If you wrap 3 around to 1 (using %) then the winner is always 1 greater than the loser.
This approach is more natural when you use 0-2, in which case we would use (ComputerIn+1)%3. I came up with my answer by subbing ComputerIn with ComputerIn-1 and UserInput with UserInput-1 and simplifying the expression.
Edit, looking at this question after a long time. As written, if the ComputerIn is not used anywhere else, and is only used to determine win/lose/draw, then this method is actually equivalent to:
if (ComputerIn == 1)
return "Win";
else if (ComputerIn == 2)
return "Lose"
else
return "Draw"
This can even be further simplified to
return new String[]{"Win", "Lose", "Draw"}[ComputerIn-1];
The results from this are entirely indistinguishable. Unless the randomly generated number is exposed to outside of this method. No matter what your input is, there's always 1/3 chance of all possibilities. That is, what you're asking for, is just a complicated way of returning "Win", "Lose", or "Draw" with equal probability.
Here's one of many possible solutions. This will print Win.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Input userInput = Input.Rock;
Result result = Play(userInput);
Console.WriteLine(Enum.GetName(result.GetType(), result));
Console.ReadKey();
}
static Result Play(Input userInput)
{
Input computer = Input.Scissors;
switch (userInput)
{
case Input.Paper:
switch (computer)
{
case Input.Paper: return Result.Draw;
case Input.Rock: return Result.Win;
case Input.Scissors: return Result.Lose;
default: throw new Exception("Logic fail.");
}
case Input.Rock:
switch (computer)
{
case Input.Paper: return Result.Lose;
case Input.Rock: return Result.Draw;
case Input.Scissors: return Result.Win;
default: throw new Exception("Logic fail.");
}
case Input.Scissors:
switch (computer)
{
case Input.Paper: return Result.Win;
case Input.Rock: return Result.Lose;
case Input.Scissors: return Result.Draw;
default: throw new Exception("Logic fail.");
}
default: throw new Exception("Logic fail.");
}
}
}
enum Input
{
Rock,
Paper,
Scissors
}
enum Result
{
Lose,
Draw,
Win
}
}
This is how I would do it:
public class Program
{
public enum RPSPlay { Rock, Scissors, Paper }
public enum RPSPlayResult { Win, Draw, Loose }
public static readonly int SIZE = Enum.GetValues(typeof(RPSPlay)).Length;
static RPSPlayResult Beats(RPSPlay play, RPSPlay otherPlay)
{
if (play == otherPlay) return RPSPlayResult.Draw;
return ((int)play + 1) % SIZE == (int)otherPlay
? RPSPlayResult.Win
: RPSPlayResult.Loose;
}
static void Main(string[] args)
{
Random rand = new Random();
while (true)
{
Console.Write("Your play ({0}) (q to exit) : ", string.Join(",", Enum.GetNames(typeof(RPSPlay))));
var line = Console.ReadLine();
if (line.Equals("q", StringComparison.OrdinalIgnoreCase))
return;
RPSPlay play;
if (!Enum.TryParse(line, true, out play))
{
Console.WriteLine("Invalid Input");
continue;
}
RPSPlay computerPlay = (RPSPlay)rand.Next(SIZE);
Console.WriteLine("Computer Played {0}", computerPlay);
Console.WriteLine(Beats(play, computerPlay));
Console.WriteLine();
}
}
}
I would prefer to use a static 3x3 matrix to store the possible outcomes. But it is a question of taste, and I am a mathematician.
Here is one-liner that we created at lunchtime.
using System;
public class Rps {
public enum PlayerChoice { Rock, Paper, Scissors };
public enum Result { Draw, FirstWin, FirstLose};
public static Result Match(PlayerChoice player1, PlayerChoice player2) {
return (Result)((player1 - player2 + 3) % 3);
}
public static void Main() {
Rps.Test(Match(PlayerChoice.Rock, PlayerChoice.Rock), Result.Draw);
Rps.Test(Match(PlayerChoice.Paper, PlayerChoice.Paper), Result.Draw);
Rps.Test(Match(PlayerChoice.Scissors, PlayerChoice.Scissors), Result.Draw);
Rps.Test(Match(PlayerChoice.Rock, PlayerChoice.Scissors), Result.FirstWin);
Rps.Test(Match(PlayerChoice.Rock, PlayerChoice.Paper), Result.FirstLose);
Rps.Test(Match(PlayerChoice.Paper, PlayerChoice.Rock), Result.FirstWin);
Rps.Test(Match(PlayerChoice.Paper, PlayerChoice.Scissors), Result.FirstLose);
Rps.Test(Match(PlayerChoice.Scissors, PlayerChoice.Paper), Result.FirstWin);
Rps.Test(Match(PlayerChoice.Scissors, PlayerChoice.Rock), Result.FirstLose);
}
public static void Test(Result sample, Result origin) {
Console.WriteLine(sample == origin);
}
}
\From A java beginner Perspective. User plays with the computer to infinity.
import java.util.Scanner;
public class AlgorithmDevelopmentRockPaperScissors{
public static void main(String[] args){
System.out.println("\n\nHello Eric today we are going to play a game.");
System.out.println("Its called Rock Paper Scissors.");
System.out.println("All you have to do is input the following");
System.out.println("\n 1 For Rock");
System.out.println("\n 2 For Paper");
System.out.println("\n 3 For Scissors");
int loop;
loop = 0;
while (loop == 0){
System.out.println("\n\nWhat do you choose ?");
int userInput;
Scanner input = new Scanner(System.in);
userInput = input.nextInt();
while (userInput > 3 || userInput <= 0 ){ //ensure that the number input by the sure is within range 1-3. if else the loop trap.
System.out.println("Your choice "+userInput+" is not among the choices that are given. Please enter again.");
userInput = input.nextInt();
}
switch (userInput){
case 1:
System.out.println("You Chose Rock.");
break;
case 2:
System.out.println("You Chose Paper.");
break;
case 3:
System.out.println("You Chose Scissors");
break;
default:
System.out.println("Please Choose either of the choices given");
break;
}
int compInput;
compInput = (int)(3*Math.random()+1);
switch (compInput){
case 1:
System.out.println("\nComputer Chooses Rock.");
break;
case 2:
System.out.println("\nComputer Chooses Paper.");
break;
case 3:
System.out.println("\nComputer Chooses Scissors");
break;
}
if (userInput == compInput){
System.out.println(".........................................");
System.out.println("\nYou Both chose the same thing, the game ends DRAW.");
System.out.println(".........................................");
}
if (userInput == 1 && compInput == 2){
System.out.println(".........................................");
System.out.println("\nComputer wins because Paper wraps rock.");
System.out.println(".........................................");
}
if (userInput == 1 && compInput == 3){
System.out.println(".........................................");
System.out.println("\nYou win because Rock breaks Scissors.");
System.out.println(".........................................");
}
if (userInput == 2 && compInput == 1){
System.out.println(".........................................");
System.out.println("\nYou win Because Paper wraps Rock");
System.out.println(".........................................");
}
if (userInput == 2 && compInput == 3){
System.out.println(".........................................");
System.out.println("\nComputer wins because Scissors cut the paper");
System.out.println(".........................................");
}
if (userInput == 3 && compInput == 1){
System.out.println(".........................................");
System.out.println("\nComputer Wins because Rock Breaks Scissors.");
System.out.println(".........................................");
}
if (userInput == 3 && compInput == 2){
System.out.println(".........................................");
System.out.println("\nYou win because scissors cut the paper");
System.out.println(".........................................");
}
}
}
}
A simple JavaScript implementation using sine wave function to calculate result:
<script>
var tab = ["Lose","Draw","Win"];
var dict = ["Paper","Stone","Scissors"];
var i,text = '';
for (i = 0; i < dict.length; i++) {
text += i + '-' + dict[i] + ' ';
}
var val1 = parseInt(prompt(text));
var val2 = Math.floor(Math.random() * 3);
alert('Computer chose: ' + dict[val2]);
result = Math.sin((val1*180+1) - (val2*180+1));
alert(tab[Math.round(result)+1]);
</script>
No if's required, just for fun...
Check it
Observation: The user wins if userInput is only one ahead of computerInput (case of (1,2), (2,3)) or lag two (case of (3,1)).
Conversely, if userInput lags one behind computerInput or two ahead, the user loses.
In the modulo 3, the lag one is the same as the advance two.
(-1 mod 3 == 2 mod 3 == 2)
int decision = (userInput - computerInput + 3) % 3;
String[] answer = {"Draw", "Win", "Lose"};
return answer[decision];
This is my first year in a Computer Programming course and one of my current assignments is to create a working Rock, Paper, Scissors game.
I have most of it working but my teacher has said that I have a lot of unnecessary code without actually telling me what it is. I'd like to get this streamline as best as possible as I'm not just satisfied with whatever works.
As well, the second validation of user input (user makes a choice, program runs through and displays who wins then is asked to make a choice again) doesn't work like the first one and I can't figure out what's going wrong. I've been looking at this for the past 2 weeks and can't figure it out so any help is appreciated.
The code that I have is as follows:
namespace Assignment04
{
class Program
{
static void Main(string[] args)
{
// Declare variables
int gamesPlayed = 0, userWins = 0, computerWins = 0, draws = 0, userSelection, computerSelection;
bool inputIsValid = false;
// Prompt user
Console.WriteLine("Welcome to the Rock, Paper, Scissors game!");
Console.WriteLine("1 - Rock");
Console.WriteLine("2 - Paper");
Console.WriteLine("3 - Scissors");
Console.WriteLine("4 - Quit program and view record");
// Create a loop to validate user's selection
do
{
Console.Write("Please make a selection: ");
// loop and test using TryParse()
while (!int.TryParse(Console.ReadLine(), out userSelection))
{
// invalid data type
Console.WriteLine("Invalid input.");
Console.Write("Please make a selection: ");
}
// test if input is within acceptable range
if (userSelection >= 1 && userSelection <= 4)
{
inputIsValid = true;
}
else
{
// valid integer, but out of acceptable range
Console.WriteLine("Number out of range.");
}
} while (!inputIsValid);
// Display user's choice
while (userSelection >= 1 && userSelection <= 3)
{
if (userSelection == 1)
{
Console.WriteLine("\nYou have selected Rock");
gamesPlayed = gamesPlayed + 1;
}
else if (userSelection == 2)
{
Console.WriteLine("\nYou have selected Paper");
gamesPlayed = gamesPlayed + 1;
}
else if (userSelection == 3)
{
Console.WriteLine("\nYou have selected Scissors");
gamesPlayed = gamesPlayed + 1;
}
// Generate computer's choice
Random randomNumber = new Random();
computerSelection = randomNumber.Next(1, 4);
// Display computer's choice
if (computerSelection == 1)
{
Console.WriteLine("Computer has chosen Rock");
}
else if (computerSelection == 2)
{
Console.WriteLine("Computer has chosen Paper");
}
else if (computerSelection == 3)
{
Console.WriteLine("Computer has chosen Scissors");
}
// Calculate and display who wins
if (userSelection == computerSelection)
{
draws = draws + 1;
}
else if (userSelection == 1 && computerSelection == 3 || userSelection == 2 && computerSelection == 1 || userSelection == 3 && computerSelection == 2)
{
userWins = userWins + 1;
}
else if (userSelection == 1 && computerSelection == 2 || userSelection == 2 && computerSelection == 3 || userSelection == 3 && computerSelection == 1)
{
computerWins = computerWins + 1;
}
// Display results and statistics
Console.WriteLine("\nYou have played {0} games with {1} wins, {2} draws, and {3} losses.", gamesPlayed, userWins, draws, computerWins);
do
{
Console.Write("Please make a selection: ");
// loop and test using TryParse()
while (!int.TryParse(Console.ReadLine(), out userSelection))
{
// invalid data type
Console.WriteLine("Invalid input.");
Console.Write("Please make a selection: ");
}
// test if input is within acceptable range
if (userSelection >= 1 && userSelection <= 4)
{
inputIsValid = true;
}
else
{
// valid integer, but out of acceptable range
Console.WriteLine("Number out of range.");
}
} while (!inputIsValid);
}
if (gamesPlayed == 0 && userSelection == 4)
{
Console.WriteLine("\nGoodbye");
}
else if (gamesPlayed > 0 && userSelection == 4)
{
Console.WriteLine("\nGames played = " + gamesPlayed);
Console.WriteLine("User wins = " + userWins);
Console.WriteLine("Computer wins = " + computerWins);
Console.WriteLine("Draws = " + draws);
}
Console.ReadLine();
}
}
}
If you find yourself writing almost the same thing multiple times, you should look for ways to refactor it. Here's an example of unnecessary repeated code:
if (userSelection == 1)
{
Console.WriteLine("\nYou have selected Rock");
gamesPlayed = gamesPlayed + 1;
}
else if (userSelection == 2)
{
Console.WriteLine("\nYou have selected Paper");
gamesPlayed = gamesPlayed + 1;
}
else if (userSelection == 3)
{
Console.WriteLine("\nYou have selected Scissors");
gamesPlayed = gamesPlayed + 1;
}
Can be simplified to:
Console.WriteLine("\nYou have selected " + tools[userSelection - 1]);
gamesPlayed++;
Where tools is defined as:
string[] tools = { "Rock", "Paper", "Scissors" };