package game.cash; import bots.BotRepository; import game.AbstractGameDescription; import game.PublicGameInfo; import game.TableSeater; /** * This class creates permutations of the seats to reduce variance in the simulations. */ public class CashGameTableSeater extends TableSeater { /** * if seats should be permuted. Currently only works for 2,3,4 and 6 seats * to be unbiased. */ private boolean permuteSeats; /** * @param botRepository * @param permuteSeats only works for even seat-counts */ public CashGameTableSeater(BotRepository botRepository, boolean permuteSeats) { super(botRepository); this.permuteSeats = permuteSeats; } @Override public PublicGameInfo[] createTables(AbstractGameDescription gameDescription) { int[][] seatPermutations = createSeatPermutations(gameDescription); PublicGameInfo[] createdGameInfos = new PublicGameInfo[seatPermutations.length]; for (int gamePermutation = 0; gamePermutation < seatPermutations.length; gamePermutation++) { PublicGameInfo publicGameInfo = new PublicGameInfo(); createdGameInfos[gamePermutation] = publicGameInfo; publicGameInfo.setNumSeats(gameDescription.getNumSeats()); for (int seat = 0; seat < gameDescription.getNumSeats(); seat++) { if (gameDescription.getBotNames()[seat] != null) { int targetBot = seatPermutations[gamePermutation][seat]; seatPlayer(gameDescription, publicGameInfo, seat, targetBot); } } } return createdGameInfos; } private int[][] createSeatPermutations(AbstractGameDescription gameDescription) { int numSeats = gameDescription.getBotNames().length; if (!permuteSeats) { int[][] seatPermutations = new int[1][numSeats]; for (int seat = 0; seat < numSeats; seat++) { seatPermutations[0][seat] = seat; } return seatPermutations; } // now for all the permutations if (numSeats == 2) { return new int[][]{{0, 1}, {1, 0}}; } if (numSeats == 3) { return new int[][]{{0, 1, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}, {0, 2, 1}, {1, 0, 2}}; } // if (numSeats == 4) { // return new int[][] { { 0, 1, 2, 3 }, { 1, 3, 0, 2 }, { 2, 0, 3, 1 }, { 3, 2, 1, 0 }, { 1, 2, 3, 0 }, { 3, 0, 2, 1 }, { 0, 3, 1, 2 }, // { 2, 1, 0, 3 }, { 2, 3, 0, 1 }, { 0, 2, 1, 3 }, { 3, 1, 2, 0 }, { 1, 0, 3, 2 }, { 3, 0, 1, 2 }, { 2, 1, 3, 0 }, { 1, 2, 0, 3 }, // { 0, 3, 2, 1 } }; // } // if (numSeats == 4) { // return new int[][] { { 0, 1, 2, 3 }, { 1, 3, 0, 2 }, { 2, 0, 3, 1 }, { 3, 2, 1, 0 }, // { 0, 3, 1, 2 }, { 3, 2, 0, 1 }, { 1, 0, 2, 3 }, { 2, 1, 3, 0 }, // { 0, 2, 3, 1 }, { 2, 1, 0, 3 }, { 3, 0, 1, 2 }, { 1, 3, 2, 0 } }; // } if (numSeats == 4 || numSeats == 6) { // would work for 10 seats as well, but currently we support only up to // 9 seats // see http://pokerai.org/pf3/viewtopic.php?f=3&t=3272 for algorithm int permutationCount = permuteSeats ? numSeats : 1; int[][] seatPermutations = new int[permutationCount][numSeats]; for (int permutation = 0; permutation < permutationCount; permutation++) { for (int seat = 0; seat < numSeats; seat++) { seatPermutations[permutation][seat] = ((permutation + 1) * (seat + 1) % (numSeats + 1)) - 1; } } return seatPermutations; } throw new IllegalArgumentException("permutation currently only works with 2,3,4 or 6 seats"); } }