public static void Replace(MoveList moves, PatternFunctionParameters <int> patternFunctionParameters) { double lValue = moves.GetValue(patternFunctionParameters[0]); moves.RemoveMove(patternFunctionParameters[0]); moves.SetMinValue(patternFunctionParameters[1], lValue); // redistribution (limited) }
public void UpdateMoveList(MoveList moves) { foreach (PatternHit lPatternHit in Patterns) { lPatternHit.Pattern.PatternCompiled.Execute(Board, Player, lPatternHit.Origin, lPatternHit.Transformation, moves); } }
public void Execute(GoBoard goBoard, Coordinate originPoint, int transform, MoveList moves) { foreach (PatternActionOperand lPatternActionOperand in Code) { lPatternActionOperand.Execute(goBoard, originPoint, transform, moves); } }
/// <summary> /// Prunes moves from the list. /// </summary> /// <param name="moves">The moves.</param> public void PruneMoveList(MoveList moves) { if ((Options.PrunePassMove) && (moves.Count > 2)) { moves.RemoveMove(CoordinateSystem.PASS); } return; }
/// <summary> /// Gets a list of legal moves. /// </summary> /// <param name="color">The color.</param> /// <returns></returns> public MoveList GetMoveList(Color playerToMove, bool forceEndGameMoves) { MoveList lMoves = new MoveList(Board.BoardSize); if (!forceEndGameMoves) { for (int lMove = 0; lMove < Board.Coord.BoardArea; lMove++) if (Board.IsLegal(lMove, playerToMove)) { SafetyStatus lSafetyStatus = Board.GetSafetyStatus(lMove); if (lSafetyStatus.IsUndecided || (lSafetyStatus.IsUnsurroundable && !lSafetyStatus.IsDame)) lMoves.Add(lMove); } lMoves.Add(CoordinateSystem.PASS); return lMoves; } // during the very final end game - when players fill dame and capture dead stones for (int lMove = 0; lMove < Board.Coord.BoardArea; lMove++) { SafetyStatus lSafetyStatus = Board.GetSafetyStatus(lMove); if ((lSafetyStatus.IsUnsurroundable) || (lSafetyStatus.IsDame)) if (Board.IsLegal(lMove, playerToMove)) { if (lSafetyStatus.IsUnsurroundable) lMoves.Add(lMove); else if (lSafetyStatus.IsDame) lMoves.Add(lMove); } } if (lMoves.Count != 0) return lMoves; for (int lMove = 0; lMove < Board.Coord.BoardArea; lMove++) { SafetyStatus lSafetyStatus = Board.GetSafetyStatus(lMove); if ((lSafetyStatus.IsDead) && (Board.Cells[lMove].Color == playerToMove.Opposite)) foreach (int lMove2 in ((GoBlock)Board.Cells[lMove].Block).Liberties) if (Board.IsLegal(lMove2, playerToMove)) lMoves.Add(lMove2); } // just in case / should still be fast lMoves.Add(CoordinateSystem.PASS); return lMoves; }
protected void Think(Color playerToMove) { MoveList = new MoveList(Board.BoardSize); int lBestValue = Search(playerToMove, SearchOptions.MaxPly, 0); SearchStatus.BestMove = MoveList.GetBestMove(); SearchStatus.BestValue = lBestValue; SearchStatus.CurrentPly = SearchOptions.MaxPly; SearchStatus.MaxPly = SearchOptions.MaxPly; SearchStatus.PercentComplete = 100; }
public void Execute(GoBoard goBoard, Coordinate originPoint, int transform, MoveList moves) { PatternFunctionParameters <int> lPatternFunctionParameters = new PatternFunctionParameters <int>(); foreach (Coordinate lCoordinate in Parameters) { Coordinate lCoordinate2 = originPoint + (lCoordinate - Origin).Transform(transform); lPatternFunctionParameters.Add(goBoard.Coord.At(lCoordinate2.X, lCoordinate2.Y)); } Function(moves, lPatternFunctionParameters); }
public MoveList SimpleEndGameSearch(Color playerToMove) { MoveList lMoveList = SimpleSearch(playerToMove); if ((lMoveList.Count == 1) && (lMoveList[0] == CoordinateSystem.PASS)) { Console.Error.WriteLine("End Game Extended:"); lMoveList = new MoveList(Board.BoardSize); lMoveList.Add(GetEndGameMove(Board, playerToMove)); } return(lMoveList); }
public void Execute(GoBoard goBoard, Coordinate originPoint, int transform, MoveList moves) { PatternFunctionParameters<int> lPatternFunctionParameters = new PatternFunctionParameters<int>(); foreach (Coordinate lCoordinate in Parameters) { Coordinate lCoordinate2 = originPoint + (lCoordinate - Origin).Transform(transform); lPatternFunctionParameters.Add(goBoard.Coord.At(lCoordinate2.X, lCoordinate2.Y)); } Function(moves, lPatternFunctionParameters); }
public MoveList SimpleSearch(Color playerToMove, bool endGame) { SearchOptions lSearchOptions = GetSearchOptions(playerToMove); lSearchOptions.IncludeEndGameMoves = endGame; if (endGame) { lSearchOptions.UsePatterns = false; } Board.Dump(); Console.Error.WriteLine("Move Search: "); Console.Error.WriteLine("Max Level: " + lSearchOptions.MaxPly.ToString() + " - Max Time: " + lSearchOptions.MaxSeconds.ToString() + " Alpha: " + lSearchOptions.AlphaValue.ToString() + " Beta: " + lSearchOptions.BetaValue.ToString()); Search.Start(Board, playerToMove, lSearchOptions, SearchMethodType, null); Search.RunUntil(lSearchOptions.MaxSeconds, lSearchOptions.EarlyTimeOut); SearchStatus lSearchStatus = Search.GetStatus(); Console.Error.WriteLine("Best Move: " + Board.Coord.ToString(lSearchStatus.BestMove) + " (" + lSearchStatus.BestValue.ToString() + ")"); Console.Error.WriteLine("Nodes: " + lSearchStatus.Nodes.ToString() + " - " + (lSearchStatus.Nodes / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second "); Console.Error.WriteLine("Evals: " + lSearchStatus.Evals.ToString() + " - " + (lSearchStatus.Evals / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("Total: " + (lSearchStatus.Evals + lSearchStatus.Nodes).ToString() + " - " + ((lSearchStatus.Evals + lSearchStatus.Nodes) / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("TT Hits: " + lSearchStatus.TranspositionTableHits.ToString() + " - " + (lSearchStatus.TranspositionTableHits / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("Time: " + (lSearchStatus.Timer.MilliSecondsElapsed / 1000.0).ToString() + " seconds"); if ((lSearchStatus.BestMove == CoordinateSystem.PASS) && (!endGame) && (!lSearchOptions.IncludeEndGameMoves)) { Console.Error.WriteLine("End Game Search:"); return(SimpleSearch(playerToMove, true)); } if (SearchOptions.PonderOnOpponentsTime) { Search.StartPonder(lSearchStatus.BestMove, playerToMove); } else if (!SearchOptions.ContinueThinkingAfterTimeOut) { Search.RequestStop(); } MoveList lMoveList = new MoveList(Board.BoardSize); lMoveList.Add(lSearchStatus.BestMove, lSearchStatus.BestValue); return(lMoveList); }
public void BestMove() { int lBoardSize = 9; MoveList lMoveList = new MoveList(lBoardSize); lMoveList.Add(CoordinateSystem.AtFromSGF("C4", lBoardSize), 4); lMoveList.Add(CoordinateSystem.AtFromSGF("A6", lBoardSize), 6); lMoveList.Add(CoordinateSystem.AtFromSGF("A5", lBoardSize), 5); lMoveList.Add(CoordinateSystem.AtFromSGF("E1", lBoardSize), 7); lMoveList.Add(CoordinateSystem.AtFromSGF("A3", lBoardSize), 3); lMoveList.Add(CoordinateSystem.AtFromSGF("D2", lBoardSize), 2); Assert.AreEqual(CoordinateSystem.AtFromSGF("E1", lBoardSize), lMoveList.GetBestMove()); lMoveList.QuickSort(); }
public void PrioritizeMoves(MoveList moves, Color playerToMove) { List <int>[] lProtected = new List <int> [2]; lProtected[0] = GoBoardHelper.GetProtectedLiberites(Board, playerToMove); lProtected[1] = GoBoardHelper.GetProtectedLiberites(Board, playerToMove.Opposite); List <int>[] lNeighborsOfProtected = new List <int> [2]; lNeighborsOfProtected[0] = GoBoardHelper.GetNeighbors(Board, lProtected[0]); lNeighborsOfProtected[1] = GoBoardHelper.GetNeighbors(Board, lProtected[1]); foreach (int lMove in moves) { moves.SetValue(lMove, GetMovePriority(lMove, playerToMove, lProtected[0].Contains(lMove), lProtected[1].Contains(lMove), lNeighborsOfProtected[0].Contains(lMove), lNeighborsOfProtected[1].Contains(lMove))); } }
public static bool Execute(string method, MoveList moves, PatternFunctionParameters <int> patternFunctionParameters) { PatternActionFunction lFunction = GetFunction(method, patternFunctionParameters.Count); if (lFunction == null) { return(false); } try { lFunction(moves, patternFunctionParameters); return(true); } catch { return(false); } }
public static void Test(MoveList moves, PatternFunctionParameters<int> patternFunctionParameters) { Console.Error.WriteLine("DEBUG: Test Action!"); }
public static void AntiSuji(MoveList moves, PatternFunctionParameters <int> patternFunctionParameters) { moves.RemoveMove(patternFunctionParameters[0]); }
public static void Test(MoveList moves, PatternFunctionParameters <int> patternFunctionParameters) { Console.Error.WriteLine("DEBUG: Test Action!"); }
/// <summary> /// Sorts the move list. /// </summary> /// <param name="moves">The moves.</param> /// <returns></returns> public void SortMoveList(MoveList moves) { moves.QuickSort(); }
public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta) { ZobristHash lZobristHash = Board.ZobristHash.Clone(); lZobristHash.Mark(playerToMove); int lTryMove = CoordinateSystem.PASS; if (depth > 1) { TranspositionTablePlus.Node lNode = TranspositionTable.Retrieve(lZobristHash); if ((lNode.Flag != TranspositionTablePlus.NodeType.Unknown) && (lNode.Height > 0)) { if ((maxPly - depth) <= lNode.Height) { TranspositionTableHits++; switch (lNode.Flag) { case TranspositionTablePlus.NodeType.Exact: { SearchComplete = false; return(lNode.Value); } case TranspositionTablePlus.NodeType.LowerBound: { alpha = (alpha > lNode.Value) ? alpha : lNode.Value; break; } case TranspositionTablePlus.NodeType.UpperBound: { beta = (beta < lNode.Value) ? beta : lNode.Value; break; } } if (alpha >= beta) { return(lNode.Value); } } lTryMove = lNode.Move; } } if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { if (depth == maxPly) { SearchComplete = false; } NodesEvaluated++; int lEval = SearchInterface.Evaluate(playerToMove); if (lEval <= alpha) { TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.LowerBound, CoordinateSystem.PASS, lZobristHash); } else if (lEval >= beta) { TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.UpperBound, CoordinateSystem.PASS, lZobristHash); } else { TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.Exact, CoordinateSystem.PASS, lZobristHash); } return(lEval); } MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); SearchInterface.PrioritizeMoves(lMoves, playerToMove); if (lTryMove != CoordinateSystem.PASS) { if (lMoves.Contains(lTryMove)) { lMoves.SetValue(lTryMove, Int32.MaxValue); } } if ((SearchOptions.UsePatterns) && (lMoves.Count != 0)) { PatternMap lPatternMap = SearchOptions.PatternDetector.FindPatterns(Board, playerToMove, lMoves.AllMoves); lPatternMap.UpdateMoveList(lMoves); } if (lMoves.Count == 0) { lMoves.Add(CoordinateSystem.PASS); } if ((lMoves.Count == 1) && (lMoves[0] == CoordinateSystem.PASS) && (Board.LastMove == CoordinateSystem.PASS)) { int lEval = SearchInterface.Evaluate(playerToMove); //TranspositionTable.Record(maxPly - depth, lEval, TranspositionTablePlus.NodeType.Exact, CoordinateSystem.PASS, lZobristHash); return(lEval); } if (Nag) { lock (this) { NagNode lNagNode = NagCoordinator.GetResult(depth); if (lNagNode != null) { if (!lNagNode.IsNarrowed()) { Console.Error.WriteLine("*** Pruning *** " + lNagNode.StartDepth.ToString() + "/" + lNagNode.Depth.ToString()); if (lNagNode.Depth == 1) { BestMove = lNagNode.BestMove; NagCoordinator.Abort(depth); return(lNagNode.Result); } SolvedDepth = lNagNode.StartDepth; SolvedValue = lNagNode.Result; NagCoordinator.Abort(depth); return(alpha); } } else { Nag = false; } } } SearchInterface.SortMoveList(lMoves); if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } NagCoordinator.CreateNagPoints(Board, alpha, beta, playerToMove, depth, maxPly, lMoves.Count, 2); int lSuperKoCount = 0; TranspositionTablePlus.NodeType lFlag = TranspositionTablePlus.NodeType.UpperBound; int lBestMove = lMoves[0]; foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAB_ID_TT.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1, -beta, -alpha); Board.Undo(); if (SolvedDepth != -1) { if (SolvedDepth != depth) { return(alpha); } alpha = SolvedValue; BestMove = lMove; SolvedDepth = -1; break; } if (lScore > alpha) { if (depth == 0) { BestMove = lMove; } if (lScore >= beta) { TranspositionTable.Record(maxPly - depth, alpha, TranspositionTablePlus.NodeType.LowerBound, lMove, lZobristHash); NagCoordinator.Abort(depth); return(beta); } alpha = lScore; lFlag = TranspositionTablePlus.NodeType.Exact; lBestMove = lMove; } } } if (lSuperKoCount == lMoves.Count) { NagCoordinator.Abort(depth); return(SearchInterface.Evaluate(playerToMove)); } TranspositionTable.Record(maxPly - depth, alpha, lFlag, lBestMove, lZobristHash); NagCoordinator.Abort(depth); return(alpha); }
/// <summary> /// Gets a list of legal moves. /// </summary> /// <param name="color">The color.</param> /// <returns></returns> public MoveList GetMoveList(Color playerToMove, bool forceEndGameMoves) { MoveList lMoves = new MoveList(Board.BoardSize); if (!forceEndGameMoves) { for (int lMove = 0; lMove < Board.Coord.BoardArea; lMove++) { if (Board.IsLegal(lMove, playerToMove)) { SafetyStatus lSafetyStatus = Board.GetSafetyStatus(lMove); if (lSafetyStatus.IsUndecided || (lSafetyStatus.IsUnsurroundable && !lSafetyStatus.IsDame)) { lMoves.Add(lMove); } } } lMoves.Add(CoordinateSystem.PASS); return(lMoves); } // during the very final end game - when players fill dame and capture dead stones for (int lMove = 0; lMove < Board.Coord.BoardArea; lMove++) { SafetyStatus lSafetyStatus = Board.GetSafetyStatus(lMove); if ((lSafetyStatus.IsUnsurroundable) || (lSafetyStatus.IsDame)) { if (Board.IsLegal(lMove, playerToMove)) { if (lSafetyStatus.IsUnsurroundable) { lMoves.Add(lMove); } else if (lSafetyStatus.IsDame) { lMoves.Add(lMove); } } } } if (lMoves.Count != 0) { return(lMoves); } for (int lMove = 0; lMove < Board.Coord.BoardArea; lMove++) { SafetyStatus lSafetyStatus = Board.GetSafetyStatus(lMove); if ((lSafetyStatus.IsDead) && (Board.Cells[lMove].Color == playerToMove.Opposite)) { foreach (int lMove2 in ((GoBlock)Board.Cells[lMove].Block).Liberties) { if (Board.IsLegal(lMove2, playerToMove)) { lMoves.Add(lMove2); } } } } // just in case / should still be fast lMoves.Add(CoordinateSystem.PASS); return(lMoves); }
public void Execute(GoBoard goBoard, Color player, Coordinate originPoint, int transform, MoveList moves) { PatternActionCode.Execute(goBoard, originPoint, transform, moves); }
protected int Search(Color playerToMove, int maxPly, int depth) { if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); if ((SearchOptions.UsePatterns) && (lMoves.Count != 0)) { PatternMap lPatternMap = SearchOptions.PatternDetector.FindPatterns(Board, playerToMove, lMoves.AllMoves); lPatternMap.UpdateMoveList(lMoves); } if (lMoves.Count == 0) { lMoves.Add(CoordinateSystem.PASS); } if ((lMoves.Count == 1) && (lMoves[0] == CoordinateSystem.PASS) && (Board.LastMove == CoordinateSystem.PASS)) { NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } int lSuperKoCount = 0; int lBest = Int32.MinValue; int lBestMove = CoordinateSystem.PASS; // dummy value foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAlphaBetaIterative.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1); Board.Undo(); if (depth == 0) { MoveList.Add(lMove, lScore); if (lScore > SearchStatus.BestValue) { SearchStatus.UpdateBestMove(lMove, lScore); } Console.Error.WriteLine("# " + MoveList.Count + " - Move: " + Board.Coord.ToString(lMove) + " (" + lScore.ToString() + ")"); } if (lScore > lBest) { lBest = lScore; lBestMove = lMove; } } } if (lSuperKoCount == lMoves.Count) { return(SearchInterface.Evaluate(playerToMove)); } return(lBest); }
public void PrioritizeMoves(MoveList moves, Color playerToMove) { List<int>[] lProtected = new List<int>[2]; lProtected[0] = GoBoardHelper.GetProtectedLiberites(Board, playerToMove); lProtected[1] = GoBoardHelper.GetProtectedLiberites(Board, playerToMove.Opposite); List<int>[] lNeighborsOfProtected = new List<int>[2]; lNeighborsOfProtected[0] = GoBoardHelper.GetNeighbors(Board, lProtected[0]); lNeighborsOfProtected[1] = GoBoardHelper.GetNeighbors(Board, lProtected[1]); foreach (int lMove in moves) moves.SetValue(lMove, GetMovePriority(lMove, playerToMove, lProtected[0].Contains(lMove), lProtected[1].Contains(lMove), lNeighborsOfProtected[0].Contains(lMove), lNeighborsOfProtected[1].Contains(lMove))); }
/// <summary> /// Prunes moves from the list. /// </summary> /// <param name="moves">The moves.</param> public void PruneMoveList(MoveList moves) { if ((Options.PrunePassMove) && (moves.Count > 2)) moves.RemoveMove(CoordinateSystem.PASS); return; }
public MoveList SimpleEndGameSearch(Color playerToMove) { MoveList lMoveList = SimpleSearch(playerToMove); if ((lMoveList.Count == 1) && (lMoveList[0] == CoordinateSystem.PASS)) { Console.Error.WriteLine("End Game Extended:"); lMoveList = new MoveList(Board.BoardSize); lMoveList.Add(GetEndGameMove(Board, playerToMove)); } return lMoveList; }
public static void Replace(MoveList moves, PatternFunctionParameters<int> patternFunctionParameters) { double lValue = moves.GetValue(patternFunctionParameters[0]); moves.RemoveMove(patternFunctionParameters[0]); moves.SetMinValue(patternFunctionParameters[1], lValue); // redistribution (limited) }
public MoveList SimpleSearch(Color playerToMove, bool endGame) { SearchOptions lSearchOptions = GetSearchOptions(playerToMove); lSearchOptions.IncludeEndGameMoves = endGame; if (endGame) lSearchOptions.UsePatterns = false; Board.Dump(); Console.Error.WriteLine("Move Search: "); Console.Error.WriteLine("Max Level: " + lSearchOptions.MaxPly.ToString() + " - Max Time: " + lSearchOptions.MaxSeconds.ToString() + " Alpha: " + lSearchOptions.AlphaValue.ToString() + " Beta: " + lSearchOptions.BetaValue.ToString()); Search.Start(Board, playerToMove, lSearchOptions, SearchMethodType, null); Search.RunUntil(lSearchOptions.MaxSeconds, lSearchOptions.EarlyTimeOut); SearchStatus lSearchStatus = Search.GetStatus(); Console.Error.WriteLine("Best Move: " + Board.Coord.ToString(lSearchStatus.BestMove) + " (" + lSearchStatus.BestValue.ToString() + ")"); Console.Error.WriteLine("Nodes: " + lSearchStatus.Nodes.ToString() + " - " + (lSearchStatus.Nodes / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second "); Console.Error.WriteLine("Evals: " + lSearchStatus.Evals.ToString() + " - " + (lSearchStatus.Evals / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("Total: " + (lSearchStatus.Evals + lSearchStatus.Nodes).ToString() + " - " + ((lSearchStatus.Evals + lSearchStatus.Nodes) / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("TT Hits: " + lSearchStatus.TranspositionTableHits.ToString() + " - " + (lSearchStatus.TranspositionTableHits / (lSearchStatus.Timer.SecondsElapsed != 0 ? lSearchStatus.Timer.SecondsElapsed : 1)).ToString() + " per second"); Console.Error.WriteLine("Time: " + (lSearchStatus.Timer.MilliSecondsElapsed / 1000.0).ToString() + " seconds"); if ((lSearchStatus.BestMove == CoordinateSystem.PASS) && (!endGame) && (!lSearchOptions.IncludeEndGameMoves)) { Console.Error.WriteLine("End Game Search:"); return SimpleSearch(playerToMove, true); } if (SearchOptions.PonderOnOpponentsTime) Search.StartPonder(lSearchStatus.BestMove, playerToMove); else if (!SearchOptions.ContinueThinkingAfterTimeOut) Search.RequestStop(); MoveList lMoveList = new MoveList(Board.BoardSize); lMoveList.Add(lSearchStatus.BestMove, lSearchStatus.BestValue); return lMoveList; }
public void Execute(GoBoard goBoard, Coordinate originPoint, int transform, MoveList moves) { foreach (PatternActionOperand lPatternActionOperand in Code) lPatternActionOperand.Execute(goBoard, originPoint, transform, moves); }
public static bool Execute(string method, MoveList moves, PatternFunctionParameters<int> patternFunctionParameters) { PatternActionFunction lFunction = GetFunction(method, patternFunctionParameters.Count); if (lFunction == null) return false; try { lFunction(moves, patternFunctionParameters); return true; } catch { return false; } }
public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta) { ZobristHash lZobristHash = Board.ZobristHash.Clone(); lZobristHash.Mark(playerToMove); if (depth > 1) { TranspositionTable.Node lNode = TranspositionTable.Retrieve(lZobristHash); if ((lNode.Flag != TranspositionTable.NodeType.Unknown) && ((maxPly - depth) <= lNode.Height)) { switch (lNode.Flag) { case TranspositionTable.NodeType.Exact: { SearchComplete = false; TranspositionTableHits++; return(lNode.Value); } case TranspositionTable.NodeType.LowerBound: { alpha = (alpha > lNode.Value) ? alpha : lNode.Value; break; } case TranspositionTable.NodeType.UpperBound: { beta = (beta < lNode.Value) ? beta : lNode.Value; break; } } if (alpha >= beta) { return(lNode.Value); } } } if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { if (depth == maxPly) { SearchComplete = false; } NodesEvaluated++; int lEval = SearchInterface.Evaluate(playerToMove); TranspositionTable.Record(maxPly - depth, lEval, TranspositionTable.NodeType.Exact, lZobristHash); return(lEval); } PrincipalVariation.SetPVLength(depth); MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); SearchInterface.PrioritizeMoves(lMoves, playerToMove); if ((SearchOptions.UsePatterns) && (lMoves.Count != 0)) { PatternMap lPatternMap = SearchOptions.PatternDetector.FindPatterns(Board, playerToMove, lMoves.AllMoves); lPatternMap.UpdateMoveList(lMoves); } if (lMoves.Count == 0) { lMoves.Add(CoordinateSystem.PASS); } if ((lMoves.Count == 1) && (lMoves[0] == CoordinateSystem.PASS) && (Board.LastMove == CoordinateSystem.PASS)) { PrincipalVariation.UpdatePV(depth, CoordinateSystem.PASS); int lEval = SearchInterface.Evaluate(playerToMove); TranspositionTable.Record(maxPly - depth, lEval, TranspositionTable.NodeType.Exact, lZobristHash); return(lEval); } // follow the principle variation if (FollowPV) { FollowPV = false; int lPVMove = PrincipalVariation.GetMove(depth); if (lPVMove != PrincipalVariation.NO_VALUE) { if (lMoves.Contains(lPVMove)) { lMoves.SetValue(lPVMove, Int32.MaxValue); FollowPV = true; } } } SearchInterface.SortMoveList(lMoves); if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } int lSuperKoCount = 0; TranspositionTable.NodeType lFlag = TranspositionTable.NodeType.UpperBound; foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAB_ID_TT_PVS.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1, -beta, -alpha); Board.Undo(); if (lScore > alpha) { if (lScore >= beta) { TranspositionTable.Record(maxPly - depth, alpha, TranspositionTable.NodeType.LowerBound, lZobristHash); return(lScore); } alpha = lScore; lFlag = TranspositionTable.NodeType.Exact; PrincipalVariation.UpdatePV(depth, lMove); } } } if (lSuperKoCount == lMoves.Count) { return(SearchInterface.Evaluate(playerToMove)); } TranspositionTable.Record(maxPly - depth, alpha, lFlag, lZobristHash); return(alpha); }
public static void AntiSuji(MoveList moves, PatternFunctionParameters<int> patternFunctionParameters) { moves.RemoveMove(patternFunctionParameters[0]); }
public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta) { if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } PrincipalVariation.SetPVLength(depth); MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); if ((SearchOptions.UsePatterns) && (lMoves.Count != 0)) { PatternMap lPatternMap = SearchOptions.PatternDetector.FindPatterns(Board, playerToMove, lMoves.AllMoves); lPatternMap.UpdateMoveList(lMoves); } if (lMoves.Count == 0) { lMoves.Add(CoordinateSystem.PASS); } if ((lMoves.Count == 1) && (lMoves[0] == CoordinateSystem.PASS) && (Board.LastMove == CoordinateSystem.PASS)) { PrincipalVariation.UpdatePV(depth, CoordinateSystem.PASS); NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } SearchInterface.SortMoveList(lMoves); if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } int lSuperKoCount = 0; foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAlphaBetaIterative.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1, -beta, -alpha); Board.Undo(); if (lScore > alpha) { if (lScore >= beta) { return(beta); } alpha = lScore; PrincipalVariation.UpdatePV(depth, lMove); if (depth == 0) { if (lScore > SearchStatus.BestValue) { SearchStatus.UpdateBestMove(lMove, lScore); } Console.Error.WriteLine("Move: " + Board.Coord.ToString(lMove) + " (" + lScore.ToString() + ")"); } } } } if (lSuperKoCount == lMoves.Count) { return(SearchInterface.Evaluate(playerToMove)); } return(alpha); }
public int Search(Color playerToMove, int maxPly, int depth, int alpha, int beta) { if ((depth == maxPly) || ((depth != 0) && (SearchInterface.IsGameOver()))) { if (depth == maxPly) { SearchComplete = false; } NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } PrincipalVariation.SetPVLength(depth); MoveList lMoves = SearchInterface.GetMoveList(playerToMove, SearchOptions.IncludeEndGameMoves); SearchInterface.PruneMoveList(lMoves); SearchInterface.PrioritizeMoves(lMoves, playerToMove); if ((SearchOptions.UsePatterns) && (lMoves.Count != 0)) { PatternMap lPatternMap = SearchOptions.PatternDetector.FindPatterns(Board, playerToMove, MoveList.Randomize(lMoves.AllMoves, SearchOptions.Permutations, depth)); lPatternMap.UpdateMoveList(lMoves); } if (lMoves.Count == 0) { lMoves.Add(CoordinateSystem.PASS); } if ((lMoves.Count == 1) && (lMoves[0] == CoordinateSystem.PASS) && (Board.LastMove == CoordinateSystem.PASS)) { PrincipalVariation.UpdatePV(depth, CoordinateSystem.PASS); NodesEvaluated++; return(SearchInterface.Evaluate(playerToMove)); } // follow the principle variation if (FollowPV) { FollowPV = false; int lPVMove = PrincipalVariation.GetMove(depth); if (lPVMove != PrincipalVariation.NO_VALUE) { if (lMoves.Contains(lPVMove)) { lMoves.SetValue(lPVMove, Int32.MaxValue); FollowPV = true; } } } SearchInterface.SortMoveList(lMoves); if (UpdateStatusFlag) { UpdateStatus(); } if (StopThinkingFlag) { Stop(); } int lSuperKoCount = 0; foreach (int lMove in lMoves) { NodesSearched++; bool lPlayed = Board.PlayStone(lMove, playerToMove, true); if (!lPlayed) { throw new ApplicationException("SearchMethodAB_ID_PVS.cs: You hit a bug!"); } if ((CheckSuperKo) && (Board.IsSuperKo())) { lSuperKoCount++; Board.Undo(); } else { int lScore = -Search(playerToMove.Opposite, maxPly, depth + 1, -beta, -alpha); Board.Undo(); if (lScore > alpha) { if (lScore >= beta) { return(lScore); } alpha = lScore; PrincipalVariation.UpdatePV(depth, lMove); } } } if (lSuperKoCount == lMoves.Count) { return(SearchInterface.Evaluate(playerToMove)); } return(alpha); }