package bots.mctsbot.ai.bots.bot.gametree.tls;
import java.util.Random;
import bots.mctsbot.ai.bots.bot.gametree.action.CallAction;
import bots.mctsbot.ai.bots.bot.gametree.action.FoldAction;
import bots.mctsbot.ai.bots.bot.gametree.action.RaiseAction;
import bots.mctsbot.ai.bots.bot.gametree.action.SearchBotAction;
import bots.mctsbot.ai.bots.bot.gametree.search.expander.sampling.RelativeBetDistribution;
import bots.mctsbot.ai.opponentmodels.OpponentModel;
import bots.mctsbot.client.common.gamestate.GameState;
import bots.mctsbot.common.elements.player.PlayerId;
import bots.mctsbot.common.util.Triple;
public class Sampler {
private OpponentModel model;
static Random random = new Random();
public Sampler(OpponentModel model, PlayerId bot) {
this.model = model;
}
public SearchBotAction sample(GameState state) {
Triple<Double, Double, Double> probs = model.getFoldCallRaiseProbabilities(state, state.getNextToAct());
double rand = random.nextDouble();
if (rand < probs.getLeft())
return new FoldAction(state, state.getNextToAct());
if (rand < probs.getLeft() + probs.getMiddle())
return new CallAction(state, state.getNextToAct());
RelativeBetDistribution dist = new RelativeBetDistribution();
double sample = dist.inverseCdf(random.nextDouble());
double minBet = state.getLowerRaiseBound(state.getNextToAct());
double maxBet = state.getUpperRaiseBound(state.getNextToAct());
maxBet -= minBet;
sample *= maxBet;
sample += minBet;
return new RaiseAction(state, state.getNextToAct(), (int) Math.round(sample));
}
public SearchBotAction sample(GameState state, SearchBotAction lowBound, SearchBotAction highBound) {
Triple<Double, Double, Double> probs = model.getFoldCallRaiseProbabilities(state, state.getNextToAct());
double foldProb = probs.getLeft();
double callProb = probs.getMiddle();
double raiseProb = probs.getRight();
if (lowBound instanceof CallAction)
foldProb = 0;
if (lowBound instanceof RaiseAction) {
foldProb = 0;
callProb = 0;
}
// if (highBound instanceof FoldAction) {
// callProb = 0;
// raiseProb = 0;
// }
if (highBound instanceof CallAction) {
raiseProb = 0;
callProb = 0;
}
RelativeBetDistribution dist = new RelativeBetDistribution();
double minBet = state.getLowerRaiseBound(state.getNextToAct());
double maxBet = state.getUpperRaiseBound(state.getNextToAct());
if (highBound instanceof RaiseAction) {
raiseProb = raiseProb * (1 - (((RaiseAction) highBound).amount - minBet) / (maxBet - minBet));
}
double sum = foldProb + callProb + raiseProb;
foldProb /= sum;
callProb /= sum;
raiseProb /= sum;
double rand = random.nextDouble();
if (rand < foldProb)
return new FoldAction(state, state.getNextToAct());
if (rand < foldProb + callProb)
return new CallAction(state, state.getNextToAct());
double lowRaise = minBet;
double highRaise = maxBet;
if (lowBound instanceof RaiseAction)
lowRaise = ((RaiseAction) lowBound).amount;
if (highBound != null)
highRaise = ((RaiseAction) highBound).amount;
lowRaise -= minBet;
lowRaise /= (maxBet - minBet);
highRaise -= minBet;
highRaise /= (maxBet - minBet);
double lowSample = dist.cdf(lowRaise);
double highSample = dist.cdf(highRaise);
rand = random.nextDouble() * (highSample - lowSample) + lowSample;
double sample = dist.inverseCdf(rand);
maxBet -= minBet;
sample *= maxBet;
sample += minBet;
return new RaiseAction(state, state.getNextToAct(), (int) Math.round(sample));
}
}