I'm trying to code Star Trek The Dice Game. The basic concept is you roll dice, which become different types of crew (Science, Medical, Command, Engineer, etc...) and you can "spend" crew to take actions (heal people, transport people, raise/lower shields, cause the ship to travel, repair the hull, etc...).
The game has event and development cards. Event cards are bad things (like the ship takes damage, an action can't be used, you need more crew to raise shields, etc...). Development cards are good things (hull repairs fix extra hull, raise shields for free, heal fixes two people, etc...).
My problem - I'm struggling to determine how to enforce the card's rules as they enter and leave play. My concerns are two-fold:
Not all rules are boolean. The rules engines I've run across seem to always assume boolean rules; an object meets the rule or doesn't. While some of the rules are boolean (ex: did the player provide enough crew to repair the hull), others aren't (ex: healing fixes an additional person).
One approach might be to have booleans in different objects which track the rules in play. For instance, an HealPersonAction class that tracks if costs went up, if an extra person is healed, etc... But that means the rules knowledge is distributed across the game and I'd need messages or an observer to inform every affected object as cards enter or exit play. My instinct is encapsulating rules logic within the cards is a wiser way to go, especially since it becomes easier to change the rules later by just changing the card.
Is there a recommended design to address the problem of game cards temporarily modifying game rules in various ways?