Greed dice game exercise from Ruby Koans

One of the Learn Ruby Koans exercise is about implementing a method that calculate the score of the Greed dice game.

A friend reviewed my solution pointing out some conditional expressions that could be avoided (from 3 they are zero now), some state that could be removed (greed_roll_scores is calculated and never changed now), and in the way of the refactoring some duplication (2 similar rules of the games now are both applied with a unique common logic) become evident and I removed it.

Here is the resulting score method, I left also the comments with the Greed game description and the original tests:

How good is this solution?
Again my friend suggested to see how easy is to read (you judge this then) and how easy is to extend with new features.
Well a good design, is emergent, is not required to and do not predict/anticipate future features (YAGNI).
Instead when a new rule is similar to the existing ones, it should be easier/faster then before to implement.
And when a new rule is completely different, well here is where you cannot and should not even try to predict and anticipate; the more you can add new unpredictable rules just adding/extending code and without throwing away the existing code, the more the design is good.

Here there are new rules that I didn't know when I implemented the code in the first place. I can try to add to the initial implementation of the score method:

The first 4 new rules (4-of-a-kind, 5-of-a-kind and 6-of-a-kind) are similar to the existing rules (3-of-a-kind), let see how easy is to extend the implementation:
Quite well: only a small change of the existing score method implementation is needed.

The last 2 new rules (a straight and three couples) are quite different to the existing rules, let see how easy is to extend the implementation:
Quite well: only a small addition of the previous score method implementation. No evidence from here that the design is bad.

Happy to hear your comments and see others solutions

Update: a reflection suggested by Riccardo while discussing off-line is about splitting the logic of each rule in a separate method and having the score method that apply the set of rules. This way make it easier to add a new rule: just define the new rule in a method and add it to the rules collection in score method.
This is the result:

Update: a new version inspired by Matteo solution
and here the related unit tests

Print | posted @ domenica 8 gennaio 2012 02:15

Comments have been closed on this topic.