Readability

8th Light Apprenticeship - Day 43

This morning I took a look over Rock Paper Scissors game I wrote yesterday. I want my code to be really readable and looking at the method that has the crux of the business logic in, I still was not 100% satisfied.

public boolean strongerThan(Gesture gesture) {
    if (gesture == PAPER && id == 1) {
        return false;
    }
    if (gesture == SCISSORS && id == 2) {
        return false;
    }

    if (gesture == ROCK && id == 3) {
        return false;
    }

    return true;
}

I wasn’t too keen on the magic numbers, so inlined the constants.

 public boolean strongerThan(Gesture gesture) {
    if (gesture == PAPER && id == ROCK.id) {
        return false;
    }
    if (gesture == SCISSORS && id == PAPER.id) {
        return false;
    }

    if (gesture == ROCK && id == SCISSORS.id) {
        return false;
    }

    return true;
}

I felt this was a little more readable, but the fact I had repeated if blocks made the code look slightly less professional than I wanted.

I also felt it wasn’t clear why one gesture was stronger than the other. I re-read the requirements again. The requirement just used language such as ‘Rock beats scissors’, and actually didn’t give any reasons why. However from my childhood I could remember the reasons. They are:

Rock beats scissors because rocks blunt scissors

Paper beats rock because paper wraps rock

Scissors beats paper because scissors cut paper.

I managed to work this into my method through refactoring - namely extracting out methods for each gesture. Now the method shows the context as to why one gesture is strong than another.

  public boolean strongerThan(Gesture gesture) {
    return !paperWrapsRock(gesture)
            && !scissorsCutPaper(gesture)
            && !rockBluntsScissors(gesture);
}

I also think this will lend itself better if Spock and Lizard are introduced. They can have their own methods with their own rules in.