I am writing a computer version of the game Dominion. It is a turn-based card game where action cards, treasure cards, and victory point cards are accumulated into a player's personal deck. I have the class structure pretty well developed, and I am starting to design the game logic. I'm using python, and I may add a simple GUI with pygame later.
The turn sequence of the players is governed by a very simple state machine. Turns pass clockwise, and a player can't exit the game before it is over. The play of a single turn is also a state machine; in general, players pass through an "action phase", a "buy phase", and a "clean-up phase" (in that order). Based on the answer to the question How to implement turn-based game engine?, the state machine is a standard technique for this situation.
My problem is that during a player's action phase, she can use an action card that has side effects, either on herself, or on one or more of the other players. For example, one action card allows a player to take a second turn immediately following the conclusion of the current turn. Another action card causes all other players to discard two cards from their hands. Yet another action card does nothing for the current turn, but allows a player to draw extra cards on her next turn. To make things even more complicated, there are frequently new expansions to the game that add new cards. It seems to me that hard-coding the results of every action card into the game's state machine would be both ugly and unadaptable. The answer to Turn-based Strategy Loop does not go into a level of detail that addresses designs to solve this problem.
What kind of programming model should I use to encompass the fact that the general pattern for taking turns can be modified by actions that take place within the turn? Should the game object keep track of the effects of every action card? Or, if the cards should implement their own effects (e.g. by implementing an interface), what setup is required to give them enough power? I have thought up a few solutions to this problem, but I am wondering if there is a standard way to solve it. Specifically, I'd like to know what object/class/whatever is responsible for keeping track of the actions that every player must do as a consequence of an action card being played, and also how that relates to temporary changes in the normal sequence of the turn state machine.