private static void PrintSearchResult(GameState state, DateTime startTime, AlphaBeta ab, int i, int score) { Console.Write("{0}\t{1}\t{2:0}\t{3}\t", i, score, (DateTime.Now - startTime).TotalMilliseconds / 10, ab.Metrics.Nodes); PrintPV(state.GameBoard, ab); Console.WriteLine(); }
private static void PrintPV(Board b, AlphaBeta ab) { for (int j = 0; j < ab.PvLength[0]; j++) { var m = ab.PrincipalVariation[0, j]; Console.Write("{0} ", m.ToAlegbraicNotation(b)); b.MakeMove(m); } //Walk through the TT table to augment the PV int hashTableMoves = 0; List <ulong> hashKeys = new List <ulong>(); while (true) { //don't let the hashtable send us into a cycle if (hashKeys.Contains(b.HashKey)) { break; } var entry = TranspositionTable.Instance.Read(b.HashKey); if (entry == null || entry.Type != (byte)TranspositionTableEntry.EntryType.PV) { break; } var m = new Move(entry.MoveValue); Console.Write("{0}(HT) ", m.ToAlegbraicNotation(b)); if (!b.MakeMove(m)) { throw new Exception("invalid move from HT!"); } hashTableMoves++; hashKeys.Add(b.HashKey); } while (hashTableMoves-- > 0) { b.UnMakeMove(); } for (int j = ab.PvLength[0] - 1; j >= 0; j--) { b.UnMakeMove(); } }
public static Move DoIterate(GameState state, Action interrupt) { state.TimeUp = false; var startTime = DateTime.Now; var timeLimit = GetThinkTimeSpan(state); AlphaBeta ab = new AlphaBeta(state, () => { if ((DateTime.Now - startTime) > timeLimit) { state.TimeUp = true; } interrupt(); }); //increment transposition table search Id TranspositionTable.Instance.NextSearchId(); int alpha = -10000; int beta = 10000; Move bestMove = null; //Console.WriteLine("Ply\tScore\tMillis\tNodes\tPV"); ab.Metrics.Depth = 0; for (int i = 0; i < AlphaBeta.MAX_DEPTH && !state.TimeUp; i++) { int score; int alphaRelax = 1, betaRelax = 1; if (i > 0) { beta = alpha + 33; alpha = alpha - 33; } do { score = ab.SearchRoot(alpha, beta, i); bestMove = ab.PrincipalVariation[0, 0]; if (!state.TimeUp) { PrintSearchResult(state, startTime, ab, i, score); } if (score > alpha && score < beta) { alpha = score; break; } else if (score >= beta) { if (score == 10000) { break; } beta = Math.Min(10000, beta + (33 * betaRelax)); betaRelax *= 4; } else if (score <= alpha) { if (score == -10000) { break; } alpha = Math.Max(-10000, alpha - (33 * alphaRelax)); alphaRelax *= 4; } } while (!state.TimeUp); //keep searching for a PV move until time is up if (!state.TimeUp) { ab.Metrics.DepthNodes[i] = ab.Metrics.Nodes; ab.Metrics.Depth = i; } if (Math.Abs(score) > 9900) // stop if we have found mate { break; } } PrintMetrics(ab.Metrics, DateTime.Now - startTime); return(bestMove); }