public Brain(StaticEvaluator staticEvaluator) { _StaticEvaluator = staticEvaluator; for (int i = 0; i < _PlyInfo.Length; i++) { _PlyInfo[i] = new PlyInfo(); } }
public void AddPosition(Board board, Move bestMove, int score, int searchDepth, int currentPly, Sides currentSide, HashEntryTypes type) { score = StaticEvaluator.RemovePlyDependence(score); UInt64 hashKey = currentSide == Sides.White ? board.HashKey : ~board.HashKey; UInt64 globalTableIndex = hashKey % (UInt64)_GlobalTable.Length; UInt64 localTableIndex = hashKey % (UInt64)_LocalTable.Length; HashEntry globalEntry = _GlobalTable[globalTableIndex]; if (globalEntry.IsStale) { _GlobalTable[globalTableIndex] = new HashEntry(hashKey, bestMove, score, searchDepth, type); } else { bool isMoreValuable = searchDepth > globalEntry.SearchDepth || searchDepth == globalEntry.SearchDepth && type == HashEntryTypes.Exact; if (globalEntry.HashKey == hashKey) { bool improvesBound = searchDepth == globalEntry.SearchDepth && (type == HashEntryTypes.LowerBound && globalEntry.Type == HashEntryTypes.LowerBound && score > globalEntry.Score || type == HashEntryTypes.UpperBound && globalEntry.Type == HashEntryTypes.LowerBound && score < globalEntry.Score); if (isMoreValuable || improvesBound) { _GlobalTable[globalTableIndex] = new HashEntry(hashKey, bestMove, score, searchDepth, type); } } else { if (isMoreValuable) { _GlobalTable[globalTableIndex] = new HashEntry(hashKey, bestMove, score, searchDepth, type); _LocalTable[localTableIndex] = globalEntry; } else { _LocalTable[localTableIndex] = new HashEntry(hashKey, bestMove, score, searchDepth, type); } } } }
HashEntryTypes LookupPosition(HashEntry[] table, UInt64 hashKey, int desiredDepth, int currentPly, Sides currentSide, ref int alpha, ref int beta) { UInt64 tableIndex = hashKey % (UInt64)table.Length; if (table[tableIndex].HashKey == hashKey) { table[tableIndex].IsStale = false; int score = StaticEvaluator.AddPlyDependence(table[tableIndex].Score, currentPly); if (table[tableIndex].SearchDepth < desiredDepth) { return(HashEntryTypes.Junk); } switch (table[tableIndex].Type) { case HashEntryTypes.LowerBound: if (score >= beta) { beta = score; return(HashEntryTypes.LowerBound); } break; case HashEntryTypes.Exact: alpha = score; return(HashEntryTypes.Exact); case HashEntryTypes.UpperBound: if (score <= alpha) { alpha = score; return(HashEntryTypes.UpperBound); } break; } } return(HashEntryTypes.Junk); }
protected override void AnalyzeOurBoard() { _NodesEvaluated = 0; _TranspositionTable.SetStale(); int depth = 2; int score = 0; while (true) { score = Search(depth, score); if (!_AreWeThinking) { break; } _Score = score; _BestMove = _PlyInfo[0].PrincipalVariation[0]; _PrincipalVariation.Clear(); for (int i = 0; i < _PlyInfo[0].PrincipalVariationLength; i++) { _PrincipalVariation.Add(_PlyInfo[0].PrincipalVariation[i]); } ReportSearchInformation(depth); if (StaticEvaluator.IsMate(_Score)) { break; } StuffPrincipalVariationIntoTranspositionTable(0, _OurSide, depth); depth++; } }
protected int AlphaBetaSearch(int alpha, int beta, int remainingDepth, int currentPly, Sides currentSide) { _NodesEvaluated++; _PlyInfo[currentPly].PrincipalVariationLength = currentPly; if (currentPly >= PlyInfo.MaxPly) { return(beta); } switch (_TranspositionTable.LookupPosition(_ScratchBoard, remainingDepth, currentPly, currentSide, ref alpha, ref beta)) { case HashEntryTypes.LowerBound: return(beta); case HashEntryTypes.Exact: Move transpositionTableMove = _TranspositionTable.GetBestMove(_ScratchBoard, currentSide); if (!transpositionTableMove.Equals(Move.Empty)) { UpdatePrincipalVariation(transpositionTableMove, currentPly); } return(alpha); case HashEntryTypes.UpperBound: return(alpha); } if (remainingDepth <= 0) { return(QuiescenceSearch(alpha, beta, currentPly, currentSide)); } int pruneScore; if (CanPrune(alpha, beta, remainingDepth, currentPly, currentSide, out pruneScore)) { return(pruneScore); } List <Move> moves; if (GenerateMoves(currentPly, currentSide, out moves) == MoveGenerationResults.Mated) { int mateScore = -StaticEvaluator.MateScoreFromPly(currentPly); _TranspositionTable.AddPosition(_ScratchBoard, Move.Empty, mateScore, remainingDepth, currentPly, currentSide, HashEntryTypes.Exact); return(mateScore); } _PlyInfo[currentPly].Board.CopyFrom(_ScratchBoard); int originalAlpha = alpha; foreach (Move move in moves) { if (!_AreWeThinking) { return(alpha); } if (_ScratchBoard.MakeMove(move) == MakeMoveResults.UndoMove) { UndoMove(currentPly); continue; } int score = -AlphaBetaSearch(-beta, -alpha, remainingDepth - 1, currentPly + 1, Board.OtherSide(currentSide)); UndoMove(currentPly); if (score >= beta) { SetKiller(move, currentPly); _TranspositionTable.AddPosition(_ScratchBoard, move, score, remainingDepth, currentPly, currentSide, HashEntryTypes.LowerBound); return(score); } if (score > alpha) { alpha = score; UpdatePrincipalVariation(move, currentPly); } } if (alpha == originalAlpha) { _TranspositionTable.AddPosition(_ScratchBoard, Move.Empty, alpha, remainingDepth, currentPly, currentSide, HashEntryTypes.UpperBound); } else { SetKiller(_PlyInfo[currentPly].PrincipalVariation[currentPly], currentPly); _TranspositionTable.AddPosition(_ScratchBoard, _PlyInfo[currentPly].PrincipalVariation[currentPly], alpha, remainingDepth, currentPly, currentSide, HashEntryTypes.Exact); } return(alpha); }
public BasicAlphaBetaBrain(StaticEvaluator staticEvaluator, int memoryCapacity_MB) : base(staticEvaluator, memoryCapacity_MB) { }
public NullMoveBrain(StaticEvaluator staticEvaluator, int memoryCapacity_MB) : base(staticEvaluator, memoryCapacity_MB) { }
public MTDfBrain(StaticEvaluator staticEvaluator, int memoryCapacity_MB) : base(staticEvaluator, memoryCapacity_MB) { }
public TranspositionTableBrain(StaticEvaluator staticEvaluator, int memoryCapacity_MB) : base(staticEvaluator) { _TranspositionTable = new TranspositionTable(memoryCapacity_MB * 1024 * 1024); }