Can I use randomized numbers for a switch statement? - java

So I'm trying to create a rock/paper/scissor app but I'm running into a problem. In the code below "Random r" chooses a number 1-3 and assigns it to R/P/S. That part works, but the scoring or toast code within my switch statement does not. The integer next to "case" should be the value of the choice correct? If anyone can find my problem I would appreciate it.
public void decide(){
int playerTotal = 0;
int computerTotal = 0;
TextView pTotal = (TextView)findViewById(R.id.playerTotal);
TextView cTotal = (TextView)findViewById(R.id.compTotal);
pTotal.setText(Integer.toString(playerTotal));
cTotal.setText(Integer.toString(computerTotal));
int cpu = r.nextInt(3); //Randomizer will choose 1-3
if(cpu == 1) {
cpuChoice = "rock";
imgCpu.setImageResource(R.drawable.rock);
}
else if(cpu == 2){
cpuChoice = "paper";
imgCpu.setImageResource(R.drawable.paper);
}
else if(cpu == 3){
cpuChoice = "scissors";
imgCpu.setImageResource(R.drawable.scissors);
}
String winOrLose = "";
switch (cpu){
case 1:
if(myChoice == "rock") {
winOrLose = "Stalemate!";
}
if(myChoice == "paper") {
winOrLose ="paper beats rock! You won this round!";
playerTotal++;
}
if(myChoice == "scissors") {
winOrLose = "rock beats paper! You lost this round!";
computerTotal++;
}
Toast.makeText(MainActivity.this,winOrLose, Toast.LENGTH_SHORT);
break;
case 2:
if(myChoice == "rock") {
winOrLose = "paper beats rock! You lost this round!";
computerTotal++;
}
if(myChoice == "paper") {
winOrLose = "Stalemate!";
}
if(myChoice == "scissors") {
winOrLose = "scissors beats paper! You won this round!";
playerTotal++;
}
Toast.makeText(MainActivity.this,winOrLose, Toast.LENGTH_SHORT);
break;
case 3:
if(myChoice == "rock") {
winOrLose = "rock beats scissors! You won this round!";
playerTotal++;
}
if(myChoice == "paper") {
winOrLose = "scissors beats paper! You lost this round!";
computerTotal++;
}
if(myChoice == "scissors") {
winOrLose = "Stalemate!";
}
Toast.makeText(MainActivity.this,winOrLose, Toast.LENGTH_SHORT);
break;
}
}

As #Seelenvirtuose said you nextInt() will generate value between 0-2 but not 1-3 (assuming your sending 3 as the parameter for nextInt() method).
So to generate value exactly between 1-3 you can try below code.
int minimum = 1;
int maximum = 4;
Random random = new Random();
int randomValue = random.nextInt( maximum - minimum ) + minimum;
To know more about generating random number between specified range you visit here

I figured it out! The scoring did not work because every time the method was called, the scored would reset to 0, so I swapped it to the end of the method and erased the zeroes. For the toast, I had to add .show() at the end like so:
Toast.makeText(MainActivity.this,winOrLose, Toast.LENGTH_SHORT).show();
Thanks for the suggestions everyone! Random worked 1-3 for me, but I changed it to 0-2 to be technically correct.

Related

Rock Paper Scissors simple java using methods

