Exemple #1
0
        /// <summary>
        /// Calculates the best possible move for the specified parameters.
        /// </summary>
        /// <param name="color">The initial player.</param>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="preferredTime">Time allocated for AI.</param>
        /// <returns>The result of AI calculating.</returns>
        public AIResult Calculate(Color color, Bitboard bitboard, float preferredTime)
        {
            var result    = new AIResult();
            var colorSign = ColorOperations.ToSign(color);
            var stopwatch = new Stopwatch();
            int estimatedTimeForNextIteration;

            result.Color         = color;
            result.PreferredTime = preferredTime;

            if (bitboard.ReversibleMoves == 0 && preferredTime != 0)
            {
                _transpositionTable.Clear();
            }

            stopwatch.Start();
            do
            {
                result.Depth++;

                var stats = new AIStats();
                result.Score = colorSign * _regularSearch.Do(color, new Bitboard(bitboard), result.Depth, AIConstants.InitialAlphaValue, AIConstants.InitialBetaValue, stats);

                result.PVNodes = GetPVNodes(bitboard, color);
                result.Stats   = stats;
                result.Ticks   = stopwatch.Elapsed.Ticks;

                OnThinkingOutput?.Invoke(this, new ThinkingOutputEventArgs(result));

                estimatedTimeForNextIteration = (int)stopwatch.Elapsed.TotalMilliseconds * result.Stats.BranchingFactor;
            }while (estimatedTimeForNextIteration < preferredTime * 1000 && result.Depth < 12 && Math.Abs(result.Score) != AIConstants.MateValue);

            return(result);
        }
Exemple #2
0
        private void HelperTask(HelperTaskParameters param)
        {
            var historyTable = new HistoryTable();
            var killerTable  = new KillerTable();
            var helperSearch = new RegularSearch(_transpositionTable, historyTable, killerTable);

            killerTable.SetInitialDepth(param.InitialDepth);

            helperSearch.Do(param.Color, param.Bitboard, param.InitialDepth, AIConstants.InitialAlphaValue, AIConstants.InitialBetaValue, param.Deadline, true, new AIStats());
        }
Exemple #3
0
        /// <summary>
        /// Calculates the best possible move for the specified parameters.
        /// </summary>
        /// <param name="color">The initial player.</param>
        /// <param name="bitboard">The bitboard.</param>
        /// <param name="preferredTime">Time allocated for AI.</param>
        /// <param name="helperTasks">The helper tasks count (0 for single thread).</param>
        /// <returns>The result of AI calculating.</returns>
        public AIResult Calculate(Color color, Bitboard bitboard, float preferredTime, int helperTasks)
        {
            var result    = new AIResult();
            var colorSign = ColorOperations.ToSign(color);
            var stopwatch = new Stopwatch();
            int estimatedTimeForNextIteration;

            var historyTable  = new HistoryTable();
            var killerTable   = new KillerTable();
            var regularSearch = new RegularSearch(_transpositionTable, historyTable, killerTable);

            result.Color         = color;
            result.PreferredTime = preferredTime;

            var deadline = preferredTime != 0 ? DateTime.Now.AddSeconds(preferredTime * 2).Ticks : DateTime.Now.AddSeconds(1).Ticks;

            historyTable.Clear();
            killerTable.Clear();

            if (bitboard.ReversibleMoves == 0 && preferredTime > 0)
            {
                _transpositionTable.Clear();
            }

            stopwatch.Start();
            do
            {
                result.Depth++;

                killerTable.SetInitialDepth(result.Depth);

                if (result.Depth >= AIConstants.MinimalDepthToStartHelperThreads)
                {
                    for (var i = 0; i < helperTasks; i++)
                    {
                        var param = new HelperTaskParameters
                        {
                            Bitboard     = new Bitboard(bitboard),
                            Color        = color,
                            Deadline     = deadline,
                            InitialDepth = result.Depth
                        };

                        Task.Run(() => HelperTask(param));
                    }
                }

                var stats = new AIStats();
                var score = colorSign * regularSearch.Do(color, new Bitboard(bitboard), result.Depth, AIConstants.InitialAlphaValue, AIConstants.InitialBetaValue, deadline, false, stats);

                if (DateTime.Now.Ticks <= deadline)
                {
                    result.PVNodes = GetPVNodes(bitboard, color);
                    result.Score   = score;

                    OnThinkingOutput?.Invoke(this, new ThinkingOutputEventArgs(result));
                }
                else
                {
                    result.Depth--;
                    _transpositionTable.Clear();
                }

                result.Stats = stats;
                result.Ticks = stopwatch.Elapsed.Ticks;

                estimatedTimeForNextIteration = (int)stopwatch.Elapsed.TotalMilliseconds * result.Stats.BranchingFactor;
            }while (estimatedTimeForNextIteration < preferredTime * 1000 &&
                    result.Depth < AIConstants.MaxDepth &&
                    Math.Abs(result.Score) != AIConstants.MateValue);

            return(result);
        }