-
Notifications
You must be signed in to change notification settings - Fork 6
How To Simulate Cash Games
Starting a cashgame is very easy - just run the CashGameConsoleStarter-class and after the simulation you will find a nice HandHistory-File in the ./data directory.
The following instructions will help you to customize the CashGameConsoleStarter to your own needs. As for now we don't have a distribution and GUI yet.
The testbed will run all bots written against the Meerkat-API (see http://www.poker-academy.com/community.php for details). These bots typically come in a jar file and a *.pd-file with the bot description/preferences. Some examples you can find in our project, as well as on this site http://oursland.net/projects/pabots/ for the 'ChumpBot' and 'FlockBot'.
These bots are managed in our testbed by the BotRepository-class. It scans for all bot-descriptions found in the ./data/bots directory and expects to find the bots *.class files on the classpath (so either put the source-code somewhere in the project or reference the *.jar-file).
BotRepository botRepository = new BotRepository();
If you don't want to write a *.pd-file for you new bot, you can also manually add some bots to the bot-repository, by giving them a unique name and defining their classname:
botRepository.addBot(new BotMetaData("MyBot", "mypackage.MyBotClassName", true, null));
The BotRepository just defines the available bots by the way, so put as many bots in there as you like :). ...
As our bots want to play on a table later we need to create a TableSeater-class as well.
TableSeater tableSeater = new CashGameTableSeater(botRepository, false);
You can read more about this class in a later chapter about how to reduce variance. For now this simple line will be enough.
Do define the actual Cash-Game one needs to create an instance of the CashGameDescription
CashGameDescription cashGameDescription = new CashGameDescription(); // basic paramaters cashGameDescription.setSmallBlind(0.01); cashGameDescription.setBigBlind(0.02); // players cashGameDescription.setBotNames(new String[] { "DemoBot/AlwaysCallBot", "DemoBot/AlwaysCallBot", "DemoBot/AlwaysCallBot", "DemoBot/AlwaysCallBot" }); cashGameDescription.setInGameNames(new String[] { "Cally #1", "Cally #2", "Cally #3", "Cally #4" }); // Stack-handling cashGameDescription.setInitialBankRoll(2); cashGameDescription.setNumGames(100); cashGameDescription.setNolimit(true);
This piece of code should be easy to understand. In this scenario we define a $0.01/$0.02-Cashgame with four players. These start with a bankroll of $2 for each hand (this is called 'Doyles Game'). All players stay for 100 games then leave the table.
Bots are referenced by their technical names', when bots come from a *.pd-file use the pattern "AI_NAME/BOT_NAME". In the game we can give them nice names like "Cally #1-#4" as we did above (this is optional by the way)
What is left is is two lines of code to run the simulation
GameRunner runner = cashGameDescription.createGameRunner(); runner.runGame(RandomDeck.createFactory(), tableSeater, gameIDGenerator, Arrays.asList(handHistoryWriter));
So whats to tell about it ?
- First parameter is a Factory for Decks ... use the RandomDeck as above for a start. The cards will be nicely shuffled for each game with this one.
- Second parameter - the tableSeater from above.
- Third parameter - a gameIDGenerator to give unique gameIDs ... just use the given implementation
- Last parameter - a list of GameObservers ... we just need one GameObserver for now ... one that writes the history files for us. That's it !
Poker is actually very nasty when one wants to compare bots against each other. Just by comparing the bankroll you will have a lot of variance just because some bots will have more luck with cards than others. Just run a game with four 'AlwaysCall'-Bots like above. These bots are pretty stupid - calling everything and going to showdown with each hand ... on average noone will be able to win with this strategy - but if you start a simple simulation than you will be far away from this expected result !
Anyway - we can do at least some little things against it. For instance we can shuffle the seats of each player and deal the same set of cards again. If one bot got an AA, than all the others will get it at least once too.
To enable this type of simulation, just tell the TableSeater - its second constructor argument decides about the seat permutations.
TableSeater tableSeater = new CashGameTableSeater(botRepository, true);
You can read more about the permutations in the following post http://poker-ai.org/archive/pokerai.org/pf3/viewtopic78d8.html?f=3&t=3272. Be aware that seat permutations currently only work for 2,3,4 and 6-player games.
We also need to make sure, that the player get the same cards on each permutation. A 'RandomDeck' is not enough for this task, you need to start the game with a 'SerializedDeck'
runner.runGame(SerializedDeck.createFactory("./data/decks/deck-100000.deck"), tableSeater, gameIDGenerator, Arrays.asList(handHistoryWriter));
We provide one serialized Deck in the data-directory - it contains prerecorded hole- and boardcards for 100.000 games and 10 players. You can also create your own file - just look into the class 'SerializedDeck' - it has its own main()-method and instructions in the JavaDoc.