So my task today is to make a rock paper scissors game using methods. My first problem with my code is that I need it to ask the user if they want to play again or not. (y or n) Also, I need to implement scoring, 1 point if user wins, -1 if they lose, and for each time they play again add that score to total score. Any ideas on how to implement this? or what I need to change to my code. Also I am a rookie so sorry for the ugly formatting and feel free to critic every little detail, ill soak up all the information I can.
public static void main(String[] args){
boolean tie = true;
do{
String computer = computerChoice();
String user = userChoice();
tie = (computer.compareTo(user) == 0);
determineWinner(computer, user);
}while(tie);
}
public static String computerChoice( ){
Random rand = new Random();
int cinput = rand.nextInt(3)+ 1;
String computer = "thing";
if (cinput == 1)
computer = "Rock";
if (cinput == 2)
computer = "Paper";
if (cinput == 3)
computer = "Scissors";
return computer;
}
public static String userChoice(){
Scanner sc = new Scanner (System.in);
String user = "default";
do{
System.out.println("choose your weapon(Paper,Scissors or Rock)");
user = sc.nextLine();
}
while (isValidChoice (user) == false);
return user;
}
public static boolean isValidChoice(String choice){
boolean status;
if (choice.compareTo("Rock")== 0)
status = true;
else if (choice.compareTo("Paper")== 0)
status = true;
else if (choice.compareTo("Scissors")== 0)
status = true;
else{
status = false;
System.out.println("Error! Make sure you are capitalizing your choices");
}
return status;
}
public static boolean determineWinner(String computer, String user){
System.out.println (" Computer Choice: " + computer);
System.out.println ("Your Choice : " + user);
if (computer.compareTo( "Rock" ) == 0 && user.compareTo ("Scissors") == 0)
System.out.println (" Computer wins! Better luck next time!");
if (computer.compareTo("Scissors")== 0 && user.compareTo("Paper") == 0)
System.out.println (" Computer wins! Better luck next time!");
if (computer.compareTo("Paper") == 0 && user.compareTo("Rock") == 0)
System.out.println (" Computer wins! Better luck next time!");
if (computer.compareTo("Rock") == 0 && user.compareTo("Paper") == 0)
System.out.println (" You win!!");
if (computer.compareTo("Scissors") == 0 && user.compareTo("Rock") == 0)
System.out.println (" You win!!");
if (computer.compareTo("Paper") == 0 && user.compareTo("Scissors") == 0)
System.out.println (" You win!!");
else if (computer.compareTo(user) == 0 ){
System.out.println(" Tie! the game must be played again.");
return false;
}
return true;
}
}
a output that my professor gave us as an example is:
Choose your weapon!
1. Paper
2. Scissors
3. Rock
5
Choose your weapon!
1. Paper
2. Scissors
3. Rock
1
You chose paper!
I choose rock!
I have been vanquished!
We have matched wits 1 times, and your score is 1
Do you want to play again (y or n)? y
Choose your weapon!
1. Paper
2. Scissors
3. Rock
1
You chose paper!
I choose paper!
We are equally matched. You are a worthy adversary.
We have matched wits 2 times, and your score is 1
Do you want to play again (y or n)? n
Here is the finished code. I added two functions, one to call the actual game and one to check if the player wanted to play again. Also, there is the concluding sentence in the end
import java.util.Random;
import java.util.Scanner;
public class RPC
{
public static Scanner sc = new Scanner(System.in);
public static int score = 0;
public static int gameCount = 0;
public static void main(String[] args)
{
play();
while (playAgain())
{
play();
}
}
public static void play()
{
String computer = computerChoice();
String user = userChoice();
determineWinner(computer, user);
}
public static String computerChoice()
{
Random rand = new Random();
int cinput = rand.nextInt(3) + 1;
String computer = "thing";
if (cinput == 1)
computer = "Rock";
if (cinput == 2)
computer = "Paper";
if (cinput == 3)
computer = "Scissors";
return computer;
}
public static boolean playAgain()
{
System.out.println("Play again?(y/n)");
String input = sc.nextLine();
if (input.toLowerCase().equals("y"))
{
return true;
} else if (input.toLowerCase().equals("n"))
{
return false;
} else
{
System.out.println("Invalid Input");
return playAgain();
}
}
public static String userChoice()
{
String user = "default";
do
{
System.out.println("choose your weapon(Paper,Scissors or Rock)");
user = sc.nextLine();
} while (!isValidChoice(user));
return user;
}
public static boolean isValidChoice(String choice)
{
boolean status;
if (choice.equals("Rock"))
status = true;
else if (choice.equals("Paper"))
status = true;
else if (choice.equals("Scissors"))
status = true;
else
{
status = false;
System.out.println("Error! Make sure you are capitalizing your choices");
}
return status;
}
public static void determineWinner(String computer, String user)
{
gameCount++;
System.out.println(" Computer Choice: " + computer);
System.out.println("Your Choice : " + user);
if (computer.equals("Rock") && user.equals("Scissors"))
{
score--;
System.out.println(" Computer wins! Better luck next time!");
}
if (computer.equals("Scissors") && user.equals("Paper"))
{
score--;
System.out.println(" Computer wins! Better luck next time!");
}
if (computer.equals("Paper") && user.equals("Rock"))
{
score--;
System.out.println(" Computer wins! Better luck next time!");
}
if (computer.equals("Rock") && user.equals("Paper"))
{
score++;
System.out.println(" You win!!");
}
if (computer.equals("Scissors") && user.equals("Rock"))
{
score++;
System.out.println(" You win!!");
}
if (computer.equals("Paper") && user.equals("Scissors"))
{
score++;
System.out.println(" You win!!");
} else if (computer.equals(user))
{
System.out.println(" Tie! the game must be played again.");
}
System.out.println("We have matched wits" + gameCount + "times, and your score is" + score);
return;
}
}

