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 PlayState SimRanPlayout(MCTSTree nodetoexplore) { while (nodetoexplore.poGame.CurrentPlayer.PlayState == PlayState.PLAYING) { } PlayState playoutresult = PlayState.WON; return(playoutresult); }
/// <summary> /// Constructor. /// </summary> /// <param name="parentTree"></param> /// <param name="maxCacheSize"></param> public MCTSNodeCacheArrayPurgeable(MCTSTree parentTree, int maxCacheSize) { maxCacheSize = Math.Max(3_000, maxCacheSize); ParentTree = parentTree; MaxCacheSize = maxCacheSize; nodes = new MCTSNode[maxCacheSize]; pruneSequenceNums = GC.AllocateUninitializedArray <int>(maxCacheSize); }
private int Simulate(MCTSTree node) { GameSimulator.ResetSimulation(node.gameState); while (!GameSimulator.IsSimulationFinished()) { List <CharacterActionType> actions = GameSimulator.GetNextPossibleActions(node); CharacterActionType selectedAction = GameSimulator.GetRandomAction(actions); GameSimulator.PlayAction(selectedAction); } return(GameSimulator.GetResult(id)); }
/// <summary> /// Constructor. /// </summary> /// <param name="parentTree"></param> /// <param name="maxCacheSize"></param> public MCTSNodeCacheArrayPurgeableSet(MCTSTree parentTree, int maxCacheSize) { ParentTree = parentTree; MaxCacheSize = maxCacheSize; // Initialize the sub-caches subCaches = new MCTSNodeCacheArrayPurgeable[MAX_SUBCACHES]; for (int i = 0; i < MAX_SUBCACHES; i++) { subCaches[i] = new MCTSNodeCacheArrayPurgeable(parentTree, maxCacheSize / MAX_SUBCACHES); } }
/// <summary> /// Constructor which creates an MCTSNode wrapper for the raw node at specified index. /// </summary> /// <param name="context"></param> /// <param name="index"></param> /// <param name="parent">optionally the parent node</param> internal MCTSNode(MCTSIterator context, MCTSNodeStructIndex index, MCTSNode parent = null) { Debug.Assert(context.Tree.Store.Nodes != null); Debug.Assert(index.Index <= context.Tree.Store.Nodes.MaxNodes); Context = context; Tree = context.Tree; this.parent = parent; Span <MCTSNodeStruct> parentArray = context.Tree.Store.Nodes.Span; ptr = (MCTSNodeStruct *)Unsafe.AsPointer(ref parentArray[index.Index]); this.index = index; }
/// <summary> /// Constructor. /// </summary> /// <param name="parentTree"></param> /// <param name="definitiveMaxCacheSize"></param> /// <param name="estimatedNumNodesInSearch"></param> public MCTSNodeCacheArrayPurgeableSet(MCTSTree parentTree, int definitiveMaxCacheSize, int estimatedNumNodesInSearch) { ParentTree = parentTree; MaxCacheSize = definitiveMaxCacheSize; // Compute number of subcaches, increasing as a function of estimates search size // (because degree of concurrency rises with size of batches and search. NumSubcaches = (int)StatUtils.Bounded(2 * MathF.Log2((float)estimatedNumNodesInSearch / 1000), 3, 16); // Initialize the sub-caches subCaches = new MCTSNodeCacheArrayPurgeable[NumSubcaches]; for (int i = 0; i < NumSubcaches; i++) { subCaches[i] = new MCTSNodeCacheArrayPurgeable(parentTree, definitiveMaxCacheSize / NumSubcaches); } }
private MCTSTree MCTSComputeAction() { int max = int.MinValue; MCTSTree bestAction = new MCTSTree(CharacterActionType.idle); foreach (var action in currentNode.Expand()) //Expansion { int numberVictory = 0; for (int i = 0; i < simulationAmountPerAction; ++i) { numberVictory += Simulate(action); } action.AddSimulationResult(numberVictory, simulationAmountPerAction); //Retropropagation if (max < action.GetSimulationResult()) //SimulationResult > -1 { max = action.GetSimulationResult(); bestAction = action; } } return(bestAction); }
//Will return the next actions the AI can do (for example if he's in mid air he can't jump) public static List <CharacterActionType> GetNextPossibleActions(MCTSTree node) { return(new List <CharacterActionType>()); }
public override void ExecuteActions() { MCTSTree chosenAction = MCTSComputeAction(); }
/// <summary> /// Constructor. /// </summary> /// <param name="parentTree"></param> /// <param name="initialCacheSize"></param> /// <param name="maxCacheSize"></param> public MCTSNodeCacheDict(MCTSTree parentTree, int initialCacheSize, int maxCacheSize) { ParentTree = parentTree; MaxCacheSize = maxCacheSize; nodeCache = new ConcurrentDictionary <int, MCTSNode>(EST_NUM_CONCURRENT, initialCacheSize); }