Just went through a variant of the game : Rock-Paper-Scissor-Lizard-Spock
I have written a Java code for traditional R-P-S problem, but when I tried extending my code for the newer version of the game (R-P-S-L-S)..I felt my code is terribly bad. Here is a snippet :
if (player1.equals("ROCK") &&
player2.equals("SCISSORS")) {
winner = 1;
}
// Paper covers rock...
else if (player1.equals("PAPER") &&
player2.equals("ROCK")) {
winner = 1;
}
// Scissors cut paper...
else if (player1.equals("SCISSORS") &&
player2.equals("PAPER")) {
winner = 1;
}
else {
winner = 2;
}
I realized the code cant be extended easily for the newer version - as well as for more than 2 players. This is mainly because of multiple if/else or switch/cases. I need some help re-designing my code for achieving the 2 objectives :
Further modification as per R-P-C-L-S problem.
Support for more than 2 players.
I don't need code, just some guidelines should help.
Thanks !!
EDIT : Seems like I was wrong in thinking that this game can be played by more than 2 players. I am sorry for this mistake, please ignore the second requirement.
Well, in theory, the game has 3 outcomes: a win, loss, or tie. Rock defeats scissors, scissors defeats paper, and paper defeats rock. Players who play Rock-Paper-Scissors have an equal probability of winning, assuming that both players choose options completely randomly. Unfortunately, this is not the case.
In, Rock-Paper-Scissor games, it is easy to decide if move a wins against move b using their index at a cycle. So you don't have to manually decide in your code the result of every combination as other answers here suggest.
For the Rock-Paper-Scissor-Spock-Lizard version:
Let's assign a number to each move (0, 1, 2, 3, 4).
Notice that every move beats two moves:
So let d = (5 + a - b) % 5
. Then:
For the Rock-Paper-Scissor version:
let d = (3 + a - b) % 3
. Then:
Generalization For n >= 3 and n odd:
Let d = (n + a - b) % n
. Then:
The nature of Rock-Paper-Scissors is such that you have to explicitly handle the case for every possible combination of states. So the number of cases you have to cover increases exponentially with the number of players, and polynomially (with the order of the polynomial being the number of players) with the number of options.
Having said that, Java's enums are good for this kind of thing.
Here's my stab at it:
import java.util.Arrays;
import java.util.List;
enum Result {
WIN, LOSE, DRAW;
}
enum Option {
ROCK(SCISSORS),
PAPER(ROCK),
SCISSORS(PAPER);
private List<Option> beats;
private Option(Option... beats) {
this.beats = Arrays.asList(beats);
}
Result play(Option other) {
if beats.contains(other) {
return Result.WIN;
} else if other.beats.contains(this) {
return Result.LOSE;
} else {
return Result.DRAW;
}
}
}
Adding more cases (Lizard and Spock) is consequently relatively simple. Adding more players would be more complicated; among other things, you'd have to determine what the rules of three-player Rock-Paper-Scissors even are, because I have no idea.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With