Skip to content

How To Simulate Cash Games

corintio edited this page Oct 18, 2013 · 2 revisions

Introduction

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.

Preparing bots to play in your simulation

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.

Defining the actual Cash-Game parameters

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)

Starting the Simulation

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 !

How to reduce variance ?

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.