public static void Save(SkyNetNode toSave, int bundleNum, int numGames, int numIters) { fileMut.WaitOne(); rootMut.WaitOne(); if (RootMap.ContainsKey(toSave.boardHash + toSave.hand)) { int key = RootMap[toSave.boardHash + toSave.hand]; BinaryFormatter bf1 = new BinaryFormatter(); FileStream file1 = File.Create("./SkyNetData/Root_" + key.ToString() + ".dat"); FileStream file2 = File.Create(String.Format("./SkyNetData/Root_Bundle_{0}_{1}G_{2}I/Root_{3}.dat", bundleNum.ToString(), numGames.ToString(), numIters.ToString(), key.ToString())); bf1.Serialize(file1, toSave); bf1.Serialize(file2, toSave); file1.Close(); file2.Close(); } Console.WriteLine("SAVED SQUISHY!!!"); BinaryFormatter bf = new BinaryFormatter(); FileStream file = File.Create("./SkyNetData/RootMap.dat"); FileStream file0 = File.Create(String.Format("./SkyNetData/Root_Bundle_{0}_{1}G_{2}I/RootMap.dat", bundleNum.ToString(), numGames.ToString(), numIters.ToString())); bf.Serialize(file, RootMap); bf.Serialize(file0, RootMap); rootMut.ReleaseMutex(); file.Close(); file0.Close(); fileMut.ReleaseMutex(); }
private bool MCTSRandSimPlayout(SkyNetNode curNode) { Console.WriteLine("ENTERING MCTS SIM PLAYOUT"); IBoard tmpBoard = localBoard; bool curBoardTerminal = CheckTerminalNode(tmpBoard); Random rand = new Random(); bool playerOne = curNode.playerOne; while (!curBoardTerminal) { List <GameMove> availMoves = localGame.getAllPlayerMoves(tmpBoard, playerOne); int cnt = availMoves.Count; int randMoveInd = rand.Next(0, availMoves.Count); GameMove randMove = availMoves [randMoveInd]; Console.WriteLine(String.Format("Move Made!\nPlayer One's: {1}\nMove: {2}", playerOne.ToString(), randMove.ToString())); makeMove(tmpBoard, randMove); curBoardTerminal = CheckTerminalNode(tmpBoard); if (!curBoardTerminal) { playerOne = !playerOne; } } Console.WriteLine("Player One Win: " + playerOne.ToString()); Console.WriteLine("EXITING MCTS SIM PLAYOUT"); return(playerOne); }
public static bool RequestExistingRoot(ref SkyNetNode root, int gameNum, int bundleNum, int numGames, int numIters) { string hashKey = root.boardHash + root.hand; rootMut.WaitOne(); if (!RootMap.ContainsKey(hashKey)) { RootMap.Add(hashKey, gameNum); } int key = RootMap[hashKey]; if (File.Exists("./SkyNetData/Root_" + key.ToString() + ".dat")) { fileMut.WaitOne(); Log(gameNum, "LOADED ROOT", bundleNum, numGames, numIters); BinaryFormatter bf = new BinaryFormatter(); FileStream file = File.Open("./SkyNetData/Root_" + key.ToString() + ".dat", FileMode.Open); root = (SkyNetNode)bf.Deserialize(file); Debug.Assert(hashKey.Equals(root.boardHash + root.hand)); file.Close(); fileMut.ReleaseMutex(); rootMut.ReleaseMutex(); return(true); } //Save(root, bundleNum, numGames, numIters); rootMut.ReleaseMutex(); return(false); }
// public void MCTS(int playerTurn, SkyNetNode prevNode){ // IBoard board = localGame.getBoard(); // int ind = 0; // bool expanding = true; // while(expanding){ // // string[][] bString = localGame.getBoardAsString (board, playerTurn); // string bHash = hashAndSlasher.HashIt (bString); // // List<GameMove> availMoves = localGame.getAllPlayerMoves (board, playerTurn); // // if (!shortTermMemory.ContainsKey (bHash)) { // shortTermMemory.Add (bHash, new List<SkyNetNode> ()); // } // // List<SkyNetNode> movesInMem = shortTermMemory[bHash]; // GameMove selected = availMoves [ind]; // SkyNetNode selectAsNode = new SkyNetNode (selected, prevNode, playerTurn, false); // int memInd = movesInMem.IndexOf (selectAsNode); // if (memInd != -1) { // We've done this move from this state before // selectAsNode = movesInMem[memInd]; // selectAsNode.prevNode = prevNode; // } else { // movesInMem.Add (selectAsNode); // } // selectAsNode.incVisit (); // // board = mockMove (board, selectAsNode); // if (!CheckTerminalNode (board)) { // // } else { // expanding = false; // backpropWin (selectAsNode); // } // } // } private void MCTSExpand(SkyNetNode curNode) { Console.WriteLine("ENTERING MCTS EXPANSION"); bool playerOne = !curNode.playerOne; List <GameMove> availMoves = localGame.getAllPlayerMoves(localBoard, playerOne); int cnt = availMoves.Count; string hash = hashAndSlasher.HashIt(localGame.getBoardAsString(localBoard, playerOne)); bool curBoardTerminal = CheckTerminalNode(localBoard); if (cnt > 0 && !curBoardTerminal) { curNode.children = new List <SkyNetNode>(); for (int i = 0; i < cnt; i++) { curNode.children.Add(new SkyNetNode(availMoves [i], curNode, playerOne, hash)); Console.WriteLine(String.Format("Added new Child Node at Index: {1}{2}", i.ToString(), curNode.children[i].ToString())); } } else { Console.WriteLine(String.Format("Found Terminal Node {1}", curNode.ToString())); curNode.setTerminalFlag(true); } Console.WriteLine("EXITING MCTS EXPANSION"); }
public GameMove PickGameMove(ref IGame game, GameMove prevPlayerMove) { if (prevPlayerMove != null) { foreach (SkyNetNode pMove in rootNode.children) { if (pMove.move.Equals(prevPlayerMove)) { curGameHead = pMove; string bStr = game.getBoardAsString(game.getBoard(), !game.isPlayerOneTurn()); string hStr = game.getHandAsString(!game.isPlayerOneTurn()); Debug.Assert((curGameHead.boardHash + curGameHead.hand).Equals(bStr + hStr)); } } } DateTime curTime = DateTime.UtcNow; DateTime endTime = DateTime.UtcNow.AddSeconds(maxWait); int curITer = 0; while (DateTime.Compare(curTime, endTime) < 0) { MCTSSingleIteration(game.CopyGame(), ref curGameHead, curITer, curGameHead.level); curITer++; curTime = DateTime.UtcNow; } SkyNetNode toRet = MCTSSelect(curGameHead, 1, 1); return(toRet.move); }
private SkyNetNode MCTSSelect(SkyNetNode curNode, int iterNum, int moveCnt) { DebugPrint("ENTERING MCTS SELECTION -- " + iterNum.ToString() + "\n"); SkyNetNode toRet = curNode; float topWinRate = float.MinValue; //rootMut.WaitOne(); foreach (SkyNetNode skyNode in curNode.children) { //Console.WriteLine(iterNum); float childWinRate = (skyNode.winCnt / skyNode.visitCnt); //if(iterNum != -1 && moveCnt != -1){ childWinRate = childWinRate + ((.8f / (skyNode.winCnt + 1)) * ((float)Math.Sqrt(Math.Log(((iterNum + 1) / (skyNode.visitCnt)) < 1 ? 1 : ((iterNum + 1) / (skyNode.visitCnt))) / (skyNode.visitCnt)))); //} // float childWinRate = ((skyNode.winCnt / skyNode.visitCnt) // + ( (.8f / (skyNode.winCnt + 1)) // * ((float) Math.Sqrt(Math.Log(((iterNum + 1) / (skyNode.visitCnt)) < 1 ? 1 : ((iterNum + 1) / (skyNode.visitCnt))) / (skyNode.visitCnt))))); // // Console.WriteLine((iterNum + 1) / (skyNode.visitCnt)); if (childWinRate > topWinRate) { toRet = skyNode; topWinRate = childWinRate; DebugPrint("Found More Valuable Child\n"); } } //rootMut.ReleaseMutex(); if (!curNode.terminal) { Debug.Assert(!toRet.Equals(curNode)); } //Debug.Assert(to) DebugPrint("EXITING MCTS SELECTION -- " + iterNum.ToString() + "\n"); return(toRet); }
private SkyNetNode MCTSSelect(SkyNetNode curNode, int iterNum, int moveCnt) { DebugPrint("ENTERING MCTS SELECTION -- " + iterNum.ToString() + "\n"); SkyNetNode toRet = curNode; float topWinRate = -1.0f; rootMut.WaitOne(); foreach (SkyNetNode skyNode in curNode.children) { float childWinRate = (skyNode.visitCnt == 0 ? 0 : skyNode.winCnt / skyNode.visitCnt) + ((.8f / (skyNode.winCnt + 1)) * ((float)Math.Sqrt(Math.Log(moveCnt / (skyNode.visitCnt == 0 ? 1 : skyNode.visitCnt)) / (skyNode.visitCnt == 0 ? 1 : skyNode.visitCnt))));; if (childWinRate > topWinRate) { toRet = skyNode; topWinRate = childWinRate; DebugPrint("Found More Valuable Child\n"); } } rootMut.ReleaseMutex(); //Debug.Assert(to) DebugPrint("EXITING MCTS SELECTION -- " + iterNum.ToString() + "\n"); return(toRet); }
public SkyNetNode PickOfficialMove(IGame game, SkyNetNode gameNode, int numIters, int gameNum, int moveCnt) { //DateTime curTime = DateTime.UtcNow; //DateTime endTime = DateTime.UtcNow.AddSeconds(maxWait); //for(int i = 0; i < numIters && DateTime.Compare(curTime, endTime) <= 0; i++) for (int i = 0; i < numIters; i++) { //RLBrain.Log(gameNum, String.Format("ITERATION {0}/{1}", i + 1, numIters)); object[] objArr = new object[] { game.CopyGame(), gameNode, i }; ///ThreadPool.QueueUserWorkItem(MCTSSingleIterationThreaded, objArr); MCTSSingleIteration(game.CopyGame(), gameNode, i, moveCnt); //curTime = DateTime.UtcNow; } // int numAvail = 0; // int other1 = 0; // int maxThreads = 0; // int other2 = 0; // int numRunning = 0; // do // { // ThreadPool.GetAvailableThreads(out numAvail, out other1); // ThreadPool.GetMaxThreads(out maxThreads, out other2); // numRunning = (maxThreads - numAvail) + (other2 - other1); // //Console.WriteLine(String.Format("{0} RUNNING -- {1} AVAILABLE", numRunning, numAvail)); // } while (numRunning > 0); SkyNetNode chosen = MCTSSelect(gameNode, -1, moveCnt); return(chosen); }
public MCTSkyNet(IGame game, bool playerOne) { hashAndSlasher = ZobristKiller.GetTheKiller(); shortTermMemory = new Dictionary <string, List <SkyNetNode> > (); localBoard = game.getBoard(); localBString = game.getBoardAsString(localBoard, playerOne); rootNode = new SkyNetNode(hashAndSlasher.HashIt(localBString), playerOne); }
public MCTSkyNet(IGame game, int gameNum) { string localBString = game.getBoardAsString(game.getBoard(), !game.isPlayerOneTurn()); rootNode = new SkyNetNode(localBString, !game.isPlayerOneTurn(), game.getHandAsString(!game.isPlayerOneTurn())); //RLBrain.RequestExistingRoot(ref rootNode, gameNum, 0, 1, 0); curGameHead = rootNode; }
public MCTSkyNet(IGame game, int numIters, float maxWait, int gameNum, int bundleNum, int numGames) { //hashAndSlasher = ZobristKiller.GetTheKiller(); string localBString = game.getBoardAsString(game.getBoard(), !game.isPlayerOneTurn()); rootNode = new SkyNetNode(localBString, !game.isPlayerOneTurn(), game.getHandAsString(!game.isPlayerOneTurn())); //RLBrain.RequestExistingRoot(ref rootNode, gameNum, bundleNum, numGames, numIters); }
static void Main_No(string[] args) { string[] inputs; inputs = Console.ReadLine().Split(' '); int N = int.Parse(inputs[0]); // the total number of nodes in the level, including the gateways int L = int.Parse(inputs[1]); // the number of links int E = int.Parse(inputs[2]); // the number of exit gateways SkyNetNode[] nodes = new SkyNetNode[N]; for (int i = 0; i < N; i++) { nodes[i] = new SkyNetNode(i); } for (int i = 0; i < L; i++) { inputs = Console.ReadLine().Split(' '); int N1 = int.Parse(inputs[0]); // N1 and N2 defines a link between these nodes int N2 = int.Parse(inputs[1]); nodes[N1].Links.Add(nodes[N2]); nodes[N2].Links.Add(nodes[N1]); } for (int i = 0; i < E; i++) { int EI = int.Parse(Console.ReadLine()); // the index of a gateway node nodes[EI].IsGateWay = true; } // game loop while (true) { int SI = int.Parse(Console.ReadLine()); // The index of the node on which the Skynet agent is positioned this turn int otherIndex = -1; var agentLinks = nodes[SI].Links; foreach (var node in agentLinks) { if (node.IsGateWay) { otherIndex = node.Id; break; } } //没有直接连接到gateway的,只在周围连接里面随便断一个 if (otherIndex < 0) { otherIndex = nodes[SI].Links[0].Id; } // Write an action using Console.WriteLine() // To debug: Console.Error.WriteLine("Debug messages..."); // Example: 0 1 are the indices of the nodes you wish to sever the link between Console.WriteLine(SI + " " + otherIndex); } }
public Worker(SkyNetNode node, int partitionNumber, Job job, int partitions, GraphInfo graphInfo) { this.node = node; this.partitionNumber = partitionNumber; this.currentIteration = -1; this.job = job; this.partitions = partitions; this.graphInfo = graphInfo; }
private bool MCTSRandSimPlayout(IGame curGame, SkyNetNode curNode, ref bool stalemate, int iterNum) { DebugPrint("ENTERING MCTS SIM PLAYOUT -- " + iterNum.ToString() + "\n"); IGame tmpGame = curGame.CopyGame(); if (curNode.isTerminal()) { DebugPrint("Player One Win: " + curNode.playerOne.ToString() + "\n"); DebugPrint("EXITING MCTS SIM PLAYOUT -- " + iterNum.ToString() + "\n"); return(tmpGame.isPlayerOneTurn()); } Debug.Assert(tmpGame.isPlayerOneTurn() == curNode.playerOne); MakeMove(tmpGame, curNode.move); IBoard tmpBoard = tmpGame.getBoard(); bool curBoardTerminal = curNode.isTerminal(); Random rand = new Random(); float moveCnt = 0; // float numMins = 0; // DateTime curTime = DateTime.UtcNow; // DateTime nextPrint = curTime.AddMinutes(1); // float movesPerSec = 0.0f; while (!curBoardTerminal) { List <GameMove> availMoves = tmpGame.getAllPlayerMoves(tmpBoard, tmpGame.isPlayerOneTurn()); int cnt = availMoves.Count; int randMoveInd = rand.Next(0, availMoves.Count); GameMove randMove = availMoves[randMoveInd]; //DebugPrint(String.Format("Move Made!\nPlayer One's: {0}\nMove: {1}\n", tmpGame.isPlayerOneTurn().ToString(), randMove.ToString())); MakeMove(tmpGame, randMove); // curTime = DateTime.UtcNow; // if (curTime.CompareTo(nextPrint) > 0) // { // nextPrint = curTime.AddMinutes(1); // numMins++; // movesPerSec = moveCnt / (numMins * 60); // //DebugPrint(String.Format("Moves: {0} --- Mins: {1} --- MPS: {2}\n", moveCnt, numMins, movesPerSec)); // } moveCnt++; if (moveCnt >= (RLBrain.maxMoves - curNode.level)) { stalemate = true; DebugPrint("EXITING MCTS SIM PLAYOUT -- " + iterNum.ToString() + "\n"); return(!tmpGame.isPlayerOneTurn()); } curBoardTerminal = CheckTerminalBoard(tmpGame, tmpBoard); if (curBoardTerminal) { //same thing as "return !curGame.isPlayerOneTurn();" tmpGame.switchTurn(); } } DebugPrint("Player One Win: " + tmpGame.isPlayerOneTurn().ToString() + "\n"); DebugPrint("EXITING MCTS SIM PLAYOUT -- " + iterNum.ToString() + "\n"); return(tmpGame.isPlayerOneTurn()); }
public SkyNetNode(GameMove move, SkyNetNode prevNode, bool playerOne, string boardHash) { this.move = move; this.parent = prevNode; this.playerOne = playerOne; this.terminal = false; this.boardHash = boardHash; this.winCnt = 0; this.visitCnt = 0; }
private void MergeTrees(SkyNetNode oldRoot, SkyNetNode newRoot) { oldRoot.visitCnt += newRoot.visitCnt; oldRoot.winCnt += newRoot.visitCnt; foreach (SkyNetNode newchild in newRoot.children) { if (oldRoot.children.Contains(newchild)) { } } }
public SkyNetNode(string boardHash, bool playerOne) { this.move = null; this.parent = null; this.children = null; this.playerOne = playerOne; this.boardHash = boardHash; this.terminal = false; this.winCnt = 0; this.visitCnt = 0; }
public void TrainOfThought(object stateInfo) { IGame game = new Game(); MCTSkyNet squishyThought = new MCTSkyNet(game, game.isPlayerOneTurn()); for (int i = 0; i < numPlaythroughs; i++) { squishyThought.MCTSSingleIteration(); } SkyNetNode newRoot = squishyThought.GetRoot(); }
public void MCTSSingleIteration(IGame curGame, SkyNetNode gameNode, int iterNum, int moveCnt) { //Console.WriteLine(String.Format("ENTERING ITERATION -- {0}", iterNum)); MCTSExpand(curGame, gameNode, iterNum); SkyNetNode pickedChild = MCTSSelect(gameNode, iterNum, moveCnt); bool stalemate = false; bool playerOneWin = MCTSRandSimPlayout(curGame, pickedChild, ref stalemate, iterNum); MCTSBackpropWin(pickedChild, playerOneWin, stalemate, iterNum); //RLBrain.Save(this.GetRoot()); //Console.WriteLine(String.Format("EXITING ITERATION -- {0}", iterNum)); }
private static void PrintTreeHelper(SkyNetNode curNode, int lev, string filestr) { if (curNode.winCnt / curNode.visitCnt <= 1.0f) { WriteToFile(filestr, "\n Level: " + lev.ToString() + "\n" + curNode.ToString()); } int nxtlev = lev + 1; foreach (SkyNetNode child in curNode.children) { PrintTreeHelper(child, nxtlev, filestr); } }
private void MCTSBackpropWin(SkyNetNode endNode, bool playerOneWin) { Console.WriteLine("ENTERING MCTS BACKPROPOGATION"); SkyNetNode cur = endNode; while (cur != null) { cur.incWinAndVisit(playerOneWin); Console.Write(cur.ToString()); cur = cur.parent; } Console.WriteLine("EXITING MCTS BACKPROPOGATION"); }
private void PrintTreeHelper(SkyNetNode curNode, int lev) { if (curNode.winCnt / curNode.visitCnt < 1.0f) { Console.Write("\n Level: " + lev.ToString() + "\n" + curNode.ToString()); } int nxtlev = lev + 1; foreach (SkyNetNode child in curNode.children) { PrintTreeHelper(child, nxtlev); } }
public SkyNetNode(GameMove move, SkyNetNode prevNode, bool playerOne, string boardHash, string hand) { this.move = move; this.parent = prevNode; this.children = new List <SkyNetNode>(); this.playerOne = playerOne; this.terminal = false; this.boardHash = boardHash; this.hand = hand; this.winCnt = 1; this.visitCnt = 1; this.level = parent.level + 1; }
private void updateRootList(SkyNetNode newRoot) { int oldInd = skyNetTreeRoots.IndexOf(newRoot); if (oldInd >= 0) { MergeTrees(skyNetTreeRoots[oldInd], newRoot); } else { skyNetTreeRoots.Add(newRoot); } }
public SkyNetNode(string boardHash, bool playerOne, string hand) { this.move = null; this.parent = null; this.children = new List <SkyNetNode>(); this.playerOne = playerOne; this.boardHash = boardHash; this.hand = hand; this.terminal = false; this.winCnt = 1; this.visitCnt = 1; this.level = 0; }
public void Test(object obj) { object[] objArr = obj as object[]; int numGames = (int)objArr[0]; int i = (int)objArr[1]; int numPlaythroughs = (int)objArr[2]; int bundleNum = (int)objArr[3]; Log(i, "STARTING", bundleNum, numGames, numPlaythroughs); IGame game = new Game(constDecks[i]); MCTSkyNet squishyThought = new MCTSkyNet(game, numPlaythroughs, 5.0f, i, bundleNum, numGames); bool curBoardTerminal = false; int moveCnt = 0; SkyNetNode gameNode = squishyThought.GetRoot(); while (!curBoardTerminal) { SkyNetNode picked = squishyThought.PickOfficialMove(game, gameNode, numPlaythroughs, i, moveCnt); //Debug.Assert(picked.playerOne == game.isPlayerOneTurn()); MakeMove(game, picked.move); //Console.Write(gameNode.ToString()); moveCnt++; //Console.WriteLine(moveCnt); //float winRate = picked.visitCnt == 0 ? 0 : (picked.winCnt / picked.visitCnt); //string winPercent = winRate.ToString(); //Log(i, String.Format("Move: {0}", moveCnt), bundleNum, numGames, numPlaythroughs); //Log(i, String.Format("Move: {0} -- Win Rate: {1}", moveCnt, winPercent), bundleNum, numGames, numPlaythroughs); if (picked.isTerminal()) { curBoardTerminal = true; int winningPlayer = picked.playerOne ? 1 : 2; Log(i, String.Format("ENDING -- PLAYER {0} WIN -- MOVES {1}", winningPlayer, moveCnt), bundleNum, numGames, numPlaythroughs); continue; } else if (moveCnt >= maxMoves) { curBoardTerminal = true; Log(i, "GAME ENDING -- STALEMATE -- MOVES " + moveCnt.ToString(), bundleNum, numGames, numPlaythroughs); continue; } //updateRootList(squishyThought.GetRoot()); gameNode = picked; } //updateRootList(squishyThought.GetRoot()); Save(squishyThought.GetRoot(), bundleNum, numGames, numPlaythroughs); }
public void MCTSSingleIteration() { SkyNetNode curNode = rootNode; while (curNode != null) //while the node has children { curNode = MCTSSelect(curNode); } MCTSExpand(curNode); SkyNetNode pickedChild = MCTSSelect(curNode); bool playerOneWin = MCTSRandSimPlayout(pickedChild); MCTSBackpropWin(pickedChild, playerOneWin); }
private void MCTSBackpropWin(SkyNetNode endNode, bool playerOneWin, bool stalemate, int iterNum) { rootMut.WaitOne(); DebugPrint("ENTERING MCTS BACKPROPOGATION -- " + iterNum.ToString() + "\n"); SkyNetNode cur = endNode; while (cur != null) { cur.incWinAndVisit(playerOneWin, stalemate); //DebugPrint(cur.ToString()); cur = cur.parent; } rootMut.ReleaseMutex(); DebugPrint("EXITING MCTS BACKPROPOGATION -- " + iterNum.ToString() + "\n"); }
// private void TrainOfThought(object stateInfo) // { // IGame game = constGame.CopyGame(); // MCTSkyNet squishyThought = new MCTSkyNet(game, numPlayouts, 5.0f); // Debug.Assert(game.isPlayerOneTurn() != squishyThought.GetRoot().playerOne); // bool curBoardTerminal = false; // int moveCnt = 0; // SkyNetNode gameNode = squishyThought.GetRoot(); // while (!curBoardTerminal && moveCnt < 100) // { // //game.getBoard().PrintBoard(); // //Console.WriteLine(game.isPlayerOneTurn()); // //Console.WriteLine(gameNode.ToString()); // //gameNode = squishyThought.PickOfficialMove(game, gameNode); // Debug.Assert(gameNode.playerOne == game.isPlayerOneTurn()); // // String[][] bStringArr = game.getBoardAsString(game.getBoard(), game.isPlayerOneTurn()); // // for (int i = 0; i < bStringArr.Length; i++) // // { // // string toPrint = ""; // // for (int j = 0; j < bStringArr[i].Length; j++) // // { // // toPrint += bStringArr[i][j]; // // } // // Console.WriteLine(toPrint); // // } // if (gameNode.isTerminal()) // { // curBoardTerminal = true; // int winningPlayer = gameNode.playerOne ? 1 : 2; // Console.WriteLine(String.Format("Game Ended. Player {0} wins", winningPlayer)); // continue; // } // MakeMove(game, gameNode.move); // Console.Write(gameNode.ToString()); // moveCnt++; // Console.WriteLine(moveCnt); // } // updateRootList(squishyThought.GetRoot()); // } // private void updateRootList(SkyNetNode newRoot) // { // rootMut.WaitOne(); // int oldInd = skyNetTreeRoots.IndexOf(newRoot); // if (oldInd >= 0) // { // MergeTrees(skyNetTreeRoots[oldInd], newRoot); // } // else // { // skyNetTreeRoots.Add(newRoot); // int cnt = RootMap.Count; // RootMap.Add(newRoot.boardHash + newRoot.hand, cnt); // } // rootMut.ReleaseMutex(); // } private void MergeTrees(SkyNetNode oldRoot, SkyNetNode newRoot) { oldRoot.visitCnt += newRoot.visitCnt; oldRoot.winCnt += newRoot.winCnt; foreach (SkyNetNode newchild in newRoot.children) { int existInd = oldRoot.children.IndexOf(newchild); if (existInd != -1) { MergeTrees(oldRoot.children[existInd], newchild); } else { oldRoot.children.Add(newchild); } } }
public void MCTSSingleIterationThreaded(object obj, int moveCnt) { object[] objArr = obj as object[]; IGame curGame = (IGame)objArr[0]; SkyNetNode gameNode = (SkyNetNode)objArr[1]; int iterNum = (int)objArr[2]; //Console.WriteLine(String.Format("ENTERING ITERATION -- {0}", iterNum)); MCTSExpand(curGame, gameNode, iterNum); SkyNetNode pickedChild = MCTSSelect(gameNode, iterNum, moveCnt); bool stalemate = false; bool playerOneWin = MCTSRandSimPlayout(curGame, pickedChild, ref stalemate, iterNum); MCTSBackpropWin(pickedChild, playerOneWin, stalemate, iterNum); //RLBrain.Save(this.GetRoot()); //Console.WriteLine(String.Format("EXITING ITERATION -- {0}", iterNum)); }