public void Add(TranspositionEntry entry) { ulong index = ItemHashFunction(entry.Hash); TranspositionEntry tpEntry = _items[index]; if (tpEntry == null) { Count++; _items[index] = entry; } else //Collision { string tracemsg = ""; string tracemsdgtype = ""; if (entry != null && entry.BestMove != null) { tracemsg = entry.BestMove.Bits.ToString(); } if (entry != null && entry.BestMove != null) { tracemsdgtype = entry.BestMove.GetType().ToString(); } TranspositionTableStatistics.Collisions++; _items[index] = ResolveCollision(tpEntry, entry); } }
public void Add(TranspositionEntry entry) { if (System.IO.File.Exists("stop.now")) { BinaryFormatter bf = new BinaryFormatter(); var stream = File.Create("TranspositionTable_serialize.obj"); bf.Serialize(stream, this); Environment.Exit(0); } ulong index = ItemHashFunction(entry.Hash); TranspositionEntry tpEntry = _items[index]; //Trace.WriteLine( string.Format( "{0} : {1}", index, tpEntry.Hash ) ); if (tpEntry == null) { Count++; _items[index] = entry; //Trace.WriteLine( string.Format( "[TranspositionTable]: Adding {0} : {1}", entry.Move.GetType().ToString(), entry.Move.Bits.ToString() ) ); } else //Collision { Trace.WriteLine(string.Format("[TranspositionTable]: Collision {0}: {1}", entry.Move.GetType().ToString(), entry.Move.Bits.ToString())); _items[index] = ResolveCollision(tpEntry, entry); } }
public TranspositionEntry this[ulong hash] { get { ulong index = ItemHashFunction(hash); TranspositionEntry entry = _items[index]; if (entry == null) { TranspositionTableStatistics.Misses++; } else { TranspositionTableStatistics.Hits++; } return(entry); } }
/// <summary> /// Decides the best move for the player given by the color parameter, with a search /// of the given depth. /// </summary> public static ColoredBitBoard GetBestMove(ChessBoard board, int depth, ChessPieceColors color, GenerateMoveDelegate GenerateMoves, GetMaterialDelegate GetMaterialValue) { Debug.Assert(board != null); Debug.Assert(depth > 0); Debug.Assert(GenerateMoves != null); Debug.Assert(GetMaterialValue != null); //Alpha, have to add one to change symbol later otherwise overflow. double a = int.MinValue + 1; //Beta value. double b = int.MaxValue; double val = 0; ColoredBitBoard bestMove = null; List <ColoredBitBoard> moves = GenerateMoves(board, color); var ttEntry = new TranspositionEntry(board.BoardHash.Key, depth, val, false, EntryType.Exact); foreach (ColoredBitBoard move in moves) { board.Update(move); if (color == ChessPieceColors.Black) { val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.White, GenerateMoves, GetMaterialValue); } else if (color == ChessPieceColors.White) { val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.Black, GenerateMoves, GetMaterialValue); } if (val > a) { a = val; bestMove = move; ttEntry.BestMove = move; ttEntry.Score = a; } board.Undo(); } TranspositionTable.TranspositionCache.Add(ttEntry); return(bestMove); }
public static List <ColoredBitBoard> SortMovesByPV(List <ColoredBitBoard> legalMoves, ChessBoard inputChessBoard, BitBoard blackMoves, BitBoard whiteMoves) { TranspositionEntry entry = TranspositionTable.TranspositionCache[inputChessBoard.BoardHash.Key]; if (entry == null || entry.BestMove == null) { return(legalMoves); } ColoredBitBoard bestmove = entry.BestMove; if (bestmove is PawnBitBoard && ((PawnBitBoard)bestmove).Color == ChessPieceColors.White && legalMoves[0].Color == ChessPieceColors.White) { Debug.Assert(bestmove.Bits != inputChessBoard.WhitePawn.Bits); } ColoredBitBoard bestmoveInLegalMoves = legalMoves.Find(p => p.Equals(bestmove)); if (bestmoveInLegalMoves != null) { legalMoves.Remove(bestmoveInLegalMoves); legalMoves.Insert(0, bestmove); } return(legalMoves); }
/// <summary> /// Implementation of the NegaMax algorithm. /// <param name="board"></param> /// <param name="depth"></param> /// <param name="a"></param> /// <param name="b"></param> /// <param name="color"></param> /// <param name="GenerateMoves"></param> /// <param name="GetMaterialValue"></param> /// <returns></returns> public static double NegaMaxAlgorithm( ChessBoard board, int depth, double a, double b, ChessPieceColors color, GenerateMoveDelegate GenerateMoves, GetMaterialDelegate GetMaterialValue ) { ColoredBitBoard bestMove = null; var hashBeforeTermCondition = board.BoardHash.Key; var termCondition = IsTerminal(board, color, GenerateMoves); Debug.Assert(hashBeforeTermCondition == board.BoardHash.Key); if (termCondition == TerminalConditions.Win || termCondition == TerminalConditions.Draw || depth == 0) { return((int)color * (GetMaterialValue(board))); } else { bool usingTT = false; ulong hash_beforeMove = board.BoardHash.Key; var ttEntry = TranspositionTable.TranspositionCache[board.BoardHash.Key]; if (ttEntry != null && ttEntry.Hash == board.BoardHash.Key && ttEntry.Depth >= depth ) { if (ttEntry.NodeType == EntryType.Alpha && ttEntry.Score <= a) { return(a); } if (ttEntry.NodeType == EntryType.Beta && ttEntry.Score >= b) { return(b); } if (ttEntry.NodeType == EntryType.Exact) { return(ttEntry.Score); } usingTT = true; } TranspositionEntry newEntry = new TranspositionEntry(board.BoardHash.Key, depth, 0, false, EntryType.Alpha); List <ColoredBitBoard> moves = new List <ColoredBitBoard>(); moves = GenerateMoves(board, color); foreach (ColoredBitBoard move in moves) { double val = 0; board.Update(move); var hashBeforeRec = board.BoardHash.Key; if (color == ChessPieceColors.White) { val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.Black, GenerateMoves, GetMaterialValue); } else if (color == ChessPieceColors.Black) { val = -NegaMaxAlgorithm(board, depth - 1, -b, -a, ChessPieceColors.White, GenerateMoves, GetMaterialValue); } Debug.Assert(hashBeforeRec == board.BoardHash.Key); board.Undo(); usingTT = false; if (val >= b) { if (!usingTT) { newEntry.NodeType = EntryType.Beta; newEntry.Score = val; TranspositionTable.TranspositionCache.Add(newEntry); Debug.Assert(hash_beforeMove == board.BoardHash.Key, "Board hash changed during update/undo"); } return(val); } if (val >= a) { a = val; bestMove = move; newEntry.NodeType = EntryType.Exact; } Debug.Assert(hash_beforeMove == board.BoardHash.Key, "Board hash changed during update/undo"); } if (!usingTT) { if (newEntry.NodeType == EntryType.Exact) { newEntry.BestMove = bestMove; } newEntry.Score = a; TranspositionTable.TranspositionCache.Add(newEntry); } return(a); } }
private TranspositionEntry ResolveCollision(TranspositionEntry oldEntry, TranspositionEntry newEntry) { return(newEntry); }