user3059540
user3059540

Reputation: 17

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

Upvotes: 0

Views: 163

Answers (9)

bary
bary

Reputation: 1739

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

Upvotes: 0

Peter Lawrey
Peter Lawrey

Reputation: 533720

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

Upvotes: 5

Dennington-bear
Dennington-bear

Reputation: 1782

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.

Upvotes: 0

grexter89
grexter89

Reputation: 1102

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;

Upvotes: 2

Elliott Frisch
Elliott Frisch

Reputation: 201497

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

Upvotes: 0

Sikorski
Sikorski

Reputation: 2691

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.

Upvotes: 0

Tim B
Tim B

Reputation: 41208

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.

Upvotes: 0

Evgeniy Dorofeev
Evgeniy Dorofeev

Reputation: 136062

You can use more efficient char comparison

char cc = compChoice.charAt(0);
char pc = playChoice.charAt(0);

if (cc == 'S' && pc == 's') {
   ...
} else if (
   ...

Upvotes: 0

SpringLearner
SpringLearner

Reputation: 13854

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

Upvotes: 1

Related Questions