Monty Hall lets make a deal in JAVA using simpler operators and functions

So I've been working on this assignment for about 12 hours and have been unsuccessful in covering all the parameters. I was asked to make a program based off of Monty Hall "Lets make a deal" and asked to check each user input for validity up to the switching of doors;
I'm having the following issues:
if the user wants to switch doors after a zonk is revealed they're taken back to the main menu where they're asked to pick a door. then put in a continuous input loop
if the user's input is invalid at the switch doors scenario then the same problem as above happens
problem displaying the win percentage
problem when wanting to play the game again
please help, somewhat of a beginner so criticism is more than welcomed on all parts of the code.
System.out.println("WELCOME TO 'LETS MAKE A DEAL'");
System.out.println("Please Enter 'A' to Play, 'B' To Watch, or 'Q' To Quit");
Scanner input = new Scanner (System.in);
String choice = input.next();
boolean done = false;
double wins = 0;
double loses = 0;
double games = 0;
while (!done)
{
if(choice.equals("A"))
{
System.out.println("Please Choose a door:\n");
System.out.println("[1] [2] [3]\n");
System.out.println("Type '1', '2', or '3'");
if(input.hasNextInt())
{
int chosenDoor = input.nextInt();
if(chosenDoor <= 3 && chosenDoor > 0)
{
int prizeIs = (int) ((Math.random() * 3) + 1);
int finChoice = 0;
int zonkIs = 0;
while (prizeIs == chosenDoor)
{
zonkIs = (int) ((Math.random() * 3) + 1);
while (zonkIs == prizeIs)
{
zonkIs = (int) ((Math.random() * 3) + 1);
}
}
if (prizeIs == 1 && chosenDoor == 2)
{
zonkIs = 3;
}
else if (prizeIs == 1 && chosenDoor == 3 )
{
zonkIs = 2;
}
else if (prizeIs == 2 && chosenDoor == 1 )
{
zonkIs = 3;
}
else if (prizeIs == 2 && chosenDoor == 3 )
{
zonkIs = 1;
}
else if (prizeIs == 3 && chosenDoor == 1 )
{
zonkIs = 2;
}
else if (prizeIs == 3 && chosenDoor == 2 )
{
zonkIs = 1;
}
System.out.println("\nI Will Now Reveal A Zonk\n\nDoor [" + zonkIs + "]");
System.out.println("\nKnowing This, Would You Like To Switch Doors? ('Y' or 'N') ");
String decision = input.next();
if(decision.equals("Y"))
{
System.out.println("Pick A New Door (Not The One With A Zonk)");
chosenDoor = input.nextInt();
finChoice = chosenDoor;
System.out.println("\nWell Then\n\nThe Moment You've Been Waiting For\n");
System.out.println("The Prize is in\n\nDoor [" + prizeIs + "]");
if (prizeIs == finChoice || prizeIs == chosenDoor)
{
System.out.println("\nCONGRATUALTIONS!!!\nYOU WON!!!!!");
wins++;
games++;
}
else
{
System.out.println("\n..Sorry, You Lost.");
loses++;
games++;
}
System.out.println("\nWould You Like To Play Again? ('Y' or 'N')");
decision = input.next();
if(decision.equals("N"))
{
System.out.println("\nWell Thanks For Playing\nYour Win Percentage was ");
if(wins <= 0.0 || wins < loses)
{
double percentage = 0;
System.out.printf(percentage +"%");
}
else
{
double percentage = (wins-loses)/games * 100;
System.out.printf("%5.2f", percentage +"%");
}
done = true;
input.close();
}
else if(decision.equals("Y"))
{
System.out.println("*******************************");
}
else
{
System.out.println("Invalid Entry, Please Try Again ('Y' or 'N')");
}
}
else if(decision.equals("N"))
{
finChoice = chosenDoor;
System.out.println("\nWell Then\n\nThe Moment You've Been Waiting For\n");
System.out.println("The Prize is in\n\nDoor [" + prizeIs + "]");
if (prizeIs == finChoice || prizeIs == chosenDoor)
{
System.out.println("\nCONGRATUALTIONS!!!\nYOU WON!!!!!");
wins++;
games++;
}
else
{
System.out.println("\n..Sorry, You Lost.");
loses++;
games++;
}
System.out.println("\nWould You Like To Play Again? ('Y' or 'N')");
decision = input.next();
if(decision.equals("N"))
{
System.out.println("\nWell Thanks For Playing\nYour Win Percentage was ");
if(wins <= 0.0 || wins < loses)
{
double percentage = 0;
System.out.printf(percentage +"%");
}
else
{
double percentage = (wins-loses)/games * 100;
System.out.printf("%5.2f", percentage +"%");
}
done = true;
input.close();
}
else if(decision.equals("Y"))
{
System.out.println("*******************************");
}
else
{
System.out.println("Invalid Entry, Please Try Again ('Y' or 'N')");
}
}
else
{
System.out.println("Invalid Entry, Please Try Again ('Y' or 'N')");
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
}
}
else
{
System.out.println("Invalid Entry, Please Try Again.");
input.next();
}
}
else if(choice.equals("B"))
{
}
else if(choice.equals("Q"))
{
done = true;
input.close();
}
else
{
System.out.println("Invalid Entry, Please Try Again..");
choice = input.next();
}
}
}
}
First, this part of the code makes no sense:
while (prizeIs == chosenDoor)
{
zonkIs = (int) ((Math.random() * 3) + 1);
while (zonkIs == prizeIs)
{
zonkIs = (int) ((Math.random() * 3) + 1);
}
}
The outer while loop here, since you change neither prizeIs nor chosenDoor inside, is going to be an endless loop.
Also, there is no point in choosing zonks out of the three doors, because after we have a prizeIs, there are only two zonks, which are the other doors. It would be best to use collections or array shuffles, I suppose, but if you are not allowed, you could list the possibilities.
if ( prizeIs == chosenDoor ) { // Note it's an if, not a while.
boolean chooseFirstZonk = Math.random() < 0.5; // 50% chance
switch ( prizeIs ) {
case 1:
if ( chooseFirstZonk ) {
zonkIs = 2;
} else {
zonkIs = 3;
}
break;
case 2:
if ( chooseFirstZonk ) {
zonkIs = 1;
} else {
zonkIs = 3;
}
break;
case 3:
if ( chooseFirstZonk ) {
zonkIs = 1;
} else {
zonkIs = 2;
}
break;
}
}
Then this if:
if (prizeIs == 1 && chosenDoor == 2)
becomes an else if to the above if.
Next, you have a bit of a misunderstanding about the game. Now that the zonk has been revealed, there are only two doors that are covered. If the user chooses to switch, he is not supposed to select a new door out of three. One is known to be a zonk, and one is known to be his previous choice which he chose to abandon. So when a user wants to switch, you are supposed to simply change chosenDoor to the unrevealed door.
If the original chosen door is the prize door, you are supposed to switch chosenDoor to the second zonk. So if prizeIs is 1, and so is chosenDoor, and zonkIs is 2, you change chosenDoor = 3. If zonkIs is 3, you do chosenDoor = 2.
If the original chosen door is not the prize door, you are supposed to assign chosenDoor = prizeIs - as the user chose a zonk, and you revealed the other zonk, so the only one remaining is the prize door.
So no user input is required in this case.
So you will need to change that large if-else. If the user chose to switch, you do the calculation. This if has no else, as when the user didn't say yes, he means to keep his original choice. At this point, check if chosenDoor == prizeIs, and calculate the percentages.
Calculations
First, you only need to keep two variables. Like wins and losses, or wins and games, or losses and games. You can always calculate losses as games - wins.
So always do games++, don't do losses at all, and do wins++ when the player wins.
Now calculating the success percentage does not require those ifs. wins cannot be less than zero. it also can't be greatar than games.
But what is important is to remember that if you divide an integer by an integer, you are going to get integer division. That is, 5/10 gives you zero, not 0.5, because it's not an integer.
So it's important to convert one of the numbers to double before you divide. One simple way to do this is to change the 100 to 100.0, and move it to the beginning:
double percentage = 100.0 * wins / games;
This way, 100.0 * wins automatically converts the value of wins to double. Therefore, when the result of it is divided by games, the value of games is also converted to double, and there is no integer division.

