patternjavaModerate
Another Rock Paper Scissors Lizard Spock implementation
Viewed 0 times
scissorspaperspockrockanotherimplementationlizard
Problem
The Challenge
Create an implementation of "Rock - Paper - Scissors - Lizard - Spock".
The rules:
Scissors cuts paper, paper covers rock, rock crushes lizard, lizard poisons Spock, Spock smashes scissors, scissors decapitate lizard, lizard eats paper, paper disproves Spock, Spock vaporizes rock. And as it always has, rock crushes scissors. -- Dr. Sheldon Cooper
My approach
I wanted to make the game flexible and general. It should not be necessary to change much to create a "normal" Rock-Paper-Scissors implementation. It should also be possible to add elements such as Water balloon if you'd like. Technically, it should also be possible without too much effort to modify the elements at runtime (this is currently not supported in the below implementation, but there's not many changes needed to make it a reality).
Players. All players have a score that gets increased when they win. A player should have a method to return which item the player chooses, this implementation can vary (a human can write input, an AI can return something random, some other AIs should perhaps always choose SPOCK...)
Code
Because I am lazy, I have put all the classes/interfaces in the same file. Of course, all of them could be placed in their own files as
```
interface IItem {
/**
* To allow configuration "from both sides", use an int instead of a boolean.
* For example, if SCISSORS have -1 edge against ROCK, it will lose as long as ROCK doesn't have an edge below -1 against SCISSORS.
* This way, it is possible to configure both "beats" and "gets beaten by". It is also possible to return a randomized value here to allow for more complex game styles.
*/
int edge(IItem opponent);
}
abstract class ItemPlayer {
public abstract IItem chooseOne(IItem[] possibles);
private int score = 0;
public void wonAGame() {
score+
Create an implementation of "Rock - Paper - Scissors - Lizard - Spock".
The rules:
Scissors cuts paper, paper covers rock, rock crushes lizard, lizard poisons Spock, Spock smashes scissors, scissors decapitate lizard, lizard eats paper, paper disproves Spock, Spock vaporizes rock. And as it always has, rock crushes scissors. -- Dr. Sheldon Cooper
My approach
I wanted to make the game flexible and general. It should not be necessary to change much to create a "normal" Rock-Paper-Scissors implementation. It should also be possible to add elements such as Water balloon if you'd like. Technically, it should also be possible without too much effort to modify the elements at runtime (this is currently not supported in the below implementation, but there's not many changes needed to make it a reality).
Players. All players have a score that gets increased when they win. A player should have a method to return which item the player chooses, this implementation can vary (a human can write input, an AI can return something random, some other AIs should perhaps always choose SPOCK...)
Code
Because I am lazy, I have put all the classes/interfaces in the same file. Of course, all of them could be placed in their own files as
public. The code is stand-alone, just copy it and paste it to your favorite IDE (Eclipse) and run it as a JUnit test case.```
interface IItem {
/**
* To allow configuration "from both sides", use an int instead of a boolean.
* For example, if SCISSORS have -1 edge against ROCK, it will lose as long as ROCK doesn't have an edge below -1 against SCISSORS.
* This way, it is possible to configure both "beats" and "gets beaten by". It is also possible to return a randomized value here to allow for more complex game styles.
*/
int edge(IItem opponent);
}
abstract class ItemPlayer {
public abstract IItem chooseOne(IItem[] possibles);
private int score = 0;
public void wonAGame() {
score+
Solution
ItemPlayer is a really good idea. Keeping the logic and score centralized in an abstract class for the AI and Human player is a good design, but, you have not taken the idea far enough.The abstract class should have a
name field, and a constructor that takes the name:abstract class ItemPlayer {
private final String name;
ItemPlayer(String name) {
this.name = name;
}
public String getName() {
return name;
}
}Using the
toString() on the concrete classes to get the name is not a great option. Instead, for example, the AI class should be:public static class AIInput extends ItemPlayer {
AIInput() {
super("AI");
}
....
}Similarly, the
HumanInput can be changed..... but, with the Human input, I like how you've made it Closable.... but then, why didn't you use a try-with-resources structure in your main loop?Finally, I like the use of the
Enum for the valid moves (and I did something similar), but having the rules for the moves outside of the enum is cumbersome. using a static initializer block inside the enum class would solve that problem instead of having to have the setup() method callCode Snippets
abstract class ItemPlayer {
private final String name;
ItemPlayer(String name) {
this.name = name;
}
public String getName() {
return name;
}
}public static class AIInput extends ItemPlayer {
AIInput() {
super("AI");
}
....
}Context
StackExchange Code Review Q#36412, answer score: 12
Revisions (0)
No revisions yet.