public PlayerTask getBestMove(SabberStoneCoreAi.POGame.POGame poGame, List <PlayerTask> options) { LinkedList <PlayerTask> minionAttacks = new LinkedList <PlayerTask>(); foreach (PlayerTask task in options) { if (task.PlayerTaskType == PlayerTaskType.MINION_ATTACK && task.Target == poGame.CurrentOpponent.Hero) { minionAttacks.AddLast(task); } } if (minionAttacks.Count > 0) { return(minionAttacks.First.Value); } PlayerTask summonMinion = null; foreach (PlayerTask task in options) { if (task.PlayerTaskType == PlayerTaskType.PLAY_CARD) { summonMinion = task; } } if (summonMinion != null) { return(summonMinion); } else { return(options[0]); } }
/* * When presented with multiple Cards to pick from, choose the one with * the highest mana and rarity combined */ private PlayerTask ChooseCard(SabberStoneCoreAi.POGame.POGame poGame) { foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { if (task.PlayerTaskType == PlayerTaskType.CHOOSE) { int value = 0; int bestChoice = 0; foreach (int entityID in task.Controller.Choice.Choices) { IPlayable card = task.Game.IdEntityDic[entityID]; int newValue = card.Card.Cost + (int)card.Card.Rarity; if (value < newValue) { bestChoice++; value = newValue; } } return(poGame.CurrentPlayer.Options() [bestChoice]); } } return(null); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { int rndSeed = 0; long startOptionMillisecond = DateTimeOffset.Now.ToUnixTimeMilliseconds(); if (startTurnMillsecond == 0) { startTurnMillsecond = DateTimeOffset.Now.ToUnixTimeMilliseconds(); } MCSimulator simulator = new MCSimulator(poGame, rndSeed, Rnd); PlayerTask bestOption = null; try { bestOption = simulator.Simulate(startOptionMillisecond, startTurnMillsecond); } catch (Exception e) { bestOption = getBestMove(poGame); } if (bestOption.PlayerTaskType == PlayerTaskType.END_TURN) { startTurnMillsecond = 0; } return(bestOption); }
public UCTSimulator(SabberStoneCoreAi.POGame.POGame poGame, int randomSeed, Random rnd, double ucb1Coef, int mcSearchDepth, int mcOpSearchDepth, int maxOpOnePlayOutTimes, int maxOnePlayOutTimes, int[,] BoardCoef, int[] MinionsCoef, int[] OpMinionsCoef) { this.root = Root(poGame); this.rndSeed = randomSeed; if (rnd != null) { this.rnd = rnd; } else { this.rnd = new Random(this.rndSeed); } this.ucb1Coef = ucb1Coef; this.mcSearchDepth = mcSearchDepth; this.mcOpSearchDepth = mcOpSearchDepth; this.maxOpOnePlayOutTimes = maxOpOnePlayOutTimes; this.maxOnePlayOutTimes = maxOnePlayOutTimes; this.BoardCoef = BoardCoef; this.MinionsCoef = MinionsCoef; this.OpMinionsCoef = OpMinionsCoef; availableOptionTypes.Add(PlayerTaskType.CHOOSE); availableOptionTypes.Add(PlayerTaskType.HERO_ATTACK); availableOptionTypes.Add(PlayerTaskType.HERO_POWER); availableOptionTypes.Add(PlayerTaskType.MINION_ATTACK); availableOptionTypes.Add(PlayerTaskType.PLAY_CARD); availableOpOptionTypes.Add(PlayerTaskType.HERO_ATTACK); availableOpOptionTypes.Add(PlayerTaskType.HERO_POWER); availableOpOptionTypes.Add(PlayerTaskType.MINION_ATTACK); }
public double scoreTask(SabberStoneCoreAi.POGame.POGame currentState, SabberStoneCoreAi.POGame.POGame nextState) { if (nextState == null) { return(Double.MinValue); } if (nextState.CurrentOpponent.Hero.Health <= 0) { return(Double.MaxValue); } if (nextState.CurrentPlayer.Hero.Health <= 0) { return(Double.MinValue); } double enemyHeroScore = scoreHero(currentState.CurrentOpponent, nextState.CurrentOpponent); double playerHeroScore = scoreHero(currentState.CurrentPlayer, nextState.CurrentPlayer); double enemyMinionsScore = scoreMinions(currentState.CurrentOpponent.BoardZone, nextState.CurrentOpponent.BoardZone); double playerMinionsScore = scoreMinions(currentState.CurrentPlayer.BoardZone, nextState.CurrentPlayer.BoardZone); double enemySecretsScore = scoreSecrets(currentState.CurrentOpponent, nextState.CurrentOpponent); double playerSecretsScore = scoreSecrets(currentState.CurrentPlayer, nextState.CurrentPlayer); double manaUsedScore = weights[MANA_REDUCED] * (currentState.CurrentPlayer.RemainingMana - nextState.CurrentPlayer.RemainingMana); return(enemyHeroScore - playerHeroScore + enemyMinionsScore - playerMinionsScore + enemySecretsScore - playerSecretsScore - manaUsedScore); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { int rndSeed = 0; if (startTurnMillsecond == 0) { startTurnMillsecond = DateTimeOffset.Now.ToUnixTimeMilliseconds(); } UCTSimulator simulator = new UCTSimulator(poGame, rndSeed, Rnd, MyProgram.ucb1Coef, MyProgram.mcSearchDepth, MyProgram.mcOpSearchDepth, MyProgram.maxOpOnePlayOutTimes, MyProgram.maxOnePlayOutTimes, MyProgram.BoardCoef, MyProgram.MinionsCoef, MyProgram.OpMinionsCoef); PlayerTask bestOption = null; try { bestOption = simulator.Simulate(simulator.root, startTurnMillsecond); } catch (Exception e) { bestOption = getBestMove(poGame); Log.Instance().Append(e.ToString()); } if (bestOption.PlayerTaskType == PlayerTaskType.END_TURN) { startTurnMillsecond = 0; } return(bestOption); }
public void FindNextMove(SabberStoneCoreAi.POGame.POGame poGame) { Controller opponent = poGame.CurrentOpponent; MCTSTree tree = new MCTSTree(); MCTSTree rootNode = tree.GetRootNode(); //rootNode.poGame.State = poGame.State; DateTime startTime = DateTime.UtcNow; while ((DateTime.UtcNow - startTime).TotalSeconds < 1000) { MCTSTree promisingNode = tree.GetPromisingNode(rootNode); if (tree.poGame.State != State.COMPLETE && tree.poGame.State != State.INVALID) { tree.ExpandNode(promisingNode); } MCTSTree nodeToExplore = promisingNode; if (nodeToExplore.childnodesList.Count > 0) { nodeToExplore = promisingNode.GetRandomChild(); } PlayState playoutResult = SimRanPlayout(nodeToExplore); //poGame.State playoutResult = simRanPlayout(nodeToExplore, opponent) nodeToExplore.Backpropagation(nodeToExplore, playoutResult); } MCTSTree winnerNode = rootNode.GetChildWithMaxScore(); List <PlayerTask> options = poGame.CurrentPlayer.Options(); //return winnerNode.state.board; }
public PlayerTask Simulate(SabberStoneCoreAi.POGame.POGame game) { List <PlayerTask> options = game.CurrentPlayer.Options(); PlayerTask bestOption = null; double bestReward = Double.MinValue; double reward = Double.MinValue; foreach (PlayerTask option in options) { if (option.PlayerTaskType == PlayerTaskType.END_TURN) { // evalute the current game // maybe do nothing is the best(directly end turn) reward = EvaluateNode(game); } else { POGame.POGame simulatedGame = Simulate(game, option); // simulate the option reward = Search(simulatedGame, maxDepth, maxnNode); } if (reward > bestReward) { bestReward = reward; bestOption = option; } } Debug.Assert(bestOption != null); return(bestOption); }
public double Search(SabberStoneCoreAi.POGame.POGame game, int depth, int nNode) { List <PlayerTask> options = game.CurrentPlayer.Options(); if (depth <= 0 || nNode <= 0) { return(EvaluateNode(game)); } double maxReward = Double.MinValue; double reward = Double.MinValue; foreach (PlayerTask option in options) { if (option.PlayerTaskType == PlayerTaskType.END_TURN) { reward = EvaluateNode(game); } else { POGame.POGame simulatedGame = Simulate(game, option); nNode -= 1; reward = Search(simulatedGame, depth - 1, nNode); } if (reward > maxReward) { maxReward = reward; } } return(maxReward); }
/* * The hero should destroy low health minions first */ private PlayerTask HeroAttack(SabberStoneCoreAi.POGame.POGame poGame) { // find taunt minions var tauntMinions = new List <IEntity> { }; foreach (Minion minion in poGame.CurrentOpponent.BoardZone.GetAll()) { if (minion.HasTaunt) { tauntMinions.Add(minion); } } foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { if (task.PlayerTaskType == PlayerTaskType.HERO_ATTACK) { if (task.Target == poGame.CurrentOpponent.Hero) { return(task); } } } return(null); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { MCT mct = new MCT(); PlayerTask nextPlayerMove = mct.FindNextMove(poGame); return(nextPlayerMove); }
float[] RandomOptionRating(SabberStoneCoreAi.POGame.POGame poGame, List <PlayerTask> playerTasks) { float[] result = new float[playerTasks.Count]; result[Rnd.Next(playerTasks.Count)] = 1; return(result); }
float[] RandomOptionRating(SabberStoneCoreAi.POGame.POGame poGame, List <PlayerTask> options) { float[] result = new float[options.Count]; for (int i = 0; i < options.Count; i++) { result[i] = (float)Rnd.NextDouble() * 2f - 1f; } return(result); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { List <PlayerTask> simulatedactions = new List <PlayerTask>(); simulatedactions.AddRange(poGame.CurrentPlayer.Options()); Dictionary <PlayerTask, SabberStoneCoreAi.POGame.POGame> sim = poGame.Simulate(simulatedactions); Dictionary <PlayerTask, SabberStoneCoreAi.POGame.POGame> .KeyCollection keyColl = sim.Keys; Dictionary <int, PlayerTask> scoresKeyPair = new Dictionary <int, PlayerTask>(); scoresKeyPair.Clear(); try { int maxScore = Int32.MinValue; int _score = 0; foreach (PlayerTask key in keyColl) { //Console.WriteLine(key); //Console.WriteLine("Player num -->>>>"+poGame.CurrentPlayer.PlayerId); //Console.WriteLine("SIM -->>>>"+sim[key]); if (sim[key] == null) { continue; } if (key.PlayerTaskType == PlayerTaskType.END_TURN) { _score = Int32.MinValue + 1; } else { _score = Score(sim[key], poGame.CurrentPlayer.PlayerId); } //Console.WriteLine(_score); if (!scoresKeyPair.ContainsKey(_score)) { scoresKeyPair.Add(_score, key); } if (_score > maxScore) { maxScore = _score; } } //Console.WriteLine("Played ==>> "+scoresKeyPair[maxScore]); return(scoresKeyPair[maxScore]); } catch { return(poGame.CurrentPlayer.Options()[Rnd.Next(poGame.CurrentPlayer.Options().Count)]); } }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { CurrentPoGame = poGame; ChangeStrategy(); List <PlayerTask> actions = poGame.CurrentPlayer.Options(); Dictionary <PlayerTask, POGame.POGame> resultedictionary = poGame.Simulate(actions); List <int> rewards = GetActionsRewards(actions, resultedictionary); return(actions[pickAction(rewards)]); }
public Node(SabberStoneCoreAi.POGame.POGame poGame) { this.reward = 0; this.nj = 0; this.j = 0; this.N = 0; this.parent = null; this.childDict = new Dictionary <PlayerTask, Node>(); this.currentPOGame = poGame; }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { DateTime start = DateTime.Now; List <PlayerTask> options = poGame.CurrentPlayer.Options(); PlayerTask t = options[0]; /* * Console.WriteLine("---------SaliMCTS---------"); * * foreach (PlayerTask option1 in options) * { * * Console.WriteLine(option1); * * } * * Console.WriteLine("--------------------------"); * Console.WriteLine(); */ if (options.Count == 1) { t = options[0]; } /*else if (options.Count == 2) * { * t = options[1]; * }*/ else { t = MCTS.MCTS.GetBestAction_second(poGame, remainingSeconds / (Math.Max(options.Count - actionCount, 1))); //t = MCTS.MCTS.GetBestAction_second(poGame,75); } double seconds = (DateTime.Now - start).TotalSeconds; if (t.PlayerTaskType == PlayerTaskType.END_TURN) { remainingSeconds = 15; actionCount = 0; } else { remainingSeconds -= seconds; actionCount++; } return(t); }
public POGame.POGame Simulate(SabberStoneCoreAi.POGame.POGame game, PlayerTask option) { LinkedList <PlayerTask> options = new LinkedList <PlayerTask>(); options.AddLast(option); Dictionary <PlayerTask, SabberStoneCoreAi.POGame.POGame> dict = game.Simulate(options.ToList <PlayerTask>()); SabberStoneCoreAi.POGame.POGame simulatedPOGame = null; dict.TryGetValue(option, out simulatedPOGame); return(simulatedPOGame); }
public UCTNode(SabberStoneCoreAi.POGame.POGame poGame) { this.reward = 0; this.nj = 0; this.j = 0; this.N = 0; this.parent = null; this.currentPOGame = poGame; this.option = null; this.childDict = new Dictionary <int, UCTNode>(); }
public int TotalOpponentHealth(SabberStoneCoreAi.POGame.POGame poGame) { int TotalOppHealth = poGame.CurrentOpponent.Hero.Health; foreach (Minion m in poGame.CurrentOpponent.BoardZone.GetAll()) { if (m.HasTaunt) { TotalOppHealth += m.Health; } } return(TotalOppHealth); }
public MCSimulator(SabberStoneCoreAi.POGame.POGame poGame, int randomSeed, Random rnd) { this.root = Root(poGame); this.rndSeed = randomSeed; if (rnd != null) { this.rnd = rnd; } else { this.rnd = new Random(this.rndSeed); } }
public Node(double reward, int nj, int j, int N, Node parent, Dictionary <PlayerTask, Node> childDict, SabberStoneCoreAi.POGame.POGame poGame) { this.reward = reward; this.nj = nj; this.j = j; this.N = N; this.parent = parent; this.childDict = childDict; this.currentPOGame = poGame; }
public int TotalAttack(SabberStoneCoreAi.POGame.POGame poGame) { int TotalAttack = 0; foreach (Minion m in poGame.CurrentPlayer.BoardZone.GetAll()) { if (m.CanAttack == true) { TotalAttack += m.AttackDamage; } } if (poGame.CurrentPlayer.Hero.CanAttack) { TotalAttack++; } return(TotalAttack); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { int rndSeed = 0; long startMillisecond = DateTimeOffset.Now.ToUnixTimeMilliseconds(); GSSimulator simulator = new GSSimulator(); PlayerTask bestOption = null; try { bestOption = simulator.Simulate(poGame); } catch (Exception e) { bestOption = getBestMove(poGame); } return(bestOption); }
/* * Determine if we should play the coin */ private PlayerTask ChooseCoin(SabberStoneCoreAi.POGame.POGame poGame) { foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { if (task.PlayerTaskType == PlayerTaskType.PLAY_CARD && task.Source.Card.Name == ("The Coin")) { // check if coin would add more options foreach (IPlayable othercards in poGame.CurrentPlayer.HandZone.GetAll()) { if (othercards.Card.Cost == 1 + poGame.CurrentPlayer.BaseMana && othercards.Card.Type == CardType.MINION) { return(task); } } } } return(null); }
public UCTNode(double reward, int nj, int j, int N, UCTNode parent, PlayerTask option, SabberStoneCoreAi.POGame.POGame poGame, Dictionary <int, UCTNode> childDict) { this.reward = reward; this.nj = nj; this.j = j; this.N = N; this.parent = parent; this.currentPOGame = poGame; this.option = option; this.childDict = childDict; }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { List <PlayerTask> simulatedactions = new List <PlayerTask>(); simulatedactions.AddRange(poGame.CurrentPlayer.Options()); Dictionary <PlayerTask, SabberStoneCoreAi.POGame.POGame> sim = poGame.Simulate(simulatedactions); Dictionary <PlayerTask, SabberStoneCoreAi.POGame.POGame> .KeyCollection keyColl = sim.Keys; foreach (PlayerTask key in keyColl) { //do something with simulated actions //in case an EndTurn was simulated you need to set your own cards //see POGame.prepareOpponent() for an example } return(poGame.CurrentPlayer.Options()[0]); }
/* * Choose what should be attacked */ private PlayerTask AttackTask(SabberStoneCoreAi.POGame.POGame poGame) { // find taunt minions var tauntMinions = new List <IEntity> { }; foreach (Minion minion in poGame.CurrentOpponent.BoardZone.GetAll()) { if (minion.HasTaunt) { tauntMinions.Add(minion); } } foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { if (task.PlayerTaskType == PlayerTaskType.MINION_ATTACK) { // if we have any taunt minions attack them first if (tauntMinions.Contains(task.Target)) { return(task); } Minion attacker = (Minion)task.Source; if (task.Target.GetType().Equals(typeof(Minion))) { Minion target = (Minion)task.Target; // if we can attack enemy minions so that ours don't die // if (attacker.AttackDamage >= target.Health && target.AttackDamage < attacker.Health) { // return task; // } // if our minion has less attack we can sacrifice it by attacking if (attacker.AttackDamage < target.AttackDamage && attacker.AttackDamage >= target.Health) { return(task); } } if (task.Target == poGame.CurrentOpponent.Hero) { return(task); } } } return(null); }
public override PlayerTask GetMove(SabberStoneCoreAi.POGame.POGame poGame) { List <PlayerTask> options = poGame.CurrentPlayer.Options(); if (options.Count > 1) { // filter all non EndTurn Tasks List <PlayerTask> validTasks = new List <PlayerTask>(); foreach (PlayerTask task in options) { if (task.PlayerTaskType != PlayerTaskType.END_TURN) { validTasks.Add(task); } } return(validTasks[Rnd.Next(validTasks.Count)]); } return(options[0]); }
/* * At first we should summon minions that increase the atack of other minions */ private PlayerTask SummonAuraMinion(SabberStoneCoreAi.POGame.POGame poGame) { foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { if (task.PlayerTaskType == PlayerTaskType.PLAY_CARD) { if (task.Source.GetType().Equals(typeof(Minion))) { if (((Minion)task.Source).Power != null && ((Minion)task.Source).Power.Aura != null) { if (((Minion)task.Source).Power.Aura.Type == AuraType.ADJACENT) { return(task); } } } } } return(null); }