PDA

View Full Version : Card Game Ai (Namely Hearts)



falkflyer
April 30th, 2007, 11:49 AM
Okay, so for Java class, we have to make a game, so my freind and I decided on hearts. The one thing we have to deal with is making an AI for the other three players. Anyone think they can contribute? You'd have to incorporate passing the cards left, right & across, so I guess they'd have to be rated. Yeah, well we've two months, so hopefully we'll get it done.

pingnak
April 30th, 2007, 01:14 PM
You'll learn the most from doing it yourself!

Hearts AI ain't so bad.

Step 1. LEARN THE GAME. Get together with your friends and PLAY Hearts. Play with REAL cards and pizza. Make a party of it. Enforce all the rules like a proper, pedantic rule lawyer.

After each round, chat and try to describe your 'winning' strategy. You'll only need to play hearts for a night or so to get it down well enough to understand the AI problem.

The next step is to write a game that plays Hearts RIGHT. Enforce all the rules correctly. Do all the stages and scoring of the game absolutely right.

The easiest way to write most of these turn-based board and card games is a state machine.



// This code gets invoked once per cycle, and goes to whichever state 'gameState' indicates.
switch( gameState )
{
case Initialize:
// Set up a fresh, new game
break;
case Shuffle:
// Shuffle cards, play animations and sounds
break;
case Cut:
// Allow a player to cut the deck, or just take it as writ
break;
case Deal:
// Deal the cards out, optionally animating the results
break;
case Pass:
// Do passing
break;
case Turn:
// Main game 'loop'. Change 'turn', generate list of valid moves, and prompt 'realplayer' or 'aiplayer' for actions
break;
case Finished:
// All cards used up. Tally
// Go to 'KeepPlaying' or 'GameWon' according to outcome
break;
case KeepPlaying:
// Show current scores and wait for user response
// Loop back to Deal
break;
case GameWon:
// Show final outcome and wait for response
// Loop back to Initialize
break;
}
What do the players do? The easiest way to handle both the interface for allowing a player to make a valid move, AND for AI is to iterate all of the legal moves *right now* for the current player and make a list. So, when it comes your turn, a list of cards that can be validly played legally is available. Same for board games, except a list of things that can be moved, for each, to where.

Once you have this much, you can actually make a first pass of 'retarded' (i.e. RANDOM or 'EASIEST') AI that simply picks from the list of valid rules at random. A running game with this much will be enough to earn you a 'C' grade, because it won't violate any rules, and you'll be far ahead of most of the class who won't even be able to make the game run without crashing. You should have this inside of 40 hours.

From here, you can excel. Simply write up some AI that chooses a 'strategy' at the start. If the cards look like it should 'shoot the moon', then it should go into 'shoot the moon' mode and play, unless over the course of the game, it looks like it won't be able to (someone else gets a heart, or QOS), then it should dump, dump, dump, like everybody else, trying to reduce its final score.

Better AI will keep a list of what has been played, and what tricks have been won, so as the game progresses, a shrewd guess as to what other players have in their hands can be made. If someone is collecting hearts, the AI should know enough not to give THEM the Queen of Spades, if at all possible. There are also strategies based on score. If ahead, it might be better to 'eat' a heart, or even the QOS as insurance against someone shooting the moon.

You should write several variations of the AI (AI handlers to attach to 'players'). You can then use them against each other in endless rounds of the game, keeping track of which ones win more (and also this will exercise your game code and find bugs). A mode of the game that 'auto-plays', skipping over animation with four AI players is crucial for this. You can 'test' thousands of rounds at a time. Keep several of the 'better' AI players, and rank them by how many games they win. This will give the game a little variety, and scalability for the skill of the person who's playing it.

Be sure to document all of this in your code, so the teacher can be suitably 'impressed'.

Then it's only a matter of 'tuning' and 'evolving' the AI until you're sick of it, then calling it 'done' and turning it in. About 120 hours. Don't get too wound up in perfectionism. If the AI characters are good enough to be 'challenging' they're plenty good enough.

BE SURE TO USE VERSION CONTROL. I can't stress this enough. Label versions with AI that 'looks pretty good', because you WILL make changes that you'll want to back out of, either partially or fully.

Also, pay attention to presentation. A bare-bones game that plays excellent Hearts will make a poorer first impression than a pretty one with a little animation that plays passable Hearts. Be sure and 'doll it up' only AFTER you have it playing well. If this teacher has been assigning this particular project for a while, you can assume he'll be able to beat the best any game can throw at him. He'll have lots of games to grade, will probably get somebody to help grade them, and will only really scrutinize the ones that play well, and them maybe the ones that play 'right'.

falkflyer
April 30th, 2007, 04:50 PM
Well, not everyone's doing hearts, and half the class is made up of retarded seniors that wanted an easy course (power to the sophomores! w00t!). I don't think an AI will be TOO looked at, because it's a high-school Java I course (I wish I was in A.P., but you gotta do this first). I don't think she expects much from an AI standpoint. But thanks for the great guide, looks like I've some work to do.:beer: