Skip to content

Instantly share code, notes, and snippets.

@ssaurel
Created August 1, 2018 11:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssaurel/fdaa4bb8a09235651549a5f8300a3b38 to your computer and use it in GitHub Desktop.
Save ssaurel/fdaa4bb8a09235651549a5f8300a3b38 to your computer and use it in GitHub Desktop.
Rock Paper Scissors Lizard Spock Game in Java on the SSaurel's Channel
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class RockPaperScissorsLizardSpock {
public enum Item {
ROCK, PAPER, SCISSORS, LIZARD, SPOCK;
public List<Item> losesTo;
public boolean losesTo(Item other) {
return losesTo.contains(other);
}
static {
SCISSORS.losesTo = Arrays.asList(ROCK, SPOCK);
ROCK.losesTo = Arrays.asList(PAPER, SPOCK);
PAPER.losesTo = Arrays.asList(SCISSORS, LIZARD);
SPOCK.losesTo = Arrays.asList(PAPER, LIZARD);
LIZARD.losesTo = Arrays.asList(SCISSORS, ROCK);
}
}
private static DecimalFormat DECIMAL_FORMATTER = new DecimalFormat(".##");
public static final Random RANDOM = new Random();
// stats for the game (you win / tie / computer win)
private int[] stats = new int[] {0, 0, 0};
// we use a Markov Chain for the AI of our computer
private int[][] markovChain; // used just for the prev to current throws prediction
private int nbThrows = 0;
private Item last = null;
private void init() {
int length = Item.values().length;
markovChain = new int[length][length];
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
markovChain[i][j] = 0;
}
}
}
private void updateMarkovChain(Item prev, Item next) {
markovChain[prev.ordinal()][next.ordinal()]++;
}
private Item nextMove(Item prev) {
if (nbThrows < 1) {
// first move => we can't use Markov Chain prediction
// so we use a random on the Item list
return Item.values()[RANDOM.nextInt(Item.values().length)];
}
// we try to predict next Item choosen by the user by reading data in our Markov Chain
// for the prev entry in the array
int nextIndex = 0;
for (int i = 0; i < Item.values().length; i++) {
int prevIndex = prev.ordinal();
if (markovChain[prevIndex][i] > markovChain[prevIndex][nextIndex]) {
nextIndex = i;
}
}
// Item probably played by the user is in nextIndex
Item predictedNext = Item.values()[nextIndex];
// we choose amongst item for which this probably item loses
List<Item> losesTo = predictedNext.losesTo;
return losesTo.get(RANDOM.nextInt(losesTo.size()));
}
public void play() {
init();
Scanner in = new Scanner(System.in);
System.out.print("Make your choice : ");
while (in.hasNextLine()) {
String input = in.nextLine();
if ("STOP".equals(input))
break;
// read user choise
Item choice;
try {
choice = Item.valueOf(input.toUpperCase());
} catch (Exception e) {
System.out.println("Invalid choice");
continue;
}
Item aiChoice = nextMove(last);
nbThrows++;
// update Markov Chain
if (last != null) {
updateMarkovChain(last, choice);
}
last = choice;
System.out.println("Computer choice : " + aiChoice);
if (aiChoice.equals(choice)) {
System.out.println(" ==> Tie !\n");
stats[1]++;
} else if(aiChoice.losesTo(choice)) {
System.out.println(" ==> You win !\n");
stats[0]++;
} else {
System.out.println(" ==> You lose !\n");
stats[2]++;
}
System.out.print("Make your choice : ");
}
in.close();
// display Stats
System.out.println("\n");
System.out.println("Win Stats");
int total = stats[0] + stats[1] + stats[2];
System.out.println("You : " + stats[0] + " - " +
DECIMAL_FORMATTER.format(stats[0] / (float) total * 100f) + "%");
System.out.println("Tie : " + stats[1] + " - " +
DECIMAL_FORMATTER.format(stats[1] / (float) total * 100f) + "%");
System.out.println("Computer : " + stats[2] + " - " +
DECIMAL_FORMATTER.format(stats[2] / (float) total * 100f) + "%");
}
public static void main(String[] args) {
RockPaperScissorsLizardSpock rpsls = new RockPaperScissorsLizardSpock();
rpsls.play();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment