HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaModerate

Switch statements in Rock-Paper-Scissors game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scissorspaperstatementsgamerockswitch

Problem

I am very much new to design pattern. I'm trying to modify the Rock, paper, scissor game from an example book where I try to add more various design pattern. But I am encountering two similar switch statement which I think have duplicates and I don't have any idea on removing those duplicates.

A abstract class:

abstract class UserVsComp {
    protected static Item item;
    abstract protected Item getItem() throws WrongMove;
}


Here are the two switch statement:(First Class is for user movement)

class UserMove extends UserVsComp {
    private String move;
    public UserMove(String move) { this.move = move; }
    public Item getItem() throws WrongMove {
        switch (choiceValue(this.move)) {
            case 0 :  item = new Paper(); break;
            case 1 :  item = new Scissors(); break;
            case 2 :  item = new Rock(); break;
            default:  throw new WrongMove("Wrong move. Game end");
        }
    return item;
}


Second class is for Computer movement:

class ItemGenerator extends UserVsComp {
    public Item getItem() throws WrongMove {
        switch((int) (Math.random() * 2)) {
            case 0: item = new Paper(); break;
            case 1: item = new Scissors(); break;
            case 2: item = new Rock(); break;
            default:  throw new WrongMove("Wrong move. Game end");
        }
    return item;
    }
}


The two switch statement have same case (I guess duplicacy). I'd like to know if there is any way to remove this duplicacy.

Solution

Instead of creating a new Item each time you can just use a enum:

public enum Move{
    Paper{ 
        public boolean canBeat(Move other){
            return other==Rock;
        }
    },
    Scissor{ 
        public boolean canBeat(Move other){
            return other==Paper;
        }
    },
    Rock{ 
        public boolean canBeat(Move other){
            return other==Scissor;
        }
    };

    public abstract boolean canBeat(Move other);

    public boolean losesTo(Move other){
        return other.canBeat(this);
    }
}


Then You can keep them in an array (like what is returned by Move.values()) and index into that.

public Item getItem() throws WrongMove {
    int choice = choiceValue(this.move);
    if(choice= Move.values().length)
        throw new WrongMove("Wrong move. Game end");
    else return  Move.values()[choice];
}

Code Snippets

public enum Move{
    Paper{ 
        public boolean canBeat(Move other){
            return other==Rock;
        }
    },
    Scissor{ 
        public boolean canBeat(Move other){
            return other==Paper;
        }
    },
    Rock{ 
        public boolean canBeat(Move other){
            return other==Scissor;
        }
    };

    public abstract boolean canBeat(Move other);


    public boolean losesTo(Move other){
        return other.canBeat(this);
    }
}
public Item getItem() throws WrongMove {
    int choice = choiceValue(this.move);
    if(choice<0||choice >= Move.values().length)
        throw new WrongMove("Wrong move. Game end");
    else return  Move.values()[choice];
}

Context

StackExchange Code Review Q#79455, answer score: 12

Revisions (0)

No revisions yet.