public int RootAlphaBeta(int alpha, int beta, Board board, int depth) { Stopwatch s = new Stopwatch(); s.Start(); Board bCopy = board; int[] moves = bCopy.GetInterestingMoves(); if (moves.Length == 0) { return((board.width * board.width) / 2); } int bestId = 0; int color = board.blackTurn ? 1 : -1; string deb = ""; for (int i = 0; i < moves.Length; i++) { bCopy = new Board(board); bCopy.ChangeSquare(moves[i]); bCopy.EndTurn(); int score = -AlphaBeta(-beta, -alpha, bCopy, depth - 1, color); if (score > alpha) { alpha = score; bestId = i; deb += "Move: " + moves[i].ToString() + " has value " + score.ToString() + ".\n "; } } s.Stop(); deb += "\n\n Execution took " + s.ElapsedMilliseconds.ToString() + " miliseconds."; board.DebugWrite(deb); return(moves[bestId]); }
public int AlphaBetaOptimized(int alpha, int beta, Board b, int depth, int color, List <int> movesLast) { Board bCopy = b; if (depth == 0) { return(EvaluateBoard(bCopy) * color); } List <int> moves; if (movesLast != null) { moves = movesLast; } else { moves = new List <int>(bCopy.GetInterestingMoves()); } for (int i = 0; i < moves.Count; i++) { bCopy = new Board(b); if (bCopy.board[moves[i]] != 0) { continue; } bCopy.ChangeSquare(moves[i]); color = bCopy.blackTurn ? -1 : 1; int value = EvaluateBoard(bCopy) * color; if (value > 9000) { return(-value * depth); } else if (value < -9000) { return(-value * depth); } bCopy.EndTurn(); List <int> movesCopy = new List <int>(moves); int[] movesToAdd = FindNewMoves(bCopy, bCopy.lastMove); for (int j = 0; j < movesToAdd.Length; j++) { if (!movesCopy.Contains(movesToAdd[j])) { movesCopy.Add(movesToAdd[j]); } } int score = -AlphaBetaOptimized(-beta, -alpha, bCopy, depth - 1, color, movesCopy); if (beta != -2147483648 && score >= beta) { return(beta); } if (score > alpha) { alpha = score; } } return(alpha); }
public void AlphaBetaFromMoves(Board board, int depth, int[] moves) { if (moves.Length == 0) { lock (locker){ results.Add(new KeyValuePair <int, int>(-1, -1)); } return; } int alpha = int.MinValue; int beta = int.MaxValue; Board bCopy = board; int bestId = 0; int color = board.blackTurn ? 1 : -1; for (int i = 0; i < moves.Length; i++) { bCopy = new Board(board); bCopy.ChangeSquare(moves[i]); bCopy.EndTurn(); int score; if (depth > 5) { score = -AlphaBetaOptimized(-beta, -alpha, bCopy, depth - 1, color, null); } else { score = -AlphaBeta(-beta, -alpha, bCopy, depth - 1, color); } if (score > alpha) { alpha = score; bestId = i; } } lock (locker){ results.Add(new KeyValuePair <int, int>(moves[bestId], alpha)); } }
public int[] FindMoves(Board state, int additionalDepth) { List <int> moves = new List <int>(state.GetInterestingMoves()); //Go through the moves and remove the real bad ones for (int i = moves.Count - 1; i >= 0; i--) { Board copy = new Board(state); int alpha = int.MinValue; int beta = int.MaxValue; copy.ChangeSquare(moves[i]); copy.EndTurn(); int win = copy.CheckWin(copy.lastMove); if ((win == 1 && state.blackTurn) || (win == 2 && !state.blackTurn)) { return(new int[] { moves[i] }); } int color = copy.blackTurn ? 1 : -1; int value = AlphaBeta(alpha, beta, copy, additionalDepth, color); //Console.WriteLine("move " + moves[i] + " val " + value); //Console.Read(); if (value > 10000) { moves.RemoveAt(i); } else if (value < -10000) { return(new int[] { moves[i] }); } } if (moves.Count == 0) { return(state.GetInterestingMoves()); } return(moves.ToArray()); }
public int AlphaBeta(int alpha, int beta, Board b, int depth, int color) { Board bCopy = b; if (depth == 0) { return(EvaluateBoard(bCopy) * color); } int[] moves = bCopy.GetInterestingMoves(); for (int i = 0; i < moves.Length; i++) { bCopy = new Board(b); bCopy.ChangeSquare(moves[i]); color = bCopy.blackTurn ? -1 : 1; int value = EvaluateBoard(bCopy) * color; if (value > 9000) { return(-value * depth); } else if (value < -9000) { return(-value * depth); } bCopy.EndTurn(); int score = -AlphaBeta(-beta, -alpha, bCopy, depth - 1, color); if (beta != -2147483648 && score >= beta) { return(beta); } if (score > alpha) { alpha = score; } } return(alpha); }
public int MonteCarloSearch(Board rootState, double searchTimer) { //Check if we can find a winning move in one move string deb = ""; if (true) { int winCheck = GetHighestValueMove(rootState, 1); if (winCheck == (rootState.width * rootState.width) / 2) { return((rootState.width * rootState.width) / 2); } Board copy = new Board(rootState); copy.ChangeSquare(winCheck); int value = rootState.blackTurn ? EvaluateBoard(copy) : -EvaluateBoard(copy); deb += "Highest 1 ply value move is: " + winCheck.ToString() + ", value " + value.ToString() + ".\n "; if (value > 9999) { rootState.DebugWrite(deb); return(winCheck); } } Node root = new Node(rootState.lastSquare, null, rootState, 1); Stopwatch s = new Stopwatch(); s.Start(); while (s.Elapsed.Seconds < searchTimer) { Node node = root; Board state = new Board(rootState); //Select while (node.untriedMoves.Count == 0 && node.nodes.Count != 0) { node = NodeSelection(node); state.ChangeSquare(node.move); state.EndTurn(); } //Expand if (node.untriedMoves.Count != 0) { int move = node.GetRandomMove(); state.ChangeSquare(move); state.EndTurn(); node = node.AddChild(move, state); } //Rollout int lastMove = node.move; while (EvaluateBoard(state) == 0) { //int move = RootAlphaBeta(int.MinValue, int.MaxValue, state, 2); int move = GetHighestValueMove(state, 1); state.ChangeSquare(move); state.EndTurn(); lastMove = move; } //Backpropagate int result = state.CheckWin(lastMove); while (node != null) { node.games++; if (result == -1) { node.wins += 0.4; } else if ((result == 1 && rootState.blackTurn) || (result == 2 && !rootState.blackTurn)) { node.wins += 1; } else { node.wins += 0; } node = node.parent; } } int bestI = 0; double bestValue = double.MinValue; for (int i = 0; i < root.nodes.Count; i++) { double val = root.nodes[i].games * (root.nodes[i].wins / root.nodes[i].games); if (val > bestValue) { deb += "Move: " + root.nodes[i].move.ToString() + " has Wins " + root.nodes[i].wins.ToString("0.0") + ", games " + root.nodes[i].games.ToString() + ", = " + (root.nodes[i].wins / root.nodes[i].games).ToString("0.000") + ".\n "; bestI = i; bestValue = val; } } rootState.DebugWrite(deb); //rootState.DebugWrite("Done finding move from " + root.nodes.Count.ToString() + " available."); return(root.nodes[bestI].move); }