I’m working on a small webapp in Rails that simulates a score card for the board game Agricola.
The question is: What/How is the best (read: proper) way to model the score card in Rails?
Currently, I have a ScoreCard model which columns are the ‘categories’ that counts toward the final score. It’s something like:
class ScoreCard < ActiveRecord::Base
validates :field_tile,
:pasture,
:grain,
:vegetable,
:sheep,
:wild_boar,
:cattle,
:unused_space,
:fenced_stable,
:clay_room,
:stone_room,
:family_member,
:victory_point,
:bonus_point,
:numericality => true
end
The scoring mechanism is described in this game manual (see the ‘Scoring’ section on page 8). Here’s a snippet from the manual:
Fields: All field tiles that are on
the player’s farmyard are scored,
regardless of whether they are
currently fallow or are sown. A player
with 0 or 1 fields loses 1 point. Each
field after the first scores 1 point,
up to a maximum of 4 points for 5 or
more fields. Players score -1/1/2/3/4
points for 0-1/2/3/4/5+ fields.Pastures: Points are awarded for
fenced areas (“Pastures”), not for the
number of farmyard spaces that are
fenced in (“Pasture spaces”). The size
of the individual pastures is
irrelevant. A player with no pastures
loses 1 point. Each pasture scores 1
point, up to a maximum of 4 points for
4 or more pastures. Players score
-1/1/2/3/4 points for 0/1/2/3/4+ pastures.
Since each ‘category’ (pasture, grain, etc) has different scoring mechanism, I defined some private methods that returns the final score of each ‘category’:
private
def calculate_field_tiles_score
case field_tile
when 0..1 then -1
when 2..4 then field_tile - 1
else 4
end
end
def calculate_pasture_score
# return proper score
end
I also have a (public) calculate method in the model which calculates the final score:
def calculate
calculate_field_tiles_score +
calculate_pasture_score +
# ... other scores
end
Is this a good approach? I’m not sure what the proper way of modelling it, but it doesn’t ‘feel right’.
I’d go for something along the lines of:
and so on. Then when I want to score a farmyard, I’d do:
This way you’re modelling each category as its own class, and it’s easy to add rules which depend on any combination of state in the farmyard.