//returns true if AI will win private bool simulatePerfectGame(MCTSNode_QAI currNode) { MCTSNode_QAI bestMove = null; if (currNode.flag[qflags.CHILDHASLOSINGBOARD]) { return(false); } else if (currNode.flag[qflags.CHILDHASWINNINGBOARD]) { return(true); } else if (currNode.flag[qflags.ENDBOARD]) { if (currNode.flag[qflags.OWNER]) { return(currNode.isWinState()); } else { return(currNode.isTie()); } } for (int index = 0; index < currNode.children.Count; index++) { if (currNode.children[index].flag[qflags.OWNER] && (bestMove == null || bestMove.nodePickScore() < currNode.children[index].nodePickScore())) { bestMove = currNode.children[index]; } else if (!currNode.children[index].flag[qflags.OWNER] && (bestMove == null || bestMove.nodePickScore() > currNode.children[index].nodePickScore())) { bestMove = currNode.children[index]; } } return(simulatePerfectGame(bestMove)); }
public Tuple <byte, byte> AIFullTurn_debug(byte givenPiece, byte boardPosition) { MCTSNode_QAI temp = null; byte pieceToGive; byte positionToPlace = 255; if (this.root != null && this.root.flag[qflags.ENDBOARD]) { return(new Tuple <byte, byte>(255, 255)); } if (AITurnUpkeep(givenPiece, boardPosition) == null) { temp = AITurnPart(2000); /*DEBUG*/ Console.WriteLine("\n\nSummary:"); /*DEBUG*/ Console.WriteLine("Counter: "); /*DEBUG*/ Console.WriteLine("Root: " + root.nodeValue + " " + root.score.Item1 + " " + root.score.Item2 + " " + counter); /*DEBUG*/ for (int i = 0; i < root.children.Count; i++) /*DEBUG*/ { /*DEBUG*/ Console.WriteLine("Child" + i + ": " + root.children[i].nodeValue + " " + root.children[i].score.Item1 + " " + root.children[i].score.Item2 + " " + Math.Round((float)root.children[i].nodePickScore(), 4) + " " + Math.Round((float)root.children[i].nodeSimScore(root.score.Item2), 4)); /*DEBUG*/ } this.root = temp; positionToPlace = this.root.nodeValue; temp = AITurnPart(2000); /*DEBUG*/ Console.WriteLine("\n\nSummary:"); /*DEBUG*/ Console.WriteLine("Counter: "); /*DEBUG*/ Console.WriteLine("Root: " + root.nodeValue + " " + root.score.Item1 + " " + root.score.Item2 + " " + counter); /*DEBUG*/ for (int i = 0; i < root.children.Count; i++) /*DEBUG*/ { /*DEBUG*/ Console.WriteLine("Child" + i + ": " + root.children[i].nodeValue + " " + root.children[i].score.Item1 + " " + root.children[i].score.Item2 + " " + Math.Round((float)root.children[i].nodePickScore(), 4) + " " + Math.Round((float)root.children[i].nodeSimScore(root.score.Item2), 4)); /*DEBUG*/ } if (temp != null) { this.root = temp; pieceToGive = this.root.nodeValue; /*DEBUG*/ Console.WriteLine("Selected: " + root.nodeValue + " with score " + root.nodePickScore()); } else { pieceToGive = 0; } time.Stop(); return(new Tuple <byte, byte>(positionToPlace, pieceToGive)); } else { time.Stop(); return(new Tuple <byte, byte>(positionToPlace, this.root.nodeValue)); } }
//Selects best move and returns reference to its noded private MCTSNode_QAI selectBestMove(MCTSNode_QAI currNode) { MCTSNode_QAI selectedMove = null; bool gameWin = false; if (this.difficulty == diff.hard) { bool willWinPerfectGame = false; for (int index = 0; index < currNode.children.Count && !gameWin; index++) { if (!willWinPerfectGame) { if (selectedMove == null) { selectedMove = currNode.children[index]; willWinPerfectGame = simulatePerfectGame(currNode.children[index]); } else { willWinPerfectGame = simulatePerfectGame(currNode.children[index]); if (willWinPerfectGame || selectedMove.nodePickScore() < currNode.children[index].nodePickScore()) { selectedMove = currNode.children[index]; } } } else { if (currNode.children[index].flag[qflags.ENDBOARD]) { selectedMove = currNode.children[index]; gameWin = true; } else if (selectedMove.nodePickScore() < currNode.children[index].nodePickScore()) { if (simulatePerfectGame(currNode.children[index])) { selectedMove = currNode.children[index]; } } } } } else { for (int index = 0; index < currNode.children.Count && !gameWin; index++) { if (compareMove()) { if (selectedMove == null) { selectedMove = currNode.children[index]; } if (currNode.children[index].flag[qflags.ENDBOARD]) { selectedMove = currNode.children[index]; gameWin = true; } else if (selectedMove.nodePickScore() < currNode.children[index].nodePickScore()) { selectedMove = currNode.children[index]; } } } } if (selectedMove == null && currNode.children.Count > 0) { selectedMove = currNode.children[random.Next(0, currNode.children.Count)]; } return(selectedMove); }