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.
there are several "correct" OOP designs for this, depending on *how you want to model the game process and the game-playing-agent's AI*

personally, i would take the minimum number of cards for a valid *round* in the game and implement those as instances of a Card class, and implement the players as instances of an Agent class, and implement a few simple playing strategies as instances of a Strategy (pattern) class, and then *see what happens*

run through some tests, have a totally random player as a foil, look at short-term gain/loss max/min operators, try mutating the agent's strategies using a genetic algorithm, download an XCS classifier and see if it is useful to derive strategies...

...the notion of a correct model depends strongly on how it will be used. Once you understand how you need to use the elements of the game and model/manipulate the player strategies/tactics, then you'll know what the 'correct' structure is for your solution