public void Execute() { //_game.Process(PlayerTask); // workaround for simulating one task Dictionary <PlayerTask, POGame.POGame> dic = _game.Simulate(new List <PlayerTask>() { PlayerTask }); _game = dic[PlayerTask]; //Controller controller = _game.ControllerById(_playerId); Controller controller = (_game.CurrentPlayer.Id == _playerId) ? _game.CurrentPlayer : _game.CurrentOpponent; _gameState = _game.State == State.RUNNING ? 0 : 1; _endTurn = _game.CurrentPlayer.Id != _playerId ? 1 : 0; // TODO: maybe asked if this is legit? // TODO: check content of 'Hash' //Hash = _game.Hash(GameTag.LAST_CARD_PLAYED, GameTag.ENTITY_ID); Hash = GetHashCode().ToString(); // scoring every state Scoring.Controller = controller; Score = Scoring.Rate(); }
private static PlayerTask greedyTask(POGame.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.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); }
KeyValuePair <PlayerTask, double> getBestTask(POGame.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.POGame before = state; if (t.PlayerTaskType == PlayerTaskType.END_TURN) { score = 0; } else { List <PlayerTask> toSimulate = new List <PlayerTask>(); toSimulate.Add(t); Dictionary <PlayerTask, POGame.POGame> simulated = state.Simulate(toSimulate); //Console.WriteLine("SIMULATION COMPLETE"); POGame.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)); }
public static TySimResult GetSimulatedGame(POGame.POGame parent, PlayerTask task, TyStateAnalyzer analyzer) { var simulatedState = parent.Simulate(new List <PlayerTask>() { task })[task]; var stateValue = GetStateValue(parent, simulatedState, task, analyzer); return(new TySimResult(simulatedState, task, stateValue)); }
private Node Expansion(Node leaf, ref POGame.POGame poGame) { Node nodeToSimulate; POGame.POGame pOGameIfSimulationFail = new POGame.POGame(poGame.getGame.Clone(), false); 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 float Simulation(Node nodeToSimulate, POGame.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); }
/// <summary> /// simulate the chosen move and update scorematrix with it /// </summary> /// <param name="poGame"></param> /// <param name="task"></param> /// <param name="options"></param> /// <returns>returns different Task if simulated Task produces errors</returns> PlayerTask SimulateNextTaskAndUpdateScoreMatrix(POGame.POGame poGame, PlayerTask task, List <PlayerTask> options) { POGame.POGame simulatedGame = poGame.getCopy(); try { Dictionary <PlayerTask, POGame.POGame> simulatedGames = simulatedGame.Simulate(new List <PlayerTask>() { task }); int tries = 0; while ((simulatedGames[task] == null || simulatedGames[task].State == SabberStoneCore.Enums.State.INVALID) && options.Count > 1) { if (tries > 3) { break; } task = options[Rnd.Next(options.Count)]; simulatedGames = simulatedGame.Simulate(new List <PlayerTask>() { task }); tries++; } simulatedGame.Process(task); } catch { } if (simulatedGame != null) { gameStateScoreMatrix.VisitState(GetExtensiveScoreParametersOfGame(simulatedGame)); } // check if game is ending to computer reward if (simulatedGame.CurrentPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON) { Log(LogLevel.INFO, "Might be winning next round, with health: " + simulatedGame.CurrentPlayer.Hero.Health); float additionalReward = Math.Clamp(simulatedGame.CurrentPlayer.Hero.Health / 30, 0, 1) * 100f; reward = 100f + additionalReward; } return(task); }
public override PlayerTask GetMove(POGame.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)); }
private void Expand() { WasExpanded = true; Dictionary <PlayerTask, POGame.POGame> dict = game.Simulate(game.CurrentPlayer.Options()); //set game to null so that it gets cleaned up faster by the gc to reduce needed memory foreach (KeyValuePair <PlayerTask, POGame.POGame> item in dict) { //poGame is null if exception occurs if (item.Value != null) { chdr.Add(new NodeGameState(item.Value, item.Key, this)); } } }
private TaskNode AddChild(PlayerTask action) { PossibleActions.Remove(action); Dictionary <PlayerTask, POGame.POGame> dic = Game.Simulate(new List <PlayerTask> { action }); POGame.POGame childGame = dic[action]; TaskNode child = new TaskNode(this, action, childGame); this.Children.Add(child); return(child); }
private int Simulate() { POGame.POGame gameClone = Game.getCopy(); int initialPlayer = gameClone.CurrentPlayer.PlayerId; while (true) { if (gameClone.State == SabberStoneCore.Enums.State.COMPLETE) { Controller currPlayer = gameClone.CurrentPlayer; if (currPlayer.PlayState == SabberStoneCore.Enums.PlayState.WON && currPlayer.PlayerId == initialPlayer) { return(1); } if (currPlayer.PlayState == SabberStoneCore.Enums.PlayState.LOST && currPlayer.PlayerId == initialPlayer) { return(0); } } List <PlayerTask> options = gameClone.CurrentPlayer.Options(); int randomNumber = rand.Next(options.Count); PlayerTask action = options[randomNumber]; try { // Process fails as soon as opponent plays a card, so use simulate here Dictionary <PlayerTask, POGame.POGame> dic = gameClone.Simulate(new List <PlayerTask> { action }); gameClone = dic[action]; //更新遊戲狀態 if (gameClone == null) { Debug.WriteLine(action.FullPrint()); } } catch (Exception e) { //Debug.WriteLine("Exception during single game simulation"); //Debug.WriteLine(e.StackTrace); } } }
private Node Selection(Node root, int iterations, ref POGame.POGame poGame) { Node bestNode = new Node(); double bestScore = double.MinValue; double childScore = 0; POGame.POGame pOGameIfSimulationFail = new POGame.POGame(poGame.getGame.Clone(), false); 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); }
private TaskNode AddChild(PlayerTask action) { PossibleActions.Remove(action); //Console.WriteLine("---------addchild---------"); // simulate the action so we can expand the tree Dictionary <PlayerTask, POGame.POGame> dic = Game.Simulate(new List <PlayerTask> { action }); POGame.POGame childGame = dic[action]; //更新遊戲狀態 TaskNode child = new TaskNode(this, action, childGame); this.Children.Add(child); return(child); }
public static double ucb1Heuristic(Node node, int iterations, double EXPLORE_CONSTANT, ref POGame.POGame poGame, double SCORE_IMPORTANCE, ParametricGreedyAgent greedyAgent) { double value; if (node.timesVisited > 0) { List <PlayerTask> taskToSimulate = new List <PlayerTask>(); taskToSimulate.Add(node.task); POGame.POGame stateAfterSimulate = poGame.Simulate(taskToSimulate)[node.task]; double score = greedyAgent.scoreTask(poGame, stateAfterSimulate); value = (node.totalValue / (double)node.timesVisited) + EXPLORE_CONSTANT * Math.Sqrt(Math.Log(iterations) / node.timesVisited) + SCORE_IMPORTANCE * (score / (double)node.timesVisited); } else { value = Double.MaxValue; } return(value); }
protected virtual PlayerTask BestCard(List <PlayerTask> cards, POGame.POGame poGame) { if (cards.Count > 0) { var simulation = poGame.Simulate(cards); var unpredicted = simulation.Where(it => it.Value == null).ToList(); /*if (unpredicted.Count > 0) * { * if (System.Diagnostics.Debugger.IsAttached) * System.Diagnostics.Debugger.Break(); * }*/ var best = simulation.Where(it => it.Value != null).MaxElement(Comp, (it => it.Value)); if (best.Key != null && Comp.Compare(best.Value, poGame) >= 0) { return(best.Key); } } return(null); }
public POGame.POGame SimulateOption(POGame.POGame game, PlayerTask option) { Dictionary <PlayerTask, POGame.POGame> dict = null; LinkedList <PlayerTask> options = null; POGame.POGame simulatedPOGame = null; options = new LinkedList <PlayerTask>(); options.AddLast(option); try { dict = game.Simulate(options.ToList <PlayerTask>()); } catch (Exception e) { return(null); } dict.TryGetValue(option, out simulatedPOGame); return(simulatedPOGame); }
float[] HardCodedSimulationRating(POGame.POGame poGame, List <PlayerTask> options) { float[] result = new float[options.Count]; try { Dictionary <PlayerTask, POGame.POGame> dict = poGame.Simulate(options); for (int i = 0; i < options.Count; i++) { if (dict[options[i]] != null) { result[i] = HardCodedGameRating(dict[options[i]]); } } } catch { } return(result); }
public override PlayerTask GetMove(POGame.POGame poGame) { PlayerTask result = null; List <PlayerTask> allTasks = poGame.CurrentPlayer.Options(); List <(PlayerTask, double)> scoreTasks = new List <(PlayerTask, double)>(); var origSimGames = poGame.Simulate(allTasks); var simGames = origSimGames.Where(x => x.Value != null); var deleted = origSimGames.Where(x => x.Value == null); foreach (var item in simGames) { scoreTasks.Add((item.Key, item.Key.PlayerTaskType != PlayerTaskType.END_TURN ? ScoreGame(item.Key, item.Value, poGame.CurrentPlayer.PlayerId) : ScoreGame(item.Key, poGame, poGame.CurrentPlayer.PlayerId))); } scoreTasks = scoreTasks.OrderByDescending(x => x.Item2).ToList(); //Console.ForegroundColor = ConsoleColor.DarkYellow; //foreach (var item in deleted) // Console.WriteLine($" {item.Key.ToString()}"); ////Console.ResetColor(); //Console.ForegroundColor = ConsoleColor.Cyan; //foreach (var item in scoreTasks) // Console.WriteLine($"[{item.Item2}] " + item.Item1.ToString()); //Console.ResetColor(); if (scoreTasks.Any()) { result = scoreTasks.First().Item1; } else { result = allTasks.First(x => x.PlayerTaskType == PlayerTaskType.END_TURN); } return(result); }
float[] ValuedOptionRating(POGame.POGame poGame, List <PlayerTask> options) { float[] result = new float[options.Count]; try { Dictionary <PlayerTask, POGame.POGame> dict = poGame.Simulate(options); for (int i = 0; i < options.Count; i++) { if (dict[options[i]] != null) { result[i] = gameStateScoreMatrix.GetScoreFromMatrix(GetExtensiveScoreParametersOfGame(dict[options[i]])); } } } catch { } // float highestValue = 0f; for (int i = 0; i < result.Length; i++) { if (result[i] > highestValue) { highestValue = result[i]; } } if (highestValue > 0) { for (int i = 0; i < result.Length; i++) { result[i] /= 200f; } } return(result); }
private List <Tuple <List <PlayerTask>, POGame.POGame> > DepthCardSearch(List <PlayerTask> cards, POGame.POGame poGame) { var result = new List <Tuple <List <PlayerTask>, POGame.POGame> >(); result.Add(Tuple.Create(new List <PlayerTask>(), poGame)); if (TurnStopwatch.Elapsed.TotalSeconds > 70) { var simulation = poGame.Simulate(cards) .Where(it => it.Value != null && Comp.Compare(it.Value, poGame) > 0); foreach (var(card, nextState) in simulation) { var nextDive = DepthCardSearch(nextState.Cards(), nextState); for (int i = 0; i < nextDive.Count; i++) { nextDive[i].Item1.Insert(0, card); } var best = nextDive.Where(it => it.Item2 != null).MaxElement(Comp, (it => it.Item2)); result.Add(best); } } return(result); }
/// <summary> /// TODO: API /// </summary> /// <param name="oppGame"></param> /// <param name="opponent">the controller of the opponent</param> /// <param name="predicitionMap">the map with all predictions</param> /// <param name="newSimulations"></param> /// <returns></returns> private double simulateOpponentWithPrediction(double lowerTimeBound, double timePerLeaf, POGame.POGame oppGame, Controller opponent, List <Prediction> predicitionMap, ref Dictionary <POGame.POGame, List <MCTSNode> > newSimulations) { double predictionScore = 0; if (predicitionMap?.Any() ?? false) { int denominator = predicitionMap.Count; var scorings = predicitionMap.GroupBy(p => p.Deck.Scoring) .Select(c => new MCTSNode.ScoreExt(((double)c.Count() / denominator), c.Key)) .OrderByDescending(s => s.Value).ToList(); // the simulation time for one prediction double timePerPrediction = timePerLeaf / predicitionMap.Count; // use prediction for each game for (int i = 0; i < predicitionMap.Count; i++) { Prediction prediction = predicitionMap[i]; var setasideZone = opponent.ControlledZones[Zone.SETASIDE] as SetasideZone; setasideZone = new SetasideZone(opponent); // create deck zone List <Card> deckCards = prediction.Deck.Cards; var deckZone = opponent.ControlledZones[Zone.DECK] as DeckZone; deckZone = new DeckZone(opponent); createZone(opponent, deckCards, deckZone, ref setasideZone); deckZone.Shuffle(); // create hand zone List <Card> handCards = prediction.Hand.Cards; var handZone = opponent.ControlledZones[Zone.HAND] as HandZone; handZone = new HandZone(opponent); createZone(opponent, handCards, handZone, ref setasideZone); var oppLeafNodes = new List <MCTSNode>(); IScore oppStrategy = prediction.Deck.Scoring; // forward game POGame.POGame forwardGame = oppGame.getCopy(); // upper time bound for simulation the opponent using the current prediction double oppSimulationTime = lowerTimeBound + (i + 1) * timePerPrediction / 2; // simulate opponent's moves while (forwardGame != null && forwardGame.State == State.RUNNING && forwardGame.CurrentPlayer.Id == opponent.Id) { // simulate var oppRoot = new MCTSNode(opponent.Id, scorings, forwardGame, null, null); MCTSNode bestOppNode = simulate(oppSimulationTime, oppRoot, ref oppLeafNodes); // get solution List <PlayerTask> solutions = bestOppNode.GetSolution(); for (int j = 0; j < solutions.Count && (forwardGame != null); j++) { PlayerTask oppTask = solutions[j]; Dictionary <PlayerTask, POGame.POGame> dir = forwardGame.Simulate(new List <PlayerTask> { oppTask }); forwardGame = dir[oppTask]; if (forwardGame != null && forwardGame.CurrentPlayer.Choice != null) { break; } } } // upper time bound for simulation the player using the forwarded game double simulationTime = oppSimulationTime + timePerPrediction / 2; double score = 0; var leafs = new List <MCTSNode>(); // simulate player using forwarded opponent game while (forwardGame != null && forwardGame.State == State.RUNNING && forwardGame.CurrentPlayer.Id == _playerId) { // simulate var root = new MCTSNode(_playerId, new List <MCTSNode.ScoreExt> { new MCTSNode.ScoreExt(1.0, _scoring) }, forwardGame, null, null); MCTSNode bestNode = simulate(simulationTime, root, ref leafs); // get solution List <PlayerTask> solutions = bestNode.GetSolution(); for (int j = 0; j < solutions.Count && (forwardGame != null); j++) { PlayerTask task = solutions[j]; Dictionary <PlayerTask, POGame.POGame> dir = forwardGame.Simulate(new List <PlayerTask> { task }); forwardGame = dir[task]; if (forwardGame != null && forwardGame.CurrentPlayer.Choice != null) { break; } } // TODO: maybe penalty forwardGame == null score = bestNode.TotalScore; } predictionScore += score; if (forwardGame != null) { newSimulations.Add(forwardGame, leafs); } } } return(predictionScore); }