I've been tinkering around trying to make an AI player for the popular card game, Dominion (http://www.boardgamegeek.com/boardgame/36218/dominion).

If you are not familiar with the game, it is basically a very streamlined cousin of Magic: The Gathering, where there is a large-ish library of cards with different rules on them. Over the course of a game, players buy these cards and incorporate them into their deck.

I am interested in this game from a machine learning perspective - I want to pit bots against each other, have them play millions of games, and try to datamine insights that will make them play better.

I am unsure how to separate the rules of the game (the verbatim instructions printed on each card) from the core AI decision-making logic.

The obvious path that I have started down is creating a class for each Card, and putting both rules and AI stuff in the same place. This is sort of gross - but it seems like the path of least resistance. But maybe it is best for each card to support some sort of interface and then have AI components code against these?

Is there a "Correct" OOP design for this? Or several reasonable possibilities?
['https://Stackoverflow.com/questions/4261219', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/409020/']
I would lean toward encapsulating the behaviour of a card as its own class, allowing easily for cards that have multiple behaviours (i.e. choices). It would also allow you to write parameterizable behaviours and mix and match them with cards.

So cards would contain things like the cost of the card, when it can be played, its name, etc. It would also contain a list of behaviours that the card can do.

The behaviours are seen by the AI actors as part of the cards. Just another property the cards have that can be weighed along with the cost.

The AI actor that is actually *using* the card's behaviour needs to be able to interpret the behaviours, so the behaviour class might need to contain some hints for the AI to understand it, but no actual AI logic itself should be contained there. If AIs need specific behaviours for specific cards, write that kind of thing into the AI actor, not the card behaviour.

If an AI actor needs to know that, for example, this behaviour has an expected victory point payoff of .2 points/round, that might be a part of the behaviour that acts as a hint to the AI when choosing what cards to buy/play.

But really I don't know how you're approaching your AI actor design so maybe this doesn't make sense. But I think that thinking of behaviour as a property of cards rather than a fundamental part of the cards themselves might help.

It gives you the advantage of encapsulating the AI actors' default actions (things the actors can do without needing cards) as behaviours as well, so you can weigh those actions against card actions without any special-case code.
I've been thinking about the logic for a non-AI version of Dominion, and it's still a mess to figure out.

You almost have to have a class for each card deck and an interface for each card type, keeping in mind that cards may have multiple types (such as Great Hall which is both Action and Victory).

At present, all Attack cards are also Actions, so you may want to make the Attack interface subclass action. For most cards, the Action would just call the Attack method. However, there are a few cards where this would need to be different, such as for Minion where you have a choice whether or not to attack.

Reaction cards are also Actions, but will also need special handling, as they can be revealed during an opponent's turn in response to an Attack card. As of Prosperity, they can also be revealed in response to things other than attacks... Watchtower can be revealed any time you would gain a card.

Duration cards (which I missed in my list of 7 card types earlier) are Actions that stay in play for an extra turn... and also count for the Peddler's buy cost in Prosperity.

Edit: Whoops, I didn't address the AI issue at all here... probably because my own development had been aimed more at a multiplayer network version.