Package org.cspoker.ai.bots.bot.rule

Source Code of org.cspoker.ai.bots.bot.rule.AlternatingBot

/**

* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*  You should have received a copy of the GNU General Public License
*  along with this program; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.cspoker.ai.bots.bot.rule;

import java.rmi.RemoteException;
import java.util.EnumSet;
import java.util.Random;
import java.util.concurrent.ExecutorService;

import org.apache.log4j.Logger;
import org.cspoker.ai.bots.bot.AbstractBot;
import org.cspoker.ai.bots.listener.BotListener;
import org.cspoker.client.common.SmartLobbyContext;
import org.cspoker.client.common.gamestate.GameState;
import org.cspoker.client.common.playerstate.PlayerState;
import org.cspoker.common.api.shared.exception.IllegalActionException;
import org.cspoker.common.elements.cards.Card;
import org.cspoker.common.elements.player.PlayerId;
import org.cspoker.common.elements.table.Round;
import org.cspoker.common.elements.table.TableId;
import org.cspoker.common.handeval.stevebrecher.HandEval;

public class AlternatingBot extends AbstractBot {

  private final static Logger logger = Logger.getLogger(CallBot.class);
 
  private long threshold;

  AlternatingBot(PlayerId playerId, TableId tableId, SmartLobbyContext lobby,
      int buyIn, ExecutorService executor, long threshold, BotListener... botListeners) {
    super(playerId, tableId, lobby, buyIn, executor, botListeners);
    this.threshold = threshold;
  }
 
  private boolean printed = false;
  private long nrActions = 0;
 
  @Override
  public void doNextAction() {
    nrActions++;
    if (nrActions < threshold) {
      try {
        playerContext.checkOrCall();
      } catch (IllegalActionException e) {
        logger.error(e);
        throw new IllegalStateException("Call was not allowed.", e);
      } catch (RemoteException e) {
        logger.error(e);
        throw new IllegalStateException("Call failed.", e);
      }
    } else {
      if (nrActions > threshold && !printed) {
        System.out.println("=================\nNEW BOT\n====================");
        printed = true;
      }
      GameState gameState = playerContext.getGameState();
      int deficit = gameState.getDeficit(getId());

      int nbPlayers = 0;
      for(PlayerState p: gameState.getAllSeatedPlayers()){
        if(p.isActivelyPlaying()) nbPlayers++;
      }
     
      double winPercentage = getWinPercentage(gameState
          .getCommunityCards(), playerContext.getPocketCards(),
          100, nbPlayers - 1);
      if (logger.isDebugEnabled()) {
        logger.debug("Win percentage is " + winPercentage
            + " with " + playerContext.getPocketCards()
            + " and " + gameState.getCommunityCards() + " and "
            + (nbPlayers - 1) + " opponents.");
      }
      double EV = winPercentage
      * (gameState.getGamePotSize() + deficit);
      if (gameState.getRound().equals(Round.PREFLOP)) {
        // be more aggressive on the flop
        EV += EV;
      }
      try {
        if (gameState
            .getNextActivePlayerAfter(getId()) == null) {
          // can only call or fold
          if (deficit <= Math.round(EV)) {
            playerContext.checkOrCall();
          } else {
            playerContext.fold();
          }
        } else {
          playerContext.raiseMaxBetWith((int) Math
              .round(EV * 0.5), (int) Math.round(EV));
        }
      } catch (IllegalActionException e) {
        logger.warn("Raise bounds: "
            + tableContext.getGameState().getLowerRaiseBound(
                getId())
                + " to "
                + tableContext.getGameState().getUpperRaiseBound(
                    getId()));
        logger.error(e);
        throw new IllegalStateException("Action was not allowed.",
            e);
      } catch (RemoteException e) {
        logger.error(e);
        throw new IllegalStateException("Action failed.", e);
      }
    }
  }
  // Card roll out code

  public double getWinPercentage(EnumSet<Card> fixedCommunityCards,
      EnumSet<Card> botCards, int nbSamples, int nbOpponents) {
    EnumSet<Card> usedFixedCards = EnumSet.copyOf(fixedCommunityCards);
    usedFixedCards.addAll(botCards);

    int nbFixedCards = fixedCommunityCards.size();
    int nbMissingCommunityCards = 5 - nbFixedCards;
    int nbCommunitySamples, nbOpponentSamples;
    if (nbMissingCommunityCards == 0) {
      nbCommunitySamples = 1;
      nbOpponentSamples = nbSamples;
    } else {
      double root = Math.sqrt(nbSamples);
      nbCommunitySamples = (int) (root * nbMissingCommunityCards / 2);
      nbOpponentSamples = (int) (root * 2 / nbMissingCommunityCards);
    }

    int nbWins = 0;
    for (int i = 0; i < nbCommunitySamples; i++) {
      EnumSet<Card> fixedAndCommunityCards = EnumSet
      .copyOf(usedFixedCards);
      EnumSet<Card> communityCards = EnumSet.copyOf(fixedCommunityCards);
      for (int j = 0; j < nbMissingCommunityCards; j++) {
        Card communityCard;
        do {
          communityCard = getRandomCard();
        } while (fixedAndCommunityCards.contains(communityCard));
        fixedAndCommunityCards.add(communityCard);
        communityCards.add(communityCard);
      }
      for (int j = 0; j < nbOpponentSamples; j++) {
        EnumSet<Card> fixedAndCommunityAndOpponentCards = EnumSet
        .copyOf(fixedAndCommunityCards);
        // fixedAndCommunityCards coincidentally contains the bot's
        // hand!
        int botRank = getRank(fixedAndCommunityCards);
        boolean botWins = true;
        for (int k = 0; k < nbOpponents; k++) {
          Card opponentFirst;
          do {
            opponentFirst = getRandomCard();
          } while (fixedAndCommunityAndOpponentCards
              .contains(opponentFirst));
          fixedAndCommunityAndOpponentCards.add(opponentFirst);
          Card opponentSecond;
          do {
            opponentSecond = getRandomCard();
          } while (fixedAndCommunityAndOpponentCards
              .contains(opponentSecond));
          fixedAndCommunityAndOpponentCards.add(opponentSecond);
          EnumSet<Card> particularOpponentHand = EnumSet.of(
              opponentFirst, opponentSecond);
          particularOpponentHand.addAll(communityCards);
          int opponentRank = getRank(particularOpponentHand);
          if (opponentRank >= botRank) {
            botWins = false;
          }// TODO fix for split pot
        }
        if (botWins) {
          ++nbWins;
        }
      }
    }
    return (double) nbWins / (nbOpponentSamples * nbCommunitySamples);
  }

  private int getRank(EnumSet<Card> cards) {
    return HandEval.getRank(cards);
  }

  private static Random random = new Random();
  private static Card[] cards = Card.values();

  protected static Card getRandomCard() {
    return cards[random.nextInt(cards.length)];
  }
}
TOP

Related Classes of org.cspoker.ai.bots.bot.rule.AlternatingBot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.