예제 #1
0
        /// <summary>
        /// Does an AI move.
        /// </summary>
        private void MoveAI()
        {
            Task.Run(() =>
            {
                var openingBookMove = _openingBook.GetMoveFromBook(_history);
                var enemyColor      = ColorOperations.Invert(_currentColor);

                Move moveToApply = null;

                if (openingBookMove != null)
                {
                    moveToApply = Bitboard.Moves.First(p =>
                                                       p.From == openingBookMove.From && p.To == openingBookMove.To);
                }
                else
                {
                    var aiResult = _ai.Calculate(_currentColor, Bitboard, _preferredTime, _helperTasksCount);
                    moveToApply  = aiResult.PVNodes[0];

                    ConsoleManager.WriteLine();
                    ConsoleManager.WriteLine($"$w{_currentColor}:");
                    ConsoleManager.WriteLine($"$wBest move: $g{aiResult.PVNodes} $w(Score: $m{aiResult.Score}$w)");
                    ConsoleManager.WriteLine($"$wTotal nodes: $g{aiResult.Stats.TotalNodes} N $w(Depth: $m{aiResult.Depth}$w)");
                    ConsoleManager.WriteLine($"$wTime: $m{aiResult.Time} s");
                    ConsoleManager.WriteLine();
                }

                CalculateBitboard(moveToApply, false);

                CheckIfGameHasEnded(Bitboard);

                _currentColor = enemyColor;
                _history.Add(moveToApply);
            });
        }
예제 #2
0
        /// <summary>
        /// Checks if king with the specified color is in stalemate.
        /// </summary>
        /// <param name="color">The king color.</param>
        /// <returns>True if king with specified color is in stalemate, otherwise false.</returns>
        public bool IsStalemate(Color color)
        {
            if (!_calculated)
            {
                throw new BitboardNotCalculatedException();
            }

            var bitboardWithoutEnPassant = new Bitboard(this);

            bitboardWithoutEnPassant.EnPassant[(int)color] = 0;

            var ai       = new AICore();
            var aiResult = ai.Calculate(color, bitboardWithoutEnPassant, 0, 0);

            return(!IsCheck(color) && Math.Abs(aiResult.Score) == AIConstants.MateValue);
        }
예제 #3
0
        /// <summary>
        /// Runs AI and does best found move.
        /// </summary>
        /// <param name="color">The engine color.</param>
        /// <returns>The AI result.</returns>
        public AIResult MoveAI(Color color)
        {
            Bitboard.Calculate(GeneratorMode.CalculateMoves | GeneratorMode.CalculateAttacks, false);
            CheckBitboardIntegrity();

            UpdateMovesCount(color);
            if (CheckIfGameHasEnded())
            {
                return(null);
            }

            var openingBookMove = _openingBook.GetMoveFromBook(_history);

            if (openingBookMove != null)
            {
                var moveToApply =
                    Bitboard.Moves.First(p => p.From == openingBookMove.From && p.To == openingBookMove.To);

                Bitboard = Bitboard.Move(moveToApply);
                _history.Add(moveToApply);

                return(new AIResult()
                {
                    PVNodes = new PVNodesList()
                    {
                        moveToApply
                    }
                });
            }
            else
            {
                var preferredTime = _preferredTimeCalculator.Calculate(MovesCount, _remainingTime[(int)color]);
                var aiResult      = _aiCore.Calculate(color, Bitboard, preferredTime);

                // Temporary
                if (aiResult.PVNodes.Count < 1)
                {
                    Console.WriteLine($"Move not found");
                    return(null);
                }

                Bitboard = Bitboard.Move(aiResult.PVNodes[0]);
                _history.Add(aiResult.PVNodes[0]);

                return(aiResult);
            }
        }
예제 #4
0
        /// <summary>
        /// Runs AI calculating.
        /// </summary>
        /// <param name="command">The AI command</param>
        private void CalculateBestMove(Command command)
        {
            var colorArgument         = command.GetArgument <string>(0);
            var preferredTimeArgument = command.GetArgument <float>(1);
            var helperTasksCount      = command.GetArgument <int>(2);

            var colorParseResult = Enum.TryParse(colorArgument, true, out Color color);

            if (!colorParseResult)
            {
                ConsoleManager.WriteLine($"$rInvalid color type ($R{color}$r)");
                return;
            }

            var ai       = new AICore();
            var aiResult = ai.Calculate(color, Bitboard, preferredTimeArgument, helperTasksCount);

            ConsoleManager.WriteLine();

            if (aiResult.PVNodes.Count == 0)
            {
                ConsoleManager.WriteLine("$gMate");
            }
            else
            {
                ConsoleManager.WriteLine($"$wDepth: $g{aiResult.Depth}");
                ConsoleManager.WriteLine($"$wTotal nodes: $g{aiResult.Stats.TotalNodes} N");
                ConsoleManager.WriteLine($"$wEnd nodes: $g{aiResult.Stats.EndNodes} N");
                ConsoleManager.WriteLine($"$wα-β cutoffs: $y{aiResult.Stats.AlphaBetaCutoffs} N");
                ConsoleManager.WriteLine($"$wTT hits: $y{aiResult.Stats.TranspositionTableHits} N");
                ConsoleManager.WriteLine($"$wBranching factor: $y{aiResult.Stats.BranchingFactor}");
                ConsoleManager.WriteLine($"$wNodes per second: $c{aiResult.NodesPerSecond / 1000} kN");
                ConsoleManager.WriteLine($"$wTime per node: $c{aiResult.TimePerNode} ns");
                ConsoleManager.WriteLine($"$wTime: $m{aiResult.Time} s");
                ConsoleManager.WriteLine();
                ConsoleManager.WriteLine($"$wQ Total nodes: $g{aiResult.Stats.QuiescenceTotalNodes} N");
                ConsoleManager.WriteLine($"$wQ End nodes: $g{aiResult.Stats.QuiescenceEndNodes} N");
                ConsoleManager.WriteLine();
                ConsoleManager.WriteLine($"$wBest move: $g{aiResult.PVNodes}");
                ConsoleManager.WriteLine($"$wScore: $m{aiResult.Score}");
            }

            ConsoleManager.WriteLine();
        }