Rock, Paper, Scissors game

I have my app class for the game Rock, Paper, Scissors. My problem is if I win two times or the computer wins two times I need the game to stop generating but it keeps going one more time. How can I rectify this?
import javax.swing.JOptionPane;
public class RockPaperScissorsApp
{
public static void main(String args[])
{
String player1, winner;
int player2, gamesPlayed = 1, player1Wins = 0, player2Wins = 0;
do
{
RockPaperScissors myRock = new RockPaperScissors();
player1 = JOptionPane.showInputDialog(null,
"Please enter your choice, Rock, Paper or Scissors");
myRock.setPlayer1(player1);
myRock.compute();
winner = myRock.getWinner();
player2 = myRock.getPlayer2();
if(winner.equals("Player 1"))
{
if(player2 == 1)
{
JOptionPane
.showMessageDialog(null,
"Congratulations, you have beaten the computer! The computer chose Rock");
}
else if(player2 == 2)
{
JOptionPane
.showMessageDialog(null,
"Congratulations, you have beaten the computer! The computer chose Paper");
}
else
{
JOptionPane
.showMessageDialog(null,
"Congratulations, you have beaten the computer! The computer chose Scissors");
}
player1Wins = player1Wins + 1;
}
else if(winner.equals("Player 2"))
{
if(player2 == 1)
{
JOptionPane
.showMessageDialog(null,
"Hard Luck, you have been beaten by the computer! The computer chose Rock");
}
else if(player2 == 2)
{
JOptionPane
.showMessageDialog(null,
"Hard Luck, you have been beaten by the computer!The computer chose Paper");
}
else
{
JOptionPane
.showMessageDialog(null,
"Hard Luck, you have been beaten by the computer! The computer chose Scissors");
}
player2Wins = player2Wins + 1;
}
else if(winner.equals("draw"))
{
if(player2 == 1)
{
JOptionPane.showMessageDialog(null,
"It was a draw this time! The computer chose Rock");
}
else if(player2 == 2)
{
JOptionPane
.showMessageDialog(null,
"It was a draw this time! The computer chose Paper");
}
else
{
JOptionPane
.showMessageDialog(null,
"It was a draw this time! The computer chose Scissors");
}
gamesPlayed = gamesPlayed + 0;
}
else
{
JOptionPane.showMessageDialog(null,
"You have entered an invalid option");
gamesPlayed = gamesPlayed - 1;
}
if(player1Wins == 2)
{
JOptionPane.showMessageDialog(null, "You win");
gamesPlayed = gamesPlayed + 2;
}
else if(player2Wins == 2)
{
JOptionPane.showMessageDialog(null, "He wins");
gamesPlayed = gamesPlayed + 2;
}
if((gamesPlayed == 2) || (gamesPlayed == 3))
{
JOptionPane.showMessageDialog(null, "The score is "
+ player1Wins + " for player1 and " + player2Wins
+ " for player2");
}
gamesPlayed = gamesPlayed + 1;
}
while(gamesPlayed <= 3);
}
}
Change your while loop condition:
while(player1Wins < 2 && player2Wins < 2)
Also, I would advise against using magic numbers; this is more maintainable:
public static final int VICTORY_THRESHOLD = 2;
.
.
.
while(player1Wins < VICTORY_THRESHOLD
&& player2Wins < VICTORY_THRESHOLD)
Also, consider creating an Enum for ROCK,PAPER,SCISORS. Then consider making a Comparator that takes the two Enums and returns -1 for losses, 0, for draw, and 1 for win.
public Enum RPS {
ROCK(),PAPER(),SCISSORS();
public int compare(RPS that) {
if(this==that)
return 0;
switch(this) {
case ROCK: return that==RPS.PAPER ? -1 : 1;
case PAPER: return that==RPS.SCISSORS ? -1 : 1;
case SCISSORS: return that==RPS.ROCK ? -1 : 1;
default: return null; /* never reached */
}
}
public String toString() {
switch(this) {
case ROCK: return "Rock";
case PAPER: return "Paper";
case SCISSORS: return "Scissors";
default: return null; /* never reached */
}
}
}
Using an Enum would make your conditional code much cleaner:
RPS player1Choice = RPS.ROCK;
RPS player2Choice = RPS.SCISSORS;
int result player1Choice.compare(player2Choice); /* 1 */
if(result == 0)
System.out.println("Draw, you both chose "+player1Choice);
else
System.out.println("You "+ (result > 0 ? "won" : "lost") +
" with "+player1Choice+
"\nThe computer chose"+player2Choice);
if(result != 0)
result > 0 ? ++player1Wins : ++player2Wins;
++gamesPlayed;
You said do... while(gamesPlayed <= 3) which means after 3 games have been played, the statement is still true, so it goes ahead and loops again.
To fix this, you can either change that 3 to a 2 or change the <= sign to a < sign.

