The Rock, Paper and Scissors Game

9 Feb
2008

The Rock, Paper and Scissors is a traditional classic game that maybe can be found in almost every part of the world including in my homeland, Bali. This classic game played by two people, they can pick either the rock, the paper or the scissors as their weapon. The rule is simple: rock wins to scissors, paper wins to rock, scissors wins to paper.

In this blog post we will create this simple game. We’ll create the Rock, Paper and Scissors object and will make them comparable to each other and they also have their own name. To make this feature we create a GameObject interface that extends the java.lang.Comparable interface, this is where it will get the ability to do the comparison. Let’s see what we got so far in our code.

The GameObject interface.

package org.kodejava.example.app;

public interface GameObject extends Comparable {
    public String getName();
}

The Rock class.

package org.kodejava.example.app;

public class Rock implements GameObject {
    private String name;

    public Rock() {
        this.name = "Rock";
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof Paper) {
            return -1;
        } else if (o instanceof Scissor) {
           return 1;
        } else if (o instanceof Rock) {
            return 0;
        }

        throw new UnsupportedOperationException();
    }
}

The Paper class.

package org.kodejava.example.app;

public class Paper implements GameObject {
    private String name;

    public Paper() {
        this.name = "Paper";
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof Scissor) {
            return -1;
        } else if (o instanceof Rock) {
            return 1;
        } else if (o instanceof Paper) {
            return 0;
        }    

        throw new UnsupportedOperationException();
    }
}

The Scissors class.

package org.kodejava.example.app;

public class Scissors implements GameObject {
    private String name;

    public Scissors() {
        this.name = "Scissors";
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof Rock) {
            return -1;
        } else if (o instanceof Paper) {
            return 1;
        } else if (o instanceof Scissor) {
            return 0;
        }

        throw new UnsupportedOperationException();
    }
}

As you can see from the code above, all classes; Rock, Paper and Scissors; are implementing the GameObject interface. This will make each class to implements the getName() and compareTo() methods.

The compareTo() method basically compare the object with the passed in object. We first check it using the instanceof operator to know if the passed object is type of Rock, Paper or Scissors. Based on the win, lose or draw rules the method return the corresponding 1, -1 or 0 value.

Now let see the main class that run our game. This class is a standard Java application class with the main(String[] args) method. The class also have a factory method; createObject(int type) method; for creating the correct GameObject from user input or a random pick by the computer player.

package org.kodejava.example.app;

import java.util.Random;
import java.util.Scanner;

public class RockPaperScissorsGame {
    public static final int ROCK     = 0;
    public static final int PAPER    = 1;
    public static final int SCISSORS = 2;

    public static void main(String[] args) {
        RockPaperScissorsGame game = new RockPaperScissorsGame();
        game.runGame();
    }

    protected void runGame() {
        System.out.println("ROCK     = 0");
        System.out.println("PAPER    = 1");
        System.out.println("SCISSORS = 2");

        Scanner scanner = new Scanner(System.in);
        int input;
        do {
            System.out.print("Pick your selection (0, 1, 2): ");
            input = scanner.nextInt();
        } while (input < 0 || input > 2);

        GameObject objectOne = createObject(input);

        //
        // Computer pick his game object.
        //
        Random random = new Random();
        int type = random.nextInt(3);
        GameObject objectTwo = createObject(type);

        System.out.println("Your pick    : " + objectOne.getName());
        System.out.println("Computer pick: " + objectTwo.getName());
        getWinner(objectOne, objectTwo);
    }

    private void getWinner(GameObject objectOne, GameObject objectTwo) {
        if (objectOne.compareTo(objectTwo) > 0) {
            System.out.println(objectOne.getName() + " vs "
                    + objectTwo.getName() + ": YOU WIN!!!");
        } else if (objectOne.compareTo(objectTwo) < 0) {
            System.out.println(objectOne.getName() + " vs "
                    + objectTwo.getName() + ": YOU LOSE!!!");
        } else if (objectOne.compareTo(objectTwo) == 0) {
            System.out.println(objectOne.getName() + " vs "
                    + objectTwo.getName() + ": DRAW!!!");
        }
    }

    private GameObject createObject(int type) {
        if (type == ROCK) {
            return new Rock();
        } if (type == PAPER) {
            return new Paper();
        } if (type == SCISSORS) {
            return new Scissors();
        }
        return null;
    }
}

We have all the code, compile it with your JDK or IDE. To play it, run the application and pick your target weapon to fight the computer player by entering the number displayed in the console, 0 for rock, 1 for paper or 2 for scissors.

2 Responses to The Rock, Paper and Scissors Game

Avatar

benno

June 3rd, 2008 at 1:29 am

Hi, I think implementing Comparable like this is not correct as it requires transitivity:

“The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.”

In this game transitivity is not given as stone is greater than scissors and scissors is greater than paper but stone is not greater than paper.

Avatar

Alberto

September 25th, 2009 at 1:12 am

Doesn’t this seem a bit overkill? It seems like it would be best to just have an enum that lists out ROCK PAPER and SCISSORS, and then just do appropriate logic from there. Yes I know Java is supposed to be OO, but is this really the best way to play such a simple game?

Comment Form

top