예제 #1
0
 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();
 }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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);
        }