A more efficient way that takes less space? this is a method btw

Here's part of a code for a Rock Paper Scissors project and im just wondering if there is a way to do this that takes up less space. Preferably more efficient too. Basically this is a method and what this method does is compare user inputs to see if one side beats the other.
Thanks.
public String determineWinner()
{
String winner = "yolo"; //if fail
if(compChoice.equals("S") && (playChoice.equals("s")))
{
winner = "nobody. There was a tie because you guessed the same thing.";
}
if(compChoice.equals("P") && (playChoice.equals("p")))
{
winner = "nobody. There was a tie because you guessed the same thing.";
}
if(compChoice.equals("R") && (playChoice.equals("r")))
{
winner = "nobody. There was a tie because you guessed the same thing.";
}
if(compChoice.equals(playChoice)) //R R, R P, R S
{
winner = "nobody. There was a tie because you guessed the same thing.";
}
if(compChoice.equals("R") && (playChoice.equals("P") || playChoice.equals("p"))) //R P
{
winner = "player because Paper beats Rock.";
}
if(compChoice.equals("R") && (playChoice.equals("S") || playChoice.equals("s"))) //R S
{
winner = "computer because Rock beats Scissors.";
}
if(compChoice.equals("P") && (playChoice.equals("R") || playChoice.equals("r")))//P R
{
winner = "computer because Paper beats Rock.";
}
if(compChoice.equals("P") && (playChoice.equals("S") || playChoice.equals("s")))//P S
{
winner = "player because Scissors beats Paper.";
}
if(compChoice.equals("S") && (playChoice.equals("R") || playChoice.equals("r"))) //S R
{
winner = "player because Rock beats Scissors.";
}
if(compChoice.equals("S") && (playChoice.equals("P") || playChoice.equals("p"))) //S P
{
winner = "computer because Scissors beats Paper.";
}
return winner;
}
You can do this
String[] words = "Rock,Paper,Scissors".split(",");
// turn the choice into an index where higher wins.
// i.e. 0 < 1 < 2 < 0 (using clock arithmetic)
int human = "RPS".indexOf(playChoice.toUpperCase());
int comp = "RPS".indexOf(compChoice.toUpperCase());
// if the index is the same, no winner
if (human == comp)
return "No winner, choices are the same";
// if the human has the higher index (using clock arithmetic), the human wins.
if (human == (comp+1) % 3)
return "Human winner as " + words[human] + " beats " + words[comp];
// otherwise the computer must have won.
return "Computer winner as " + words[comp] + " beats " + words[human];
String winner = "";
String playersChoice = playChoice.toUpperCase();
if(compChoice.equals(playersChoice))
return "tie";
switch(compChoice) {
case "S":
switch(playersChoice) {
case "P":
winner = "computer";
break;
case "R":
winner = "player";
break;
}
break;
case "P":
switch(playersChoice) {
case "S":
winner = "player";
break;
case "R":
winner = "computer";
break;
}
break;
case "R":
switch(playersChoice) {
case "S":
winner = "computer";
break;
case "P":
winner = "player";
break;
}
break;
}
return winner;
for more efficient I would suggest you to go for nested if else statements instead of only if statements like
if {} else{if(){} else{....}}
In your code each and every if loop will be executed which decreases the efficiency so use nested if else
Useful link for nested if else
You can use more efficient char comparison
char cc = compChoice.charAt(0);
char pc = playChoice.charAt(0);
if (cc == 'S' && pc == 's') {
...
} else if (
...
JqueryLearner is right, but you get a much cleaner if-else if you do this:
if () {
} else if () {
} else if () {
} else {
}
You need to think more about general rules and simplification and less about the specifics.
For example if you took the input and put it to lowercase you then just need to check for r, s etc rather than R, S as well.
If you then check for the two being equal (you don't care if its r and r, or s and s - you just need them to be the same) that handles all the draws.
You then just need to check r > s > p > r.
You can have an if clause for checking if both computer and player choices are same, for eg:
if(compChoice.equalsIgnoreCase(playerChoice)){
return "TIE"
}
Note i used ignoreCase to avoid your multiple if for lower and upper cases.
OR
Create an array for options : [ paper, rock, scissors]
Now paper beats rock, rock beats scissors and scissors beats paper.
You would have to calculate index of comp and player choice from this array and then use following formula for result:
int result = (playerChoiceNum - compChoiceNum) % 3
playerChoiceNum and compChoiceNum are indexes from array.
If result is 0 it is tie,else if result is negative comp wins and else result is positive player wins.
How about using an enum here's the entire game...
public static enum RPS {
ROCK, PAPER, SCISSORS;
// Simple method to get the appropriate enum.
public static RPS fromString(String in) {
if (in.toLowerCase().startsWith("r")) {
return ROCK;
} else if (in.toLowerCase().startsWith("p")) {
return PAPER;
} else if (in.toLowerCase().startsWith("s")) {
return SCISSORS;
}
return null;
}
// Calculate the winner in a contest.
public Boolean wins(RPS in) {
if (this == in) { // Tie!
return null;
}
switch (this) {
case ROCK:
if (in == SCISSORS) { // Rock beats scissors.
return true;
}
return false;
case PAPER:
if (in == ROCK) { // Paper beats rock.
return true;
}
return false;
case SCISSORS:
if (in == PAPER) { // Scissors beats paper.
return true;
}
return false;
}
return null;
}
}
public static void main(String[] args) {
Random r = new Random(System.currentTimeMillis());
String[] choices = new String[] { "R", "P", "S" };
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
System.out.println("Please enter (R)ock, (P)aper "
+ "or (S)cissors to play. (Q)uit.");
String c = in.nextLine();
c = c.trim();
if (c.toLowerCase().startsWith("q")) {
break;
}
RPS player = RPS.fromString(c);
RPS computer = RPS.fromString(choices[r
.nextInt(choices.length)]);
System.out.println("Computer picked " + computer);
if (player.wins(computer) == null) {
System.out.println("It's a Tie");
} else if (player.wins(computer)) {
System.out.println("You won");
} else {
System.out.println("The comptuer won");
}
}
}
ok first your question is misleading
but
if you use .equalsIgnoreCase() This will allow you you to check for both,
'P' and 'p' for paper so it stops you have to check both 'P' and 'p'.
The if and else if would work better here as:
if a statement is not true it will go to the else if to check if this is true and if this is not true it will move on to the next statement to see which is true.
The else then says that if none of the above if and else ifs are true it has to be this option.
if(compChoice.equalsIgnoreCase(playChoice)) //R R, R P, R S
{
winner = "nobody. There was a tie because you guessed the same thing.";
}
else if(compChoice.equals("R") && (playChoice.equalsIgnoreCase("P"))) //R P
{
winner = "player because Paper beats Rock.";
}
else if(compChoice.equals("R") && (playChoice.equalsIgnoreCase("S"))) //R S
{
winner = "computer because Rock beats Scissors.";
}
else if(compChoice.equals("P") && (playChoice.equalsIgnoreCase("R")))//P R
{
winner = "computer because Paper beats Rock.";
}
else if(compChoice.equals("P") && (playChoice.equalsIgnoreCase("S")))//P S
{
winner = "player because Scissors beats Paper.";
}
else if(compChoice.equals("S") && (playChoice.equalsIgnoreCase("R"))) //S R
{
winner = "player because Rock beats Scissors.";
}
else//S P
{
winner = "computer because Scissors beats Paper.";
}
return winner;
Thats as short and efficient I can make it.
This works as well
public String determineWinner() {
Map<String, String> shortcutMap = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
Map<String, Map<String, Integer>> winMap = new TreeMap<String, Map<String, Integer>>(String.CASE_INSENSITIVE_ORDER);
shortcutMap.put("R", "Rock");
shortcutMap.put("P", "Paper");
shortcutMap.put("S", "Scissors");
winMap.put("R", new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER));
winMap.put("P", new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER));
winMap.put("S", new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER));
winMap.get("R").put("R", 0); // Rock draw against Rock,
winMap.get("R").put("P", -1); // Rock loose against Paper,
winMap.get("R").put("S", 1); // Rock win against Scissors,
winMap.get("P").put("R", 1); // Paper win against Rock,
winMap.get("P").put("P", 0); // Paper draw against Paper,
winMap.get("P").put("S", -1); // Paper loose against Scissors,
winMap.get("S").put("R", -1); // Scissors loose against Rock,
winMap.get("S").put("P", 1); // Scissors win against Paper,
winMap.get("S").put("S", 0); // Scissors draw against Scissors,
String winner = "yolo"; // if fail
Integer result = winMap.get(compChoice).get(playChoice);
if (result > 0) {
winner = "computer because " + shortcutMap.get(compChoice) + " beats " + shortcutMap.get(playChoice) + ".";
}
else if (result < 0) {
winner = "player because " + shortcutMap.get(playChoice) + " beats " + shortcutMap.get(compChoice) + ".";
}
else {
winner = "nobody. There was a tie because you guessed the same thing.";
}
return winner;
}

