private Dictionary <PlayerTask, int> SimulateAll(POGame initgame, List <PlayerTask> opitons, int depth) { Dictionary <PlayerTask, POGame> sims = initgame.Simulate(opitons); Dictionary <PlayerTask, int> scores = new Dictionary <PlayerTask, int>(); foreach (KeyValuePair <PlayerTask, POGame> sim in sims) { int score = int.MinValue; if (sim.Key.PlayerTaskType == PlayerTaskType.END_TURN || depth <= 0) { score = Score(sim.Value); } else { List <PlayerTask> new_options = sim.Value.CurrentPlayer.Options(); if (new_options.Count() > 0) { score = SimulateAll(sim.Value, new_options, depth - 1).ToList().Max(x => x.Value); } else { score = Score(sim.Value); } } scores.Add(sim.Key, score); } return(scores); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var optcount = validOpts.Count(); var returnValue = validOpts.Any() ? validOpts.Select(x => score(x, player.PlayerId, (optcount >= 5) ? ((optcount >= 25) ? 1 : 2) : 3)).OrderBy(x => x.Value).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); return(returnValue); KeyValuePair <PlayerTask, int> score(KeyValuePair <PlayerTask, POGame> state, int player_id, int max_depth = 3) { int max_score = int.MinValue; if (max_depth > 0 && state.Value.CurrentPlayer.PlayerId == player_id) { var subactions = state.Value.Simulate(state.Value.CurrentPlayer.Options()).Where(x => x.Value != null); foreach (var subaction in subactions) { max_score = Math.Max(max_score, score(subaction, player_id, max_depth - 1).Value); } } max_score = Math.Max(max_score, Score(state.Value, player_id)); return(new KeyValuePair <PlayerTask, int>(state.Key, max_score)); } }
// Simulates an option and returns the score that this option achieves // maxDepth: the maximum amount of recursive calls that is allowed private KeyValuePair <PlayerTask, double> Simulate(POGame poGame, int playerId, int maxDepth = 3) { List <PlayerTask> options = poGame.CurrentPlayer.Options(); Dictionary <PlayerTask, double> scores = new Dictionary <PlayerTask, double>(); options.ForEach(o => scores[o] = 0.0); poGame.Simulate(options).ToList().ForEach(simulation => { if (simulation.Value == null) { scores[simulation.Key] = Double.MinValue; return; } scores[simulation.Key] += ComputeScore(simulation.Value, playerId); if (maxDepth > 0 && playerId == poGame.CurrentPlayer.PlayerId) { scores[simulation.Key] += Simulate(simulation.Value, playerId, maxDepth - 1).Value; } }); // Get the option with the highest score return(scores.Aggregate((x, y) => x.Value > y.Value ? x : y)); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; //var opponent = game.CurrentOpponent; // Get all simulation results for simulations that didn't fail //var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var validOpts = game.Simulate(player.Options()); //Put player options in a variable var playerOptions = player.Options(); /*foreach (var x in playerOptions) * { * Console.WriteLine($"Here is an option {x.PlayerTaskType}"); * }*/ List <PlayerTask> PlayerTaskList = new List <PlayerTask>(validOpts.Keys); PlayerTask endTurnTask = playerOptions.First(); PlayerTask returnTask; updateStates(game); //Prints the game turn and the remaining mana available //Console.WriteLine($"Turn {game.Turn} Move {moveNum}, you have {player.RemainingMana} mana available."); //Prints the board state for the game turn //Console.WriteLine($"Board State for Turn {game.Turn}:" + game.PartialPrint()); InspectHand(player.HandZone); returnTask = PlayCard(PlayerTaskList, game.CurrentPlayer, player.HandZone, player.BoardZone, game); if (returnTask != null) { return(returnTask); } returnTask = MinionAttack(PlayerTaskList, game); if (returnTask != null) { return(returnTask); } if (player.RemainingMana > 0) { returnTask = HeroPower(PlayerTaskList, game.CurrentPlayer); if (returnTask != null) { return(returnTask); } } returnTask = heroAttack(PlayerTaskList); if (returnTask != null) { return(returnTask); } //Console.WriteLine($"Turn {game.Turn}: Ending Turn {endTurnTask}"); return(endTurnTask); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new WeightedScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } //Lookhead n steps and choose the best scoring <PlayerTask> and each depth -> branch ->score->until depth //(DFS search) var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var voptcount = validOpts.Count(); if (validOpts.Any()) { var depth = voptcount > 5 ? (voptcount > 25 ? 1: 2) : 3; var scored = validOpts.Select(x => Simulate(x, player.PlayerId, depth)); // Array.ForEach(scored.Select(x=>x.Item1).ToArray(),Console.Write); // Console.Write($"\r{scored.Count()} "); return(scored.OrderBy(x => x.Value).Last().Key); } else { return(player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); } }
KeyValuePair <PlayerTask, double> getBestTask(POGame state) { double bestScore = Double.MinValue; PlayerTask bestTask = null; List <PlayerTask> list = state.CurrentPlayer.Options(); foreach (PlayerTask t in list) { debug("---->POSSIBLE " + stringTask(t)); double score = 0; POGame before = state; if (t.PlayerTaskType == PlayerTaskType.END_TURN) { score = 0; } else { List <PlayerTask> toSimulate = new List <PlayerTask>(); toSimulate.Add(t); Dictionary <PlayerTask, POGame> simulated = state.Simulate(toSimulate); //Console.WriteLine("SIMULATION COMPLETE"); POGame nextState = simulated[t]; score = scoreTask(state, nextState); //Warning: if using tree, avoid overflow with max values! } debug("SCORE " + score); if (score >= bestScore) { bestTask = t; bestScore = score; } } return(new KeyValuePair <PlayerTask, double>(bestTask, bestScore)); }
private float DefaultPolicyHeuristic(Node node) { float result = 0; POGame state = node.State; int currentTurnDepth = node.TurnDepth; while (state.State != State.COMPLETE && (node.Action.PlayerTaskType == PlayerTaskType.END_TURN ? currentTurnDepth < TurnDepth - 1 : currentTurnDepth < TurnDepth)) { Controller currentPlayer = state.CurrentPlayer; List <PlayerTask> actions = currentPlayer.Options(); List <PlayerTask> oldActions = new List <PlayerTask>(actions); bool uncertainity = currentPlayer.Options() .Any(option => option.PlayerTaskType == PlayerTaskType.PLAY_CARD && option.Source.Card.Name == "No Way!"); // end potential infinite loop of 0 cost spells (happend few times with a mage) if (currentPlayer.CardsPlayedThisTurn.Count > 50) { break; } if (uncertainity) { // depending on active player choose one: // 1) simulate player's card draw // 2) simulate opponent's possible actions actions = state.CurrentPlayer.PlayerId == player.PlayerId ? ActionEstimator.DrawSimulation(currentPlayer) : ActionEstimator.ActionEstimaton(state, currentPlayer); } var bestPair = state.Simulate(actions.Any() ? actions : oldActions) .Where(pair => pair.Value != null) .OrderBy(pair => StateRateStrategies.GetStateRateStrategy(StateRateStrategy.Greedy)(pair.Value, currentPlayer)) .Last(); //Console.WriteLine(currentTurnDepth + ", " + bestPair.Key); if (bestPair.Key.PlayerTaskType == PlayerTaskType.END_TURN) { currentTurnDepth++; } state = bestPair.Value; // this should be redundant.. but, you know.. just in case.. if (state == null) { return(0.5f); } } var firstPlayer = state.CurrentPlayer.PlayerId == player.PlayerId ? state.CurrentPlayer : state.CurrentOpponent; result = StateRateStrategies.GetStateRateStrategy(StateRateStrategy.Greedy)(state, firstPlayer); return(result); }
private static PlayerTask greedyTask(POGame poGame, ParametricGreedyAgent greedyAgent, Random Rnd, double CHILDREN_CONSIDERED_SIMULATING) { PlayerTask bestTask = null; double bestScore = Double.MinValue; double score = 0; List <PlayerTask> taskToSimulate = new List <PlayerTask>(); POGame stateAfterSimulate = null; List <PlayerTask> options = poGame.CurrentPlayer.Options(); int cutPoint = (int)Math.Ceiling(poGame.CurrentPlayer.Options().Count *CHILDREN_CONSIDERED_SIMULATING); while (options.Count > cutPoint) { options.Remove(options[Rnd.Next(0, options.Count - 1)]); } foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { taskToSimulate.Add(task); stateAfterSimulate = poGame.Simulate(taskToSimulate)[task]; score = greedyAgent.scoreTask(poGame, stateAfterSimulate); if (score > bestScore) { bestScore = score; bestTask = task; } taskToSimulate.Clear(); } return(bestTask); }
public override PlayerTask GetMove(POGame game) { //StopWatch.StartWithReset(); int threadCount = 4; var player = game.CurrentPlayer; var opponent = game.CurrentOpponent; var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); var optsCount = validOpts.Count(); var history = opponent.PlayHistory; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } countProbabilities(); MCTS mcts = new MCTS(game, DecksDict, ProbabilitiesDict, TurnDepth, TimeBudget, Selection, StateRate, ExplorationConstant); PlayerTask result = mcts.Search(); //StopWatch.StopWithMessage(String.Format("Compute {0} options in {1} ms", optcount, StopWatch.ElapsedMilliseconds)); //Console.WriteLine("Final task: " + result); return(result); void countProbabilities() { /* ----------- Counting probabilities ------------ */ foreach (KeyValuePair <string, List <Card> > deck in DecksDict) { int similarCount = 0; var playedCards = history.Select(h => h.SourceCard).ToList(); var deckCards = deck.Value; var deckCardsDistinct = deckCards.Distinct().ToList(); playedCards .ForEach(playedCard => { deckCardsDistinct.ForEach(deckCard => { if (playedCard.Name == deckCard.Name) { similarCount++; } }); }); double probability = Math.Round((double)similarCount / deckCards.Count(), 2); ProbabilitiesDict[deck.Key] = probability; //if (probability > 0) Console.WriteLine(deck.Key + " has probability of " + ProbabilitiesDict[deck.Key] * 100 + "%"); } } }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; var opponent = poGame.CurrentOpponent; var validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null); var history = opponent.PlayHistory; if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new MyScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } updateProbabilities(); ActionEstimator = new ActionEstimator(DecksDict, ProbabilitiesDict); int optionsCount = validOpts.Count(); Console.WriteLine("Valid options for TestAgent: "); validOpts.ToList().ForEach(option => Console.WriteLine(option)); var action = validOpts.Any() ? validOpts.Select(option => Score(option, poGame.CurrentPlayer.PlayerId, (optionsCount >= 5) ? ((optionsCount >= 25) ? 1 : 2) : 3)).OrderBy(pair => pair.Value).Last().Key : player.Options().First(option => option.PlayerTaskType == PlayerTaskType.END_TURN); Console.WriteLine("TestAgent: " + action); return(action); void updateProbabilities() { /* ----------- Counting probabilities ------------ */ foreach (KeyValuePair <string, List <Card> > deck in DecksDict) { int similarCount = 0; var playedCards = history.Select(h => h.SourceCard).ToList(); var deckCards = deck.Value; var deckCardsDistinct = deckCards.Distinct().ToList(); playedCards .ForEach(playedCard => { deckCardsDistinct.ForEach(deckCard => { if (playedCard.Name == deckCard.Name) { similarCount++; } }); }); double probability = Math.Round((double)similarCount / deckCards.Count(), 2); ProbabilitiesDict[deck.Key] = probability; //if (probability > 0) Console.WriteLine(deck.Key + " has probability of " + ProbabilitiesDict[deck.Key] * 100 + "%"); } } }
public override PlayerTask GetMove(POGame poGame) { var player = poGame.CurrentPlayer; var validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null); return(validOpts.Any() ? validOpts.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); }
private Node Expansion(Node leaf, ref POGame poGame) { Node nodeToSimulate; POGame pOGameIfSimulationFail = poGame.getCopy(); if (leaf.timesVisited == 0 || leaf.depth >= TREE_MAXIMUM_DEPTH || leaf.task.PlayerTaskType == PlayerTaskType.END_TURN) { nodeToSimulate = leaf; } else { foreach (PlayerTask task in poGame.CurrentPlayer.Options()) { leaf.children.Add(new Node(task, leaf, leaf.depth + 1)); } nodeToSimulate = leaf.children[0]; List <PlayerTask> taskToSimulate = new List <PlayerTask>(); taskToSimulate.Add(nodeToSimulate.task); if (nodeToSimulate.task.PlayerTaskType != PlayerTaskType.END_TURN) { poGame = poGame.Simulate(taskToSimulate)[nodeToSimulate.task]; } while (poGame == null) { if (leaf.children.Count <= 1) { return(leaf); } poGame = pOGameIfSimulationFail; taskToSimulate.Clear(); leaf.children.Remove(leaf.children[0]); nodeToSimulate = leaf.children[0]; taskToSimulate.Add(nodeToSimulate.task); if (nodeToSimulate.task.PlayerTaskType != PlayerTaskType.END_TURN) { poGame = poGame.Simulate(taskToSimulate)[nodeToSimulate.task]; } } } return(nodeToSimulate); }
private PlayerTask BestAction(POGame state, List <PlayerTask> actions, Controller player, Func <POGame, Controller, int> strategy) { var validOpts = state.Simulate(actions).Where(x => x.Value != null); PlayerTask bestAction = validOpts.Any() ? validOpts.OrderBy(x => strategy(state, player)).Last().Key : actions.First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); return(bestAction); }
public static TySimResult GetSimulatedGame(POGame parent, PlayerTask task, TyStateAnalyzer analyzer) { POGame simulatedState = parent.Simulate(new List <PlayerTask>() { task })[task]; float stateValue = GetStateValue(parent, simulatedState, task, analyzer); return(new TySimResult(simulatedState, task, stateValue)); }
private float Simulation(Node nodeToSimulate, POGame poGame) { float result = -1; int simulationSteps = 0; PlayerTask task = null; List <PlayerTask> taskToSimulate = new List <PlayerTask>(); if (poGame == null) { return(0.5f); } if (nodeToSimulate.task.PlayerTaskType == PlayerTaskType.END_TURN) { return(Estimator.estimateFromState(ESTIMATION_MODE, poGame)); } while (poGame.getGame().State != SabberStoneCore.Enums.State.COMPLETE) { task = SimulationPolicies.selectSimulationPolicy(SIMULATION_POLICY, poGame, Rnd, greedyAgent, CHILDREN_CONSIDERED_SIMULATING); taskToSimulate.Add(task); if (task.PlayerTaskType != PlayerTaskType.END_TURN) { poGame = poGame.Simulate(taskToSimulate)[taskToSimulate[0]]; } taskToSimulate.Clear(); if (poGame == null) { return(0.5f); } if (task.PlayerTaskType == PlayerTaskType.END_TURN) { return(Estimator.estimateFromState(ESTIMATION_MODE, poGame)); } simulationSteps++; } if (poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.CONCEDED || poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.LOST) { result = 0; } else if (poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON) { result = 1; } return(result); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Get all simulation results for simulations that didn't fail var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); //Dictionary<PlayerTask, POGame> Dictionary <PlayerTask, POGame> dict1 = game.Simulate(game.CurrentPlayer.Options()); if (dict1.Any()) { return(dict1.OrderBy(s => Score(s.Value, game.CurrentPlayer.PlayerId)).Last().Key); } else { return(game.CurrentPlayer.Options().First(p => p.PlayerTaskType == PlayerTaskType.END_TURN)); } }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Get all simulation results for simulations that didn't fail var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); // If all simulations failed, play end turn option (always exists), else best according to score function return(validOpts.Any() ? validOpts.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); }
public override PlayerTask GetMove(POGame poGame) { if (poGame.Turn != turn) { turnWatch.Restart(); turn = poGame.Turn; } actWatch.Restart(); int actTime = (int)((30000 - turnWatch.ElapsedMilliseconds) * 0.75); var player = poGame.CurrentPlayer.PlayerId; var openTasks = new Stack <SimGame>(); openTasks.Push(new SimGame(poGame, SearchDepth)); // lookahead all solutions until SearchDepth reached int bestScore = int.MinValue; SimGame bestSim = null; while (openTasks.Any()) { var currentSim = openTasks.Pop(); var children = currentSim.Next(); for (int j = 0; j < children.Length; j++) { if (!children[j].hasChildren) { int score = children[j].GameValue(player, scoreDict); if (score > bestScore) { bestScore = score; bestSim = children[j]; } } else { openTasks.Push(children[j]); } } if (actWatch.ElapsedMilliseconds >= actTime) { break; } } //Debug.WriteLine($"Turn {poGame.Turn}|{poGame.CurrentPlayer.Hero.Health - poGame.CurrentOpponent.Hero.Health} took {actWatch.ElapsedMilliseconds}ms to find {bestSim.tasks[0]}"); //var foo = poGame.CurrentPlayer.Options(); //var bar = poGame.Simulate(foo); return(bestSim?.tasks[0] ?? poGame.Simulate(poGame.CurrentPlayer.Options()).Keys.First()); }
private KeyValuePair <int, float> DefaultPolicy(POGame state, Node node) { KeyValuePair <int, float> result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 0.5f); while (state.State != State.COMPLETE) { List <PlayerTask> actions = state.CurrentPlayer.Options(); List <PlayerTask> oldActions = new List <PlayerTask>(actions); bool uncertainity = state.CurrentPlayer.Options() .Any(option => option.PlayerTaskType == PlayerTaskType.PLAY_CARD && option.Source.Card.Name == "No Way!"); Controller currentPlayer = state.CurrentPlayer; if (uncertainity) { // player's drawn cards are also unknown -> need to simulate actions = state.CurrentPlayer.PlayerId == player.PlayerId ? ActionEstimator.DrawSimulation(currentPlayer) : ActionEstimator.ActionEstimaton(state, currentPlayer); } var bestPair = state.Simulate(actions.Any() ? actions : oldActions) .Where(pair => pair.Value != null) .OrderBy(pair => StateRateStrategies.GetStateRateStrategy(StateRateStrategy.Greedy)(pair.Value, player)) .Last(); //Console.WriteLine("Choosing: " + bestAction); state = bestPair.Value; // this should be redundant.. but, you know.. just in case.. if (state == null) { return(new KeyValuePair <int, float>(currentPlayer.PlayerId, 0.5f)); } } if (state.CurrentPlayer.PlayState == PlayState.CONCEDED || state.CurrentPlayer.PlayState == PlayState.LOST) { result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 0); } else if (state.CurrentPlayer.PlayState == PlayState.WON) { result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 1); } else if (state.CurrentPlayer.PlayState == PlayState.TIED) { result = new KeyValuePair <int, float>(state.CurrentPlayer.PlayerId, 0.5f); } return(result); }
private float Simulate(Node nodeToSimulate, POGame poGame) { float result = -1; int simulationSteps = 0; PlayerTask task = null; if (poGame == null) { return(0.5f); } List <PlayerTask> taskToSimulate = new List <PlayerTask>(1); taskToSimulate.Add(null); while (poGame.getGame().State != SabberStoneCore.Enums.State.COMPLETE) { task = Greedy(poGame); taskToSimulate[0] = task; if (task.PlayerTaskType != PlayerTaskType.END_TURN) { poGame = poGame.Simulate(taskToSimulate)[taskToSimulate[0]]; } if (poGame == null) { return(0.5f); } if (task.PlayerTaskType == PlayerTaskType.END_TURN) { return(ScoreToValue(Score(poGame))); } simulationSteps++; } if (poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.CONCEDED || poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.LOST) { result = 0; } else if (poGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON) { result = 1; } return(result); }
private void InitializeNode(Node node, POGame state) { if (state != null) { var validOpts = state.CurrentPlayer.Options() .Where(option => !(option.HasSource && option.Source.Card.Name == "No Way!")); var simulations = state.Simulate(validOpts.ToList()); simulations.Keys .ToList() .ForEach(option => node.Children.Add(new Node(simulations[option], option, node, state.CurrentPlayer.PlayerId, node.Action?.PlayerTaskType == PlayerTaskType.END_TURN ? node.TurnDepth + 1 : node.TurnDepth))); } }
private List <HardSimulation> Simulate(POGame game, int numSolutions) { var simulations = game .Simulate(game.CurrentPlayer.Options()).Where(x => x.Value != null) .Select(x => new HardSimulation { Task = x.Key, Game = x.Value, Score = Score(x.Value, game.CurrentPlayer.PlayerId) }) .OrderBy(x => x.Score) .TakeLast(numSolutions) .Reverse() // Best task first .ToList(); return(simulations); }
public override PlayerTask GetMove(POGame poGame) { timeIsUp = false; timer = new Timer(28000); timer.Elapsed += whenTimeUp; timer.Enabled = true; Controller player = poGame.CurrentPlayer; playerId = player.PlayerId; if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } IEnumerable <KeyValuePair <PlayerTask, POGame> > validOpts = poGame.Simulate(player.Options()).Where(x => x.Value != null); int countOptions = validOpts.Count(); //AppendChildNodes(rootNode); int bestScore = Int32.MinValue; PlayerTask chosenTask = null; foreach (KeyValuePair <PlayerTask, POGame> option in validOpts) { int currentScore = MiniMax(0, option.Value, true, Int32.MinValue, Int32.MaxValue); //Console.WriteLine("Current Score: " + currentScore); if (currentScore > bestScore) { bestScore = currentScore; chosenTask = option.Key; } } //Console.WriteLine("Best Score: " + bestScore); if (chosenTask == null) { chosenTask = player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); } //Console.WriteLine("Zugzeit " + stopWatch.Elapsed); //Console.WriteLine("Best Task: " + chosenTask); return(chosenTask); }
public override PlayerTask GetMove(POGame poGame) { int myPlayerId = poGame.CurrentPlayer.PlayerId; List <PlayerTask> options = poGame.CurrentPlayer.Options(); // Implement a simple Mulligan Rule if (poGame.CurrentPlayer.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(poGame.CurrentPlayer.Choice.Choices.Select(p => poGame.getGame().IdEntityDic[p]).ToList()); //all mulligan handlers are the same for each score return(ChooseTask.Mulligan(poGame.CurrentPlayer, mulligan)); } var simulationResults = poGame.Simulate(options); double bestWorth = getWorth(poGame, myPlayerId); //best worth starts with the current field PlayerTask bestTask = null; foreach (PlayerTask t in options) { double resultingWorth = Double.NegativeInfinity; if (simulationResults.ContainsKey(t) && t.PlayerTaskType != PlayerTaskType.END_TURN) { POGame resultingGameState = simulationResults[t]; resultingWorth = getWorth(resultingGameState, myPlayerId); } else //TODO: think of something to do if the key is unvalid //for now, do nothing if the resulting value is negative { } if (bestWorth < resultingWorth) { bestWorth = resultingWorth; bestTask = t; } } if (bestTask == null) { return(EndTurnTask.Any(poGame.CurrentPlayer)); } return(bestTask); }
private Node Selection(Node root, int iterations, ref POGame poGame) { Node bestNode = new Node(); double bestScore = double.MinValue; double childScore = 0; POGame pOGameIfSimulationFail = poGame.getCopy(); foreach (Node node in root.children) { childScore = TreePolicies.selectTreePolicy(TREE_POLICY, node, iterations, EXPLORE_CONSTANT, ref poGame, SCORE_IMPORTANCE, greedyAgent); if (childScore > bestScore) { bestScore = childScore; bestNode = node; } } List <PlayerTask> taskToSimulate = new List <PlayerTask>(); taskToSimulate.Add(bestNode.task); if (bestNode.task.PlayerTaskType != PlayerTaskType.END_TURN) { poGame = poGame.Simulate(taskToSimulate)[bestNode.task]; } if (poGame == null) { root.children.Remove(bestNode); if (root.children.Count == 0) { root = root.parent; } poGame = pOGameIfSimulationFail; return(Selection(root, iterations, ref poGame)); } if (bestNode.children.Count != 0) { bestNode = Selection(bestNode, iterations, ref poGame); } return(bestNode); }
public int Rollout(Node node, Controller player) { POGame state = node.State.Value; KeyValuePair <PlayerTask, POGame> bestMove; //while (!(state.getGame().State == State.COMPLETE)) do { List <PlayerTask> moves = state.CurrentPlayer.Options(); var legalMoves = state.Simulate(moves).Where(x => x.Value != null).ToList(); bestMove = legalMoves.OrderBy(x => Score(x.Value, state.CurrentPlayer.PlayerId)).Last(); state = bestMove.Value; } while (bestMove.Key.PlayerTaskType != PlayerTaskType.END_TURN); int result = Reward(state, player.PlayerId, terminalIsEOT: true); return(result); }
public POGame Simulation(MCTSNode node, int myPlayerId) { int depth = MAX_SIMULATION_DEPTH; POGame simGame = node.poGame.getCopy(); //if(node.poGame.CurrentPlayer.Id != myPlayerId) simGame = createOpponentHand(simGame.getCopy()); while (depth > 0) { IEnumerable <KeyValuePair <PlayerTask, POGame> > subactions = simGame.Simulate(simGame.CurrentPlayer.Options()).Where(x => x.Value != null); if (!subactions.Any()) { break; } simGame = subactions.RandomElement(rnd).Value.getCopy(); depth--; } return(simGame); }
public override PlayerTask GetMove(POGame game) { var player = game.CurrentPlayer; // Implement a simple Mulligan Rule if (player.MulliganState == Mulligan.INPUT) { List <int> mulligan = new AggroScore().MulliganRule().Invoke(player.Choice.Choices.Select(p => game.getGame().IdEntityDic[p]).ToList()); return(ChooseTask.Mulligan(player, mulligan)); } // Get all simulation results for simulations that didn't fail var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); // If all simulations failed, play end turn option (always exists), else best according to score function return(validOpts.Any() ? validOpts.OrderBy(x => Score(x.Value, player.PlayerId)).Last().Key : player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN)); }
public override PlayerTask GetMove(POGame game) { pID = game.CurrentPlayer.Id; var player = game.CurrentPlayer; var validOpts = game.Simulate(player.Options()).Where(x => x.Value != null); /* No look-ahead*/ /*return validOpts.Any() ? * validOpts.OrderBy(x => getValue(game, x.Value)).Last().Key : * player.Options().First(x => x.PlayerTaskType == PlayerTaskType.END_TURN);*/ /* with look-ahead */ PlayerTask best_move = null; double best_value = 0; foreach (KeyValuePair <PlayerTask, POGame> pair in validOpts) { var game_ = pair.Value; var player_ = game_.CurrentPlayer; var move_ = pair.Key; if (player_.Id == player.Id) { var validOpts_ = game_.Simulate(player_.Options()).Where(x => x.Value != null); foreach (KeyValuePair <PlayerTask, POGame> pair_ in validOpts_) { double value = getValue(pair_.Value); if (value > best_value) { best_value = value; best_move = move_; } } } } if (best_move == null) { best_move = validOpts.OrderBy(x => getValue(x.Value)).Last().Key; } return(best_move); }
PlayerTask Greedy(POGame poGame) { PlayerTask bestTask = null; int bestScore = Int32.MinValue; List <PlayerTask> options = poGame.CurrentPlayer.Options(); var simulated = poGame.Simulate(options); foreach (var stateAfterSimulate in simulated) { int score = Score(stateAfterSimulate.Value); if (score >= bestScore) { bestScore = score; bestTask = stateAfterSimulate.Key; } } return(bestTask); }