public AlphaBetaHashAlgoritm(Field field, OldMoveGenerator moveGenerator = null, Estimator estimator = null, ZobristHashField hashField = null, TranspositionTable transpositionTable = null) { Field = field; MoveGenerator = moveGenerator ?? new OldMoveGenerator(field); Estimator = estimator ?? new Estimator(field); HashField = hashField ?? new ZobristHashField(field, 0); TranspositionTable = transpositionTable ?? new TranspositionTable(field); }
private unsafe float EvaluatePosition(byte depth, Dot player, float alpha, float beta, ulong key, HashSet <int> moves) { float oldAlpha = alpha; Dot nextPlayer = player.NextPlayer(); float score = CheckCollision(player, depth, alpha, beta, key, moves); if (score >= 0) { return(score); } if (depth == 0) { return(Estimator.Estimate(player)); } foreach (var move in moves) { if (Field.MakeMove(move)) { HashField.UpdateHash(); float tmp = -EvaluatePosition((byte)(depth - 1), nextPlayer, -beta, -alpha, HashField.Key, MoveGenerator.GenerateMoves(nextPlayer, moves)); Field.UnmakeMove(); HashField.UpdateHash(); if (tmp > alpha) { TranspositionTable.RecordHash( (byte)depth, tmp, tmp < beta ? enmHashEntryType.Exact : enmHashEntryType.Beta, HashField.Key, (ushort)move); alpha = tmp; if (alpha >= beta) { return(beta); } } } } if (alpha == oldAlpha) { TranspositionTable.RecordHash((byte)depth, alpha, enmHashEntryType.Alpha, HashField.Key, 0); } return(alpha); }
private unsafe float CheckCollision(Dot player, byte depth, float alpha, float beta, ulong key, HashSet <int> moves) { fixed(HashEntry *hashEntry = &TranspositionTable.HashEntries_[key % AiSettings.HashTableSize]) { if (hashEntry->HashKey == key) { if (hashEntry->Depth >= depth) { float score = hashEntry->Score; if (hashEntry->Type == enmHashEntryType.Alpha) { if (score <= alpha) { return(alpha); } /*if (score < beta) * beta = score; * if (beta <= alpha) * return alpha;*/ } else { if (score > alpha) { alpha = score; } if (alpha >= beta) { return(beta); } } } if (hashEntry->Type != enmHashEntryType.Alpha && depth != 0) { if (Field.MakeMove(hashEntry->BestMove)) { HashField.UpdateHash(); float tmp = -EvaluatePosition((byte)(depth - 1), player.NextPlayer(), -beta, -alpha, HashField.Key, MoveGenerator.GenerateMoves(player.NextPlayer(), moves)); Field.UnmakeMove(); HashField.UpdateHash(); if (tmp > alpha) { TranspositionTable.RecordHash(depth, tmp, tmp < beta ? enmHashEntryType.Exact : enmHashEntryType.Beta, key, hashEntry->BestMove); alpha = tmp; if (alpha >= beta) { return(beta); } } } } } } return(-1); }