How to fix the computerChoice always choosing rock which is integer 1

I'm trying to get a random number using the Random().nextInt() function. I don't know if it's right or if my logic is messed up or not reading right. Also for loop isn't working the way that it's suppose to be working. Can you please help? I'm trying to finish an assignment for class since we started Java like last month.
//DECLARE VARIABLES
String rounds, userChooses;
Random computerChooses = new Random();
int round = 1;
int userChoice = 0;
final int ONE = 1;
final int TWO = 2;
final int THREE = 3;
int computerChoice = computerChooses.nextInt(3) + 1;
//ASK USER FOR NUMBER OF ROUNDS
rounds = JOptionPane.showInputDialog(null, "How many rounds do you want to play?");
round = Integer.parseInt(rounds);
//TRACK NUMBER OF ROUNDS
for (int x = 1; x <= round; x++) {
JOptionPane.showMessageDialog(null, "This is round " + x + ".");
//CREATE THE INPUT FOR THE USER
try {
//START GAME
userChooses = JOptionPane.showInputDialog(null, "Enter 1)rock, 2)paper, or 3)scissors!");
userChoice = Integer.parseInt(userChooses);
if (userChoice > 3 || userChoice < 1) {
throw new Exception();
}
} catch (Exception ex) {
JOptionPane.showInputDialog(null, "That wasn't a number!", "Error!", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(null, "You have not entered correct number! Terminating program!");
System.exit(0);
}
if (userChoice == ONE) {
if (computerChoice == ONE) {
JOptionPane.showMessageDialog(null, "You tied the computer.\nYou chose: rock\nComputer chose: rock");
} else if (computerChoice == TWO) {
JOptionPane.showMessageDialog(null, "You lost!\nYou chose: rock\nComputer chose: paper");
} else if (computerChoice == THREE){
JOptionPane.showMessageDialog(null, "You won!\nYou chose: rock\nComputer chose: scissors");
}
} else if (userChoice == TWO) {
if (computerChoice == ONE) {
JOptionPane.showMessageDialog(null, "You won!\nYou chose: paper\nComputer chose: rock");
} else if (userChoice == TWO) {
JOptionPane.showMessageDialog(null, "You tied!\nYou chose: paper\nComputer chose: paper");
} else if (userChoice == THREE) {
JOptionPane.showMessageDialog(null, "You lost!\nYou chose: paper\nComputer chose: scissors");
}
} else if (userChoice == THREE) {
if (computerChoice == ONE) {
JOptionPane.showMessageDialog(null, "You lost!\nYou chose: scissors\nComputer chose: rock");
} else if (computerChoice == TWO) {
JOptionPane.showMessageDialog(null, "You won!\nYou chose: scissors\nComputer chose: paper");
} else if (computerChoice == THREE) {
JOptionPane.showMessageDialog(null, "You tied!\nYou chose: scissors\nComputer chose: scissors");
}
}
}
}
Every time I choose something, it says that the computer always chooses the rock option. Any idea?
Simply by using a Random object:
new Random().nextInt(3) + 1;
As for your for-loop, the closing brace should be put after your catch Exception-block and not after: JOptionPane.showMessageDialog(null, "This is round " + round + ".");
Here is something that seems to work better:
import java.util.Random;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class RockPaperScissors {
private static final int ROCK = 1;
private static final int PAPER = 2;
private static final int SCISSORS = 3;
private Random computerChooses = new Random();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new RockPaperScissors().play();
}
});
}
protected void play() {
String rounds;
String userChooses;
int round = 0;
int userChoice;
// CREATE THE INPUT FOR THE USER
try {
rounds = JOptionPane.showInputDialog(null, "How many rounds do you want to play?");
round = Integer.parseInt(rounds);
// CREATE COUNTER
for (int x = 0; x < round; x++) {
int computerChoice = computerChooses.nextInt(3) + 1;
JOptionPane.showMessageDialog(null, "This is round " + x + ".");
// START GAME
userChooses = JOptionPane.showInputDialog(null, "Enter 1)rock, 2)paper, or 3)scissors!");
userChoice = Integer.parseInt(userChooses);
String message = null;
switch (userChoice) {
case ROCK:
switch (computerChoice) {
case ROCK:
message = "You tied computer. You both chose rock";
break;
case PAPER:
message = "You win.";
break;
case SCISSORS:
message = "You loose";
break;
}
break;
case PAPER:
switch (computerChoice) {
case ROCK:
message = "You win.";
break;
case PAPER:
message = "You tied computer. You both chose paper";
break;
case SCISSORS:
message = "You loose";
break;
}
break;
case SCISSORS:
switch (computerChoice) {
case ROCK:
message = "You loose";
break;
case PAPER:
message = "You win";
break;
case SCISSORS:
message = "You tied computer. You both chose scissors";
break;
}
break;
}
JOptionPane.showMessageDialog(null, message);
}
} catch (Exception ex) {
JOptionPane.showInputDialog(null, "That wasn't a number!", "Error!", JOptionPane.ERROR_MESSAGE);
JOptionPane.showMessageDialog(null, "You have not entered correct number! Terminating program!");
System.exit(0);
}
}
}

Categories