package bots.mctsbot.ai.bots.bot.gametree.tls.strategies.selection; import bots.mctsbot.ai.bots.bot.gametree.tls.nodes.AbstractTLSNode; import bots.mctsbot.client.common.gamestate.GameState; import bots.mctsbot.client.common.playerstate.PlayerState; import bots.mctsbot.common.elements.player.PlayerId; public class WeightedUCTSelector extends SelectionStrategy { private final double C; public WeightedUCTSelector(double C) { this.C = C; } @Override public AbstractTLSNode select(AbstractTLSNode node) { AbstractTLSNode leftChild = node.getLeftChild(); double leftValue = evaluate(leftChild); AbstractTLSNode rightChild = node.getRightChild(); if (rightChild == null) return leftChild; if (evaluate(rightChild) >= leftValue) return rightChild; return leftChild; } protected double evaluate(AbstractTLSNode node) { int nbSamples = node.getNbSamples(); if (nbSamples == 0) return 0; int nbParentSamples = node.getParent().getNbSamples(); return node.getEV() + getC2(node) * Math.sqrt(Math.log(nbParentSamples) / nbSamples); } // C2 = C * (maxProfit - maxLoss) maxLoss is negative private double getC2(AbstractTLSNode node) { GameState gameState = node.getGameState(); PlayerId bot = node.getBot(); //wrong assumption if bot is already all-in and doesn't match opponents bets int maxProfit = gameState.getGamePotSize(); int botStack = gameState.getPlayer(bot).getStack(); int maxOpponentStack = 0; for (PlayerState playerState : gameState.getAllSeatedPlayers()) { if (playerState.getPlayerId() != bot && !playerState.hasFolded()) { int stack = playerState.getStack(); // from each player you can win nothing more than the minimum of his stack and yours maxProfit += Math.min(botStack, stack); maxOpponentStack = Math.max(maxOpponentStack, stack); } } int maxLoss = Math.min(botStack, maxOpponentStack); //we add up because we took the maxLoss positive here return C * (maxProfit + maxLoss); } }