Exemple #1
0
        // A toString type function for the parameter move.
        public static string MoveToString(int move)
        {
            string moveToPrint;

            var fromFile = Conversion.getFilesBrd(MoveOperations.FromSq(move));
            var fromRank = Conversion.getRanksBrd(MoveOperations.FromSq(move));
            var toFile   = Conversion.getFilesBrd(MoveOperations.ToSq(move));
            var toRank   = Conversion.getRanksBrd(MoveOperations.ToSq(move));

            var promoted = MoveOperations.Promoted(move);

            if (promoted != 0)
            {
                var pieceChar = 'q';
                if (Data.IsPieceKnight(promoted))
                {
                    pieceChar = 'n';
                }
                else if (Data.IsPieceRookQueen(promoted) && !Data.IsPieceBishopQueen(promoted))
                {
                    pieceChar = 'r';
                }
                else if (!Data.IsPieceRookQueen(promoted) && Data.IsPieceBishopQueen(promoted))
                {
                    pieceChar = 'b';
                }

                moveToPrint = string.Format("{0}{1}{2}{3}{4}", Convert.ToChar('a' + fromFile),
                                            Convert.ToChar('1' + fromRank),
                                            Convert.ToChar('a' + toFile), Convert.ToChar('1' + toRank),
                                            Convert.ToChar(pieceChar));
            }
            else
            {
                moveToPrint = string.Format("{0}{1}{2}{3}", Convert.ToChar('a' + fromFile),
                                            Convert.ToChar('1' + fromRank),
                                            Convert.ToChar('a' + toFile), Convert.ToChar('1' + toRank));
            }

            return(moveToPrint);
        }
Exemple #2
0
        public int AlphaBeta(int alpha, int beta, int depth, ref S_SearchInfo info, bool DoNull)
        {
            Debug.Assert(BoardOperations.CheckBoard(board));

            if (depth == 0)
            {
                return(Quiescence(alpha, beta, ref info));
            }

            if ((info.Nodes & 2047) == 0)
            {
                CheckUp(ref info);
            }

            info.Nodes++;

            // If position is a draw.
            if ((IsRepetition() || board.FiftyMoves >= 100) && board.Ply != 0)
            {
                return(0);
            }

            if (board.Ply > Variables.MAX_DEPTH - 1)
            {
                return(Evaluate.Position(board));
            }

            bool kingInCheck = Attack.IsSqAttacked(board.KingSq[board.Side], board.Side ^ 1, board);

            // If king is in check, search deeper to get out of check.
            if (kingInCheck)
            {
                depth++;
                // The two following lines are possibly ERROR.
                long timeInc = (info.StopTime - info.StartTime) * (1 / 2);
                info.StopTime += timeInc;
            }

            MoveList list = new MoveList();

            MoveGen.GenerateAllMoves(board, list, false);
            int oldAlpha = alpha;
            int score    = -infinite;
            int legal    = 0; // Will increment when we find a legal move.
            int bestMove = Variables.NO_MOVE;
            int PvMove   = PvTable.Probe(board);

            // Prioritize Principle Variation move if it's found.
            if (PvMove != Variables.NO_MOVE)
            {
                for (int i = 0; i < list.Count; ++i)
                {
                    var move = list.Moves[i].Move;
                    if (move == PvMove)
                    {
                        list.Moves[i].Score = 2000000;
                        break;
                    }
                }
            }

            for (int i = 0; i < list.Count; ++i)
            {
                PickNextMove(i, list);

                var move = list.Moves[i].Move;
                if (!MakeMove.Make_Move(board, move))
                {
                    continue;
                }

                legal++;
                score = -AlphaBeta(-beta, -alpha, depth - 1, ref info, true);
                MakeMove.TakeMove(board); // Take back the made move.

                if (info.Stopped)
                {
                    return(0); // Back up to the root if times up.
                }

                // We have a new alpha or beta cutoff.
                if (score > alpha)
                {
                    bool isCaptureMove = (move & MoveOperations.MoveFlagCapture) != 0;
                    // beta cutoff?
                    if (score >= beta)
                    {
                        if (legal == 1)
                        {
                            info.Fhf++; // We searched the best move first.
                        }

                        info.Fh++;

                        // If beta cutoff, but no capture move.
                        if (!isCaptureMove)
                        {
                            board.SearchKillers[1, board.Ply] = board.SearchKillers[0, board.Ply];
                            board.SearchKillers[0, board.Ply] = move;
                        }
                        return(beta);
                    }

                    // Alpha cutoff
                    alpha    = score;
                    bestMove = move;

                    if (!isCaptureMove)
                    {
                        int from = MoveOperations.FromSq(move);
                        int to   = MoveOperations.ToSq(move);
                        board.SearchHistory[board[from], to] += depth; // Prioritizes move near the root of the tree.
                    }
                }
            }

            // If we haven't had any legal moves.
            if (legal == 0)
            {
                // If in check with no legal moves checkmate.
                if (kingInCheck)
                {
                    return(-mate + board.Ply); // Return the amount of moves it takes to mate.
                    // Returning in this way, allows the method to "prefer" the fastest checkmate combination.
                }
                else
                {
                    return(0); // Stalemate.
                }
            }

            if (alpha != oldAlpha)
            {
                PvTable.StoreMove(board, bestMove);
            }

            return(alpha);
        }
