Reputation: 37
Learning java obviously. I was able to make the game work fine. But I need to make it so that if the user puts something other than R/P/S then it defaults to Rock. I don't need to loop. The game works perfect if I put rock. If I put anything other than RPS it also works perfect and defaults to rock. If, however, I do Paper or Scissors, it gives me the paper and scissors answer, AND the defaults to rock answer. Any hints on why this isn't working?
Also, is my direction wrong? Could I be doing this a better way? This feels really... unelegant at best.
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
String userChoice="", userInput, compChoice="";
int ranInt = (int)(Math.random()*3);
if (ranInt == 0){
compChoice = "Rock";
} else if (ranInt == 1){
compChoice = "Paper";
}else if (ranInt == 2){
compChoice = "Scissors";
}
System.out.println("Please select one of [R/P/S]: ");
userInput = in.next();
if(userInput.equalsIgnoreCase("p")){
userChoice = "Paper ";
if(compChoice.equalsIgnoreCase("Rock")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println(userChoice + "beats "+compChoice +"- you win!");
}else if (compChoice.equalsIgnoreCase("Paper")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println("A tie!");
}else if(compChoice.equalsIgnoreCase("Scissors")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println(compChoice + " beats " + userChoice + " - i win!");
}
}
if(userInput.equalsIgnoreCase("S")){
userChoice = "Scissors ";
if(compChoice.equalsIgnoreCase("Paper")){
System.out.println("You chose: "+userChoice);
System.out.println("I choce: "+compChoice);
System.out.println(userChoice + "beats "+compChoice +"- you win!");
}else if(compChoice.equalsIgnoreCase("Scissors")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println("A tie!");
}else if(compChoice.equalsIgnoreCase("Rock")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println(compChoice + " beats " + userChoice + " - i win!");
}
}
if(userInput.equalsIgnoreCase("R")){
userChoice = "Rock ";
if(compChoice.equalsIgnoreCase("Rock")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println("A Tie!");
}else if(compChoice.equalsIgnoreCase("Paper")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println(compChoice + " beats " + userChoice + " - you lose!");
}else if(compChoice.equalsIgnoreCase("Scissors")){
System.out.println("You chose: "+userChoice);
System.out.println("I chose: "+compChoice);
System.out.println(userChoice + " beats " + compChoice + " - you win!");
}
}
else {
userChoice = "";
System.out.println("Invalid selection, defaulting to rock.");
if(compChoice.equalsIgnoreCase("Rock")){
System.out.println("You chose: Rock");
System.out.println("I chose: "+compChoice);
System.out.println("A Tie!");
}else if (compChoice.equalsIgnoreCase("Paper")){
System.out.println("You chose: Rock");
System.out.println("I chose: "+compChoice);
System.out.println(compChoice + " beats " + "Rock - you lose!");
} else if(compChoice.equalsIgnoreCase("Scissors")){
System.out.println("You chose: Rock");
System.out.println("I chose: "+compChoice);
System.out.println("Rock beats " + compChoice + " - you win!");
}
}
}
}
Upvotes: 0
Views: 766
Reputation: 6778
Your code needs to have else if
for the 'S' branch and the 'R' branch, otherwise the logic proceeds as follows (for an 'S' input):
if (P) do something // No, so move on
if (S) do something // Yes, so do 'S' stuff
if (R) do something else do something different // Not 'R', so doing something different.
For ideas on adding 'elegance' to your code, check out the Rosetta Code page for Rock, Paper, Scissors
Upvotes: 3
Reputation: 285403
You asked about "elegant" solution, and one way to do this is to use a win matrix, in other words something like so:
public enum RPS {
ROCK, PAPER, SCISSORS;
public int test(RPS otherRps) {
int[][] winMatrix = {
{ 0, -1, 1 },
{ 1, 0, -1 },
{ -1, 1, 0 } };
return winMatrix[ordinal()][otherRps.ordinal()];
}
}
Then you could test the result by simply calling the enum's test(...) method. For example:
import java.util.Random;
import java.util.Scanner;
public class RockPaperScissors {
private static Random random = new Random();
private static Scanner in = new Scanner(System.in);
public static void main(String[] args) {
RPS compChoice = RPS.values()[random.nextInt(RPS.values().length)];
RPS userChoice = getUserChoice();
String result = "";
switch (userChoice.test(compChoice)) {
case 1:
result = "you win!";
break;
case -1:
result = "you lose!";
break;
case 0:
result = "it's a tie";
default:
break;
}
System.out.printf("You chose %s, the computer chose %s, %s%n",
userChoice, compChoice, result);
}
private static RPS getUserChoice() {
System.out.print("Please select one of [R/P/S]: ");
String userChoiceStr = in.nextLine().trim();
if (userChoiceStr.isEmpty()) {
return RPS.ROCK;
}
for (RPS rps : RPS.values()) {
if (rps.toString().startsWith(userChoiceStr.toUpperCase())) {
return rps;
}
}
return RPS.ROCK; // default
}
}
Upvotes: 2
Reputation: 234795
In pseudocode, the structure of your code is:
if (paper) {
process paper
}
if (scissors) {
process scissors
}
if (rock) {
process rock
} else {
process default rock
}
Note that (since the cases are mutually exclusive) if paper
or scissors
is true, then rock
is false and the else
will execute. Just change the structure to:
if (paper) {
process paper
} else if (scissors) {
process scissors
} else if (rock) {
process rock
} else {
process default rock
}
Upvotes: 3