/**
* 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 bots.mctsbot.ai.opponentmodels.simple;
import java.util.concurrent.ConcurrentHashMap;
import net.jcip.annotations.NotThreadSafe;
import bots.mctsbot.ai.bots.bot.gametree.mcts.nodes.INode;
import bots.mctsbot.ai.opponentmodels.OpponentModel;
import bots.mctsbot.client.common.gamestate.DetailedHoldemTableState;
import bots.mctsbot.client.common.gamestate.GameState;
import bots.mctsbot.client.common.gamestate.GameStateVisitor;
import bots.mctsbot.client.common.gamestate.modifiers.AllInState;
import bots.mctsbot.client.common.gamestate.modifiers.BetState;
import bots.mctsbot.client.common.gamestate.modifiers.BlindState;
import bots.mctsbot.client.common.gamestate.modifiers.CallState;
import bots.mctsbot.client.common.gamestate.modifiers.CheckState;
import bots.mctsbot.client.common.gamestate.modifiers.ConfigChangeState;
import bots.mctsbot.client.common.gamestate.modifiers.FoldState;
import bots.mctsbot.client.common.gamestate.modifiers.JoinTableState;
import bots.mctsbot.client.common.gamestate.modifiers.LeaveTableState;
import bots.mctsbot.client.common.gamestate.modifiers.NewCommunityCardsState;
import bots.mctsbot.client.common.gamestate.modifiers.NewDealState;
import bots.mctsbot.client.common.gamestate.modifiers.NewPocketCardsState;
import bots.mctsbot.client.common.gamestate.modifiers.NewRoundState;
import bots.mctsbot.client.common.gamestate.modifiers.NextPlayerState;
import bots.mctsbot.client.common.gamestate.modifiers.RaiseState;
import bots.mctsbot.client.common.gamestate.modifiers.ShowHandState;
import bots.mctsbot.client.common.gamestate.modifiers.SitInState;
import bots.mctsbot.client.common.gamestate.modifiers.SitOutState;
import bots.mctsbot.client.common.gamestate.modifiers.WinnerState;
import bots.mctsbot.common.elements.player.PlayerId;
import bots.mctsbot.common.elements.table.Round;
import bots.mctsbot.common.util.Pair;
import bots.mctsbot.common.util.Triple;
@NotThreadSafe
public class HistogramModel implements OpponentModel, GameStateVisitor {
private final ConcurrentHashMap<Pair<PlayerId, Round>, PlayerRoundHistogram> opponentModels = new ConcurrentHashMap<Pair<PlayerId, Round>, PlayerRoundHistogram>();
private volatile GameState lastKnownState = null;
private volatile Round round;
private volatile boolean started = false;
@Override
public Pair<Double, Double> getCheckBetProbabilities(GameState gameState, PlayerId actor) {
return getModelFor(actor, gameState.getRound()).getCheckBetProbabilities(gameState, actor);
}
@Override
public Triple<Double, Double, Double> getFoldCallRaiseProbabilities(GameState gameState, PlayerId actor) {
return getModelFor(actor, gameState.getRound()).getFoldCallRaiseProbabilities(gameState, actor);
}
@Override
public double[] getShowdownProbabilities(GameState gameState, PlayerId actor) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public PlayerRoundHistogram getModelFor(PlayerId opponentId, Round round) {
Pair<PlayerId, Round> key = new Pair<PlayerId, Round>(opponentId, round);
if (!opponentModels.containsKey(key)) {
throw new IllegalStateException("Can't find model for " + key);
}
return opponentModels.get(key);
}
private void initiateModelsFor(PlayerId player) {
// check
// bet
// fold
// call
// raise
opponentModels.put(new Pair<PlayerId, Round>(player, Round.PREFLOP), new PlayerRoundHistogram(10, 1, 11,
(int) Math.round(37556539.0 / 53203232.0 * 10), (int) Math.round(7410418.0 / 53203232.0 * 10), (int) Math.round(8236275.0 / 53203232.0 * 10),
(int) (Math.round(37556539.0 / 53203232.0 * 10) + Math.round(7410418.0 / 53203232.0 * 10) + Math.round(8236275.0 / 53203232.0 * 10))));
opponentModels.put(new Pair<PlayerId, Round>(player, Round.FLOP), new PlayerRoundHistogram((int) Math.round(5643188.0 / 9067525.0 * 10), (int) Math
.round(3424337.0 / 9067525.0 * 10), (int) (Math.round(5643188.0 / 9067525.0 * 10) + Math.round(3424337.0 / 9067525.0 * 10)), (int) Math
.round(3012394.0 / 5085650.0 * 10), (int) Math.round(1493533.0 / 5085650.0 * 10), (int) Math.round(579723.0 / 5085650.0 * 10), (int) (Math
.round(3012394.0 / 5085650.0 * 10)
+ Math.round(1493533.0 / 5085650.0 * 10) + Math.round(579723.0 / 5085650.0 * 10))));
opponentModels.put(new Pair<PlayerId, Round>(player, Round.TURN), new PlayerRoundHistogram((int) Math.round(2969602.0 / 4635236.0 * 10), (int) Math
.round(1665634.0 / 4635236.0 * 10), (int) (Math.round(2969602.0 / 4635236.0 * 10) + Math.round(1665634.0 / 4635236.0 * 10)), (int) Math
.round(1152214.0 / 2172745.0 * 10), (int) Math.round(814117.0 / 2172745.0 * 10), (int) Math.round(206414.0 / 2172745.0 * 10), (int) (Math
.round(1152214.0 / 2172745.0 * 10)
+ Math.round(814117.0 / 2172745.0 * 10) + Math.round(206414.0 / 2172745.0 * 10))));
opponentModels.put(new Pair<PlayerId, Round>(player, Round.FINAL), new PlayerRoundHistogram((int) Math.round(1863381.0 / 2843076.0 * 10), (int) Math
.round(979695.0 / 2843076.0 * 10), (int) (Math.round(1863381.0 / 2843076.0 * 10) + Math.round(979695.0 / 2843076.0 * 10)), (int) Math
.round(653301.0 / 1150533.0 * 10), (int) Math.round(407975.0 / 1150533.0 * 10), (int) Math.round(89257.0 / 1150533.0 * 10), (int) (Math
.round(653301.0 / 1150533.0 * 10)
+ Math.round(407975.0 / 1150533.0 * 10) + Math.round(89257.0 / 1150533.0 * 10))));
}
private void forgetModelsFor(PlayerId player) {
opponentModels.remove(new Pair<PlayerId, Round>(player, Round.FINAL));
opponentModels.remove(new Pair<PlayerId, Round>(player, Round.FLOP));
opponentModels.remove(new Pair<PlayerId, Round>(player, Round.PREFLOP));
opponentModels.remove(new Pair<PlayerId, Round>(player, Round.TURN));
}
@Override
public void assumePermanently(GameState gameState) {
gameState.acceptHistoryVisitor(this, lastKnownState);
lastKnownState = gameState;
}
@Override
public OpponentModel clone() {
HistogramModel hist = new HistogramModel();
hist.opponentModels.putAll(this.opponentModels);
hist.lastKnownState = this.lastKnownState;
hist.round = this.round;
hist.started = this.started;
return hist;
}
@Override
public void visitAllInState(AllInState allInState) {
if (started) {
getModelFor(allInState.getEvent().getPlayerId(), round).addAllIn(allInState, allInState.getEvent());
}
}
@Override
public void visitBetState(BetState betState) {
if (started) {
getModelFor(betState.getEvent().getPlayerId(), round).addBet(betState, betState.getEvent());
}
}
@Override
public void visitCallState(CallState callState) {
if (started) {
getModelFor(callState.getEvent().getPlayerId(), round).addCall(callState, callState.getEvent());
}
}
@Override
public void visitCheckState(CheckState checkState) {
if (started) {
getModelFor(checkState.getEvent().getPlayerId(), round).addCheck(checkState, checkState.getEvent());
}
}
@Override
public void visitFoldState(FoldState foldState) {
if (started) {
getModelFor(foldState.getEvent().getPlayerId(), round).addFold(foldState, foldState.getEvent());
}
}
@Override
public void visitInitialGameState(DetailedHoldemTableState initialGameState) {
}
@Override
public void visitJoinTableState(JoinTableState joinTableState) {
initiateModelsFor(joinTableState.getLastEvent().getPlayerId());
}
@Override
public void visitLeaveTableState(LeaveTableState leaveTableState) {
forgetModelsFor(leaveTableState.getLastEvent().getPlayerId());
}
@Override
public void visitNewCommunityCardsState(NewCommunityCardsState newCommunityCardsState) {
}
@Override
public void visitNewDealState(NewDealState newDealState) {
if (!started) {
started = true;
for (PlayerId player : newDealState.getAllSeatedPlayerIds()) {
initiateModelsFor(player);
}
}
}
@Override
public void visitNewPocketCardsState(NewPocketCardsState newPocketCardsState) {
}
@Override
public void visitNewRoundState(NewRoundState newRoundState) {
round = newRoundState.getRound();
}
@Override
public void visitNextPlayerState(NextPlayerState nextPlayerState) {
}
@Override
public void visitRaiseState(RaiseState raiseState) {
}
@Override
public void visitShowHandState(ShowHandState showHandState) {
}
@Override
public void visitSitInState(SitInState sitInState) {
initiateModelsFor(sitInState.getEvent().getPlayer().getId());
}
@Override
public void visitSitOutState(SitOutState sitOutState) {
}
@Override
public void visitBlindState(BlindState blindState) {
}
@Override
public void visitWinnerState(WinnerState winnerState) {
}
@Override
public void assumeTemporarily(GameState gameState) {
}
@Override
public void forgetLastAssumption() {
}
@Override
public void visitConfigChangeState(ConfigChangeState configChangeState) {
}
@Override
public void setChosenNode(INode node) {
}
@Override
public INode getChosenNode() {
return null;
}
@Override
public PlayerId getBotId() {
return null;
}
}