Exemple #3
0
        /// <summary>
        ///     Translates a move to an integer
        /// </summary>
        /// <param name="board"></param>
        /// <param name="ptrChar"></param>
        /// <returns></returns>
        public static int ParseMove(Board board, char[] ptrChar)
        {
            if (ptrChar[1] > '8' || ptrChar[1] < '1')
            {
                return(Variables.NO_MOVE);
            }

            if (ptrChar[3] > '8' || ptrChar[3] < '1')
            {
                return(Variables.NO_MOVE);
            }

            if (ptrChar[0] > 'h' || ptrChar[0] < 'a')
            {
                return(Variables.NO_MOVE);
            }

            if (ptrChar[2] > 'h' || ptrChar[2] < 'a')
            {
                return(Variables.NO_MOVE);
            }

            // Use ASCII values as integers.
            int from = Conversion.FR2SQ(ptrChar[0] - 'a', ptrChar[1] - '1');
            int to   = Conversion.FR2SQ(ptrChar[2] - 'a', ptrChar[3] - '1');

            Debug.Assert(Validators.SqOnBoard(from), String.Format("The from {0} sq is invalid", Io.SqToString(from)));
            Debug.Assert(Validators.SqOnBoard(to),
                         String.Format("The to {0} sq is invalid", Io.SqToString(to)));

            MoveList moveList = new MoveList();

            MoveGen.GenerateAllMoves(board, moveList, false);

            for (int i = 0; i < moveList.Count; ++i)
            {
                int move = moveList.Moves[i].Move;

                // If the move has been located in the move list, it means it's a valid move.
                if (MoveOperations.FromSq(move) == from && MoveOperations.ToSq(move) == to)
                {
                    int promotedPce = MoveOperations.Promoted(move);
                    if (promotedPce != (int)Piece.EMPTY)
                    {
                        if (Data.IsPieceRookQueen(promotedPce) &&
                            !Data.IsPieceBishopQueen(promotedPce) && ptrChar[4] == 'r')
                        {
                            return(move);
                        }
                        else if (!Data.IsPieceRookQueen(promotedPce) &&
                                 Data.IsPieceBishopQueen(promotedPce) && ptrChar[4] == 'b')
                        {
                            return(move);
                        }
                        else if (Data.IsPieceKnight(promotedPce) && ptrChar[4] == 'k')
                        {
                            return(move);
                        }
                        else if (Data.IsPieceBishopQueen(promotedPce) &&
                                 Data.IsPieceRookQueen(promotedPce) && ptrChar[4] == 'q')
                        {
                            return(move);
                        }
                        continue;
                    }

                    return(move);
                }
            }

            return(Variables.NO_MOVE);
        }