public override double rollOut() { this.s = 0; DeterministicNode tmp = new DeterministicNode(this.board.getBoardState(), null, NODE.NONE, Constant.NONE, Constant.NONE); while (tmp.board.isEnd() == END_STATE.CONTINUE) { this.s += 1; CESPFMove tmpMove = tmp.board.CESPF(); if (tmpMove.isFlippingAction()) { tmp.board.flip(tmpMove.move.from.row, tmpMove.move.from.column); } else { tmp.board.move(tmpMove.move.from.row, tmpMove.move.from.column, tmpMove.move.to.row, tmpMove.move.to.column); } } END_STATE end = tmp.board.isEnd(); if (end == END_STATE.DRAW) { return(0.5); } else if (DeterministicNode.side == (int)end) { return(1); } return(0); }
public override void expand() { int actionLength = this.board.getCountActions(); if (actionLength != 0) { NODE currentType; if (board.sideToMove != side) { currentType = NODE.MIN; } else { currentType = NODE.MAX; } children = new Node[actionLength]; List <Actions> tmp = this.board.getActions(); int index = 0; for (int i = 0; i < tmp.Count; i++) { if (tmp[i].action == ACTION.MOVE) { DeterministicActions action = (DeterministicActions)tmp[i]; int length = action.to.Count; for (int x = 0; x < length; x++) { BoardState tmpBoardState = this.board.getBoardState(); this.board.move(action.from.row, action.from.column, action.to[x].row, action.to[x].column); children[index] = new DeterministicNode(this.board.getBoardState(), new Move(action.from, action.to[x]), currentType, Constant.NONE, Constant.NONE); this.board.restoreBoardState(tmpBoardState); index++; } } else { NondeterministicActions action = (NondeterministicActions)tmp[i]; NondeterministicNode tmpNode = new NondeterministicNode(action.probability, new Move(action.position, action.position), currentType); tmpNode.children = new DeterministicNode[action.probability.Count]; for (int x = 0; x < action.piece.Count; x++) { BoardState tmpBoardState = this.board.getBoardState(); Position tmpPosition = this.board.getFlippedPositionByPiece(action.piece[x]); //temukan real position this.board.switchFlippedPieceByPosition(tmpPosition.row, tmpPosition.column, action.position.row, action.position.column); //pindahkan dari real position ke position yang diinginkan this.board.flip(action.position.row, action.position.column); //buka piece tmpNode.children[x] = new DeterministicNode(this.board.getBoardState(), new Move(action.position, action.position), currentType, action.piece[x], action.probability[x]); this.board.restoreBoardState(tmpBoardState); } children[index] = tmpNode; index++; } } } }
public Node startNMCTS() { taskQueue jlhParallelThread = new taskQueue(base.jlhParallel); Task <DeterministicNode>[] searchTree = new Task <DeterministicNode> [base.jlhParallel]; for (int i = 0; i < base.jlhParallel; i++) { searchTree[i] = jlhParallelThread.enqueueReturn(move); } //sum winrate nondeterministic node for (int i = 0; i < base.jlhParallel; i++) { for (int j = 0; j < searchTree[i].Result.children.Length; j++) { if (searchTree[i].Result.children[j] is NondeterministicNode) { ((NondeterministicNode)searchTree[i].Result.children[j]).sumWinRate(); } } } //sum total result = searchTree[0].Result; for (int i = 1; i < base.jlhParallel; i++) { result.nVisits += searchTree[i].Result.nVisits; result.winRate += searchTree[i].Result.winRate; for (int j = 0; j < searchTree[i].Result.children.Length; j++) { result.children[j].nVisits += searchTree[i].Result.children[j].nVisits; result.children[j].winRate += searchTree[i].Result.children[j].winRate; } } Node maxWinRate = result.children[0]; for (int i = 1; i < result.children.Length; i++) { if (maxWinRate.winRate <= result.children[i].winRate) { maxWinRate = result.children[i]; } } jlhParallelThread.Dispose(); return(maxWinRate); }
private DeterministicNode move() { if (base.isShowConsole) { Console.WriteLine("EXECUTE TASK : " + Task.CurrentId + ", ON THREAD : " + System.Threading.Thread.CurrentThread.ManagedThreadId); } DeterministicNode searchTree = new DeterministicNode(this.board.getBoardState(), null, NODE.NONE, Constant.NONE, Constant.NONE); searchTree.expand(); searchTree.updateStatus(searchTree.rollOut(), searchTree.s); timer.Start(); while (timer.Elapsed.TotalSeconds <= base.wktThinking) { //if (base.isVerboseRunning) //{ //Console.WriteLine("Left Time : " + (wktThinking - timer.Elapsed.TotalSeconds)); //} searchTree.selectAction(); } return(searchTree); }
public void setPGLValue() { DeterministicNode tmpNode = new DeterministicNode(this.board.getBoardState(), null, NODE.NONE, Constant.NONE, Constant.NONE); DeterministicNode.side = this.sideToMove; double x = 0; if (base.isShowConsole) { openConsole(); Console.WriteLine("\nSET PGL VALUE : 500 Kali"); } for (int i = 0; i < 500; i++) { tmpNode.rollOut(); x += tmpNode.s; } Node.PGL = x / 500; if (base.isShowConsole) { Console.WriteLine("SELESAI SET PGL VALUE"); Console.WriteLine("====================="); } }