Although its no puzzle game, I set up something similiar called WinRule for my game.
It's an interface with different implementations, very simple.
The main method isFulfilled() is called every once a while from the game loop:
boolean isFulfilled(List<Actor> actors, List<Actor> players, Set<Actor> winners);
There is one additional abstract class which got shared code for finding the winners, used by two rules.
Variations are so far: Infinity, Timespan, Highscore, Last-Man, Escape
just an addition thats the strategy pattern http://en.wikipedia.org/wiki/Strategy_pattern
imho there are not much real world usecases for inheritance and the main reason to use inheritance is polymorphism . To avoid
dublicate code use composition. (http://en.wikipedia.org/wiki/Composition_over_inheritance
But keep in mind there is no perfect code. If you can make the game you want dont worry about the "perfect" design or you will end up over-engineering the game instead of finishing it.