Beispiel #1
0
        static ulong perfT(MoveGen moveGen, Position pos, int depth)
        {
            if (depth == 0)
            {
                return(1);
            }
            ulong nodes = 0;

            MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
            MoveGen.RemoveIllegal(pos, moves);
            if (depth == 1)
            {
                int ret = moves.size;
                moveGen.returnMoveList(moves);
                return((ulong)ret);
            }
            UndoInfo ui = new UndoInfo();

            for (int mi = 0; mi < moves.size; mi++)
            {
                Move m = moves.m[mi];
                pos.makeMove(m, ui);
                nodes += perfT(moveGen, pos, depth - 1);
                pos.unMakeMove(m, ui);
            }
            moveGen.returnMoveList(moves);
            return(nodes);
        }
Beispiel #2
0
        /**
         * Update the game state according to move/command string from a player.
         * @param str The move or command to process.
         * @return True if str was understood, false otherwise.
         */
        public bool processstring(string str)
        {
            if (handleCommand(str))
            {
                return(true);
            }
            if (getGameState() != GameState.ALIVE)
            {
                return(false);
            }

            Move m = TextIO.stringToMove(pos, str);

            if (m == null)
            {
                return(false);
            }

            UndoInfo ui = new UndoInfo();

            pos.makeMove(m, ui);
            TextIO.fixupEPSquare(pos);
            while (currentMove < moveList.Count)
            {
                moveList.RemoveAt(currentMove);
                uiInfoList.RemoveAt(currentMove);
                drawOfferList.RemoveAt(currentMove);
            }
            moveList.Add(m);
            uiInfoList.Add(ui);
            drawOfferList.Add(pendingDrawOffer);
            pendingDrawOffer = false;
            currentMove++;
            return(true);
        }
Beispiel #3
0
        public List <string> getPosHistory()
        {
            List <string> ret = new List <string>();

            Position pos2 = new Position(pos /*this.pos*/);

            for (int i = currentMove; i > 0; i--)
            {
                pos2.unMakeMove(moveList[i - 1], uiInfoList[i - 1]);
            }
            ret.Add(TextIO.toFEN(pos2)); // Store initial FEN

            string moves = "";

            for (int i = 0; i < moveList.Count; i++)
            {
                Move   move    = moveList[i];
                string strMove = TextIO.moveTostring(pos2, move, false);
                moves += " " + strMove;
                UndoInfo ui = new UndoInfo();
                pos2.makeMove(move, ui);
            }
            ret.Add(moves); // Store move list string
            int numUndo = moveList.Count - currentMove;

            ret.Add(((int)numUndo).ToString());
            return(ret);
        }
Beispiel #4
0
        /** Search a position and return the best move and score. Used for test suite processing. */
        public TwoReturnValues <Move, string> searchPosition(Position pos, int maxTimeMillis)
        {
            // Create a search object
            ulong[] posHashList = new ulong[200];
            tt.nextGeneration();
            Search sc = new Search(pos, posHashList, 0, tt);

            // Determine all legal moves
            MoveGen.MoveList moves = new MoveGen().pseudoLegalMoves(pos);
            MoveGen.RemoveIllegal(pos, moves);
            sc.scoreMoveList(moves, 0);

            // Find best move using iterative deepening
            sc.timeLimit(maxTimeMillis, maxTimeMillis);
            Move bestM = sc.iterativeDeepening(moves, -1, -1, false);

            // Extract PV
            string   PV = TextIO.moveTostring(pos, bestM, false) + " ";
            UndoInfo ui = new UndoInfo();

            pos.makeMove(bestM, ui);
            PV += tt.extractPV(pos);
            pos.unMakeMove(bestM, ui);

            //        tt.printStats();

            // Return best move and PV
            return(new TwoReturnValues <Move, string>(bestM, PV));
        }
Beispiel #5
0
        /** Check if a draw claim is allowed, possibly after playing "move".
         * @param move The move that may have to be made before claiming draw.
         * @return The draw string that claims the draw, or empty string if draw claim not valid.
         */
        private string canClaimDraw(Position pos, ulong[] posHashList, int posHashListSize, Move move)
        {
            string drawStr = "";

            if (Search.canClaimDraw50(pos))
            {
                drawStr = "draw 50";
            }
            else if (Search.canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize))
            {
                drawStr = "draw rep";
            }
            else
            {
                string strMove = TextIO.moveTostring(pos, move, false);
                posHashList[posHashListSize++] = pos.zobristHash();
                UndoInfo ui = new UndoInfo();
                pos.makeMove(move, ui);
                if (Search.canClaimDraw50(pos))
                {
                    drawStr = "draw 50 " + strMove;
                }
                else if (Search.canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize))
                {
                    drawStr = "draw rep " + strMove;
                }
                pos.unMakeMove(move, ui);
            }
            return(drawStr);
        }
Beispiel #6
0
        private void initBook(bool verbose)
        {
            bookMap = new Dictionary <ulong, List <BookEntry> >();
            long t0 = SystemHelper.currentTimeMillis();

            numBookMoves = 0;
            try
            {
                /* read /book.bin into buf */
                Byte[]   buf      = Bookbin.DATA;
                Position startPos = TextIO.readFEN(TextIO.startPosFEN);
                Position pos      = new Position(startPos);
                UndoInfo ui       = new UndoInfo();
                int      len      = buf.Length;
                for (int i = 0; i < len; i += 2)
                {
                    int b0 = buf[i]; if (b0 < 0)
                    {
                        b0 += 256;
                    }
                    int b1 = buf[i + 1]; if (b1 < 0)
                    {
                        b1 += 256;
                    }
                    int move = (b0 << 8) + b1;
                    if (move == 0)
                    {
                        pos = new Position(startPos);
                    }
                    else
                    {
                        bool bad  = ((move >> 15) & 1) != 0;
                        int  prom = (move >> 12) & 7;
                        Move m    = new Move(move & 63, (move >> 6) & 63,
                                             promToPiece(prom, pos.whiteMove));
                        if (!bad)
                        {
                            addToBook(pos, m);
                        }
                        pos.makeMove(m, ui);
                    }
                }
            }
            catch
            {
                SystemHelper.println("Can't read opening book resource");
                throw new RuntimeException();
            }
            if (verbose)
            {
                long t1 = SystemHelper.currentTimeMillis();
                SystemHelper.println("Book moves: " + numBookMoves.ToString() +
                                     "(parse time: " + ((t1 - t0) / 1000).ToString() + ")");
            }
        }
Beispiel #7
0
        public void unMakeMove(Move move, UndoInfo ui)
        {
            hashKey  ^= whiteHashKey;
            whiteMove = !whiteMove;
            int p = squares[move.to];

            setPiece(move.from, p);
            setPiece(move.to, ui.capturedPiece);
            setCastleMask(ui.castleMask);
            setEpSquare(ui.epSquare);
            halfMoveClock = ui.halfMoveClock;
            bool wtm = whiteMove;

            if (move.promoteTo != Piece.EMPTY)
            {
                p = wtm ? Piece.WPAWN : Piece.BPAWN;
                setPiece(move.from, p);
            }
            if (!wtm)
            {
                fullMoveCounter--;
            }

            // Handle castling
            int king = wtm ? Piece.WKING : Piece.BKING;

            if (p == king)
            {
                int k0 = move.from;
                if (move.to == k0 + 2)
                { // O-O
                    movePieceNotPawn(k0 + 1, k0 + 3);
                }
                else if (move.to == k0 - 2)
                { // O-O-O
                    movePieceNotPawn(k0 - 1, k0 - 4);
                }
            }

            // Handle en passant
            if (move.to == epSquare)
            {
                if (p == Piece.WPAWN)
                {
                    setPiece(move.to - 8, Piece.BPAWN);
                }
                else if (p == Piece.BPAWN)
                {
                    setPiece(move.to + 8, Piece.WPAWN);
                }
            }
        }
Beispiel #8
0
        /// <summary>
        /// Extract a list of PV moves, starting from "rootPos" and first move "m".
        /// </summary>
        /// <param name="rootPos"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        public List <Move> extractPVMoves(Position rootPos, Move m)
        {
            Position pos = new Position(rootPos);

            m = new Move(m);
            List <Move>  ret         = new List <Move>();
            UndoInfo     ui          = new UndoInfo();
            List <ulong> hashHistory = new List <ulong>();
            MoveGen      moveGen     = new MoveGen();

            while (true)
            {
                ret.Add(m);
                pos.makeMove(m, ui);
                if (hashHistory.Contains(pos.zobristHash()))
                {
                    break;
                }
                hashHistory.Add(pos.zobristHash());
                TTEntry ent = probe(pos.historyHash());
                if (ent.type == TTEntry.T_EMPTY)
                {
                    break;
                }
                m = new Move(0, 0, 0);
                ent.getMove(m);
                MoveGen.MoveList moves = moveGen.pseudoLegalMoves(pos);
                MoveGen.RemoveIllegal(pos, moves);
                bool contains = false;
                for (int mi = 0; mi < moves.size; mi++)
                {
                    if (moves.m[mi].equals(m))
                    {
                        contains = true;
                        break;
                    }
                }
                if (!contains)
                {
                    break;
                }
            }
            return(ret);
        }
Beispiel #9
0
        /**
         * Apply a move to the current position.
         * Special version that only updates enough of the state for the SEE function to be happy.
         */
        public void makeSEEMove(Move move, UndoInfo ui)
        {
            ui.capturedPiece = squares[move.to];
            bool wtm = whiteMove;

            int   p        = squares[move.from];
            ulong fromMask = 1UL << move.from;

            // Handle castling
            if (((pieceTypeBB[Piece.WKING] | pieceTypeBB[Piece.BKING]) & fromMask) != 0)
            {
                int k0 = move.from;
                if (move.to == k0 + 2)
                { // O-O
                    setSEEPiece(k0 + 1, squares[k0 + 3]);
                    setSEEPiece(k0 + 3, Piece.EMPTY);
                }
                else if (move.to == k0 - 2)
                { // O-O-O
                    setSEEPiece(k0 - 1, squares[k0 - 4]);
                    setSEEPiece(k0 - 4, Piece.EMPTY);
                }
            }

            // Handle en passant
            if (move.to == epSquare)
            {
                if (p == Piece.WPAWN)
                {
                    setSEEPiece(move.to - 8, Piece.EMPTY);
                }
                else if (p == Piece.BPAWN)
                {
                    setSEEPiece(move.to + 8, Piece.EMPTY);
                }
            }

            // Perform move
            setSEEPiece(move.from, Piece.EMPTY);
            setSEEPiece(move.to, p);
            whiteMove = !wtm;
        }
Beispiel #10
0
        public void unMakeSEEMove(Move move, UndoInfo ui)
        {
            whiteMove = !whiteMove;
            int p = squares[move.to];

            setSEEPiece(move.from, p);
            setSEEPiece(move.to, ui.capturedPiece);
            bool wtm = whiteMove;

            // Handle castling
            int king = wtm ? Piece.WKING : Piece.BKING;

            if (p == king)
            {
                int k0 = move.from;
                if (move.to == k0 + 2)
                { // O-O
                    setSEEPiece(k0 + 3, squares[k0 + 1]);
                    setSEEPiece(k0 + 1, Piece.EMPTY);
                }
                else if (move.to == k0 - 2)
                { // O-O-O
                    setSEEPiece(k0 - 4, squares[k0 - 1]);
                    setSEEPiece(k0 - 1, Piece.EMPTY);
                }
            }

            // Handle en passant
            if (move.to == epSquare)
            {
                if (p == Piece.WPAWN)
                {
                    setSEEPiece(move.to - 8, Piece.BPAWN);
                }
                else if (p == Piece.BPAWN)
                {
                    setSEEPiece(move.to + 8, Piece.WPAWN);
                }
            }
        }
Beispiel #11
0
        /** Apply a move to the current position. */
        public void makeMove(Move move, UndoInfo ui)
        {
            ui.capturedPiece = squares[move.to];
            ui.castleMask    = castleMask;
            ui.epSquare      = epSquare;
            ui.halfMoveClock = halfMoveClock;
            bool wtm = whiteMove;

            int   p        = squares[move.from];
            int   capP     = squares[move.to];
            ulong fromMask = 1UL << move.from;

            int prevEpSquare = epSquare;

            setEpSquare(-1);

            if ((capP != Piece.EMPTY) || (((pieceTypeBB[Piece.WPAWN] | pieceTypeBB[Piece.BPAWN]) & fromMask) != 0))
            {
                halfMoveClock = 0;

                // Handle en passant and epSquare
                if (p == Piece.WPAWN)
                {
                    if (move.to - move.from == 2 * 8)
                    {
                        int x = Position.getX(move.to);
                        if (((x > 0) && (squares[move.to - 1] == Piece.BPAWN)) ||
                            ((x < 7) && (squares[move.to + 1] == Piece.BPAWN)))
                        {
                            setEpSquare(move.from + 8);
                        }
                    }
                    else if (move.to == prevEpSquare)
                    {
                        setPiece(move.to - 8, Piece.EMPTY);
                    }
                }
                else if (p == Piece.BPAWN)
                {
                    if (move.to - move.from == -2 * 8)
                    {
                        int x = Position.getX(move.to);
                        if (((x > 0) && (squares[move.to - 1] == Piece.WPAWN)) ||
                            ((x < 7) && (squares[move.to + 1] == Piece.WPAWN)))
                        {
                            setEpSquare(move.from - 8);
                        }
                    }
                    else if (move.to == prevEpSquare)
                    {
                        setPiece(move.to + 8, Piece.EMPTY);
                    }
                }

                if (((pieceTypeBB[Piece.WKING] | pieceTypeBB[Piece.BKING]) & fromMask) != 0)
                {
                    if (wtm)
                    {
                        setCastleMask(castleMask & ~(1 << Position.A1_CASTLE));
                        setCastleMask(castleMask & ~(1 << Position.H1_CASTLE));
                    }
                    else
                    {
                        setCastleMask(castleMask & ~(1 << Position.A8_CASTLE));
                        setCastleMask(castleMask & ~(1 << Position.H8_CASTLE));
                    }
                }

                // Perform move
                setPiece(move.from, Piece.EMPTY);
                // Handle promotion
                if (move.promoteTo != Piece.EMPTY)
                {
                    setPiece(move.to, move.promoteTo);
                }
                else
                {
                    setPiece(move.to, p);
                }
            }
            else
            {
                halfMoveClock++;

                // Handle castling
                if (((pieceTypeBB[Piece.WKING] | pieceTypeBB[Piece.BKING]) & fromMask) != 0)
                {
                    int k0 = move.from;
                    if (move.to == k0 + 2)
                    { // O-O
                        movePieceNotPawn(k0 + 3, k0 + 1);
                    }
                    else if (move.to == k0 - 2)
                    { // O-O-O
                        movePieceNotPawn(k0 - 4, k0 - 1);
                    }
                    if (wtm)
                    {
                        setCastleMask(castleMask & ~(1 << Position.A1_CASTLE));
                        setCastleMask(castleMask & ~(1 << Position.H1_CASTLE));
                    }
                    else
                    {
                        setCastleMask(castleMask & ~(1 << Position.A8_CASTLE));
                        setCastleMask(castleMask & ~(1 << Position.H8_CASTLE));
                    }
                }

                // Perform move
                movePieceNotPawn(move.from, move.to);
            }
            if (!wtm)
            {
                fullMoveCounter++;
            }

            // Update castling rights when rook moves
            if ((BitBoard.maskCorners & fromMask) != 0)
            {
                int rook = wtm ? Piece.WROOK : Piece.BROOK;
                if (p == rook)
                {
                    removeCastleRights(move.from);
                }
            }
            if ((BitBoard.maskCorners & (1UL << move.to)) != 0)
            {
                int oRook = wtm ? Piece.BROOK : Piece.WROOK;
                if (capP == oRook)
                {
                    removeCastleRights(move.to);
                }
            }

            hashKey  ^= whiteHashKey;
            whiteMove = !wtm;
        }
Beispiel #12
0
 private bool handleDrawCmd(string drawCmd)
 {
     if (drawCmd.StartsWith("rep") || drawCmd.StartsWith("50"))
     {
         bool   rep = drawCmd.StartsWith("rep");
         Move   m   = null;
         string ms  = drawCmd.Substring(drawCmd.IndexOf(" ") + 1);
         if (ms.Length > 0)
         {
             m = TextIO.stringToMove(pos, ms);
         }
         bool valid;
         if (rep)
         {
             valid = false;
             List <Position> oldPositions = new List <Position>();
             Position        tmpPos;
             if (m != null)
             {
                 UndoInfo ui = new UndoInfo();
                 tmpPos = new Position(pos);
                 tmpPos.makeMove(m, ui);
                 oldPositions.Add(tmpPos);
             }
             oldPositions.Add(pos);
             tmpPos = pos;
             for (int i = currentMove - 1; i >= 0; i--)
             {
                 tmpPos = new Position(tmpPos);
                 tmpPos.unMakeMove(moveList[i], uiInfoList[i]);
                 oldPositions.Add(tmpPos);
             }
             int      repetitions = 0;
             Position firstPos    = oldPositions[0];
             for (int i = 0; i < oldPositions.Count; i++)
             {
                 Position p = oldPositions[i];
                 if (p.drawRuleEquals(firstPos))
                 {
                     repetitions++;
                 }
             }
             if (repetitions >= 3)
             {
                 valid = true;
             }
         }
         else
         {
             Position tmpPos = new Position(pos);
             if (m != null)
             {
                 UndoInfo ui = new UndoInfo();
                 tmpPos.makeMove(m, ui);
             }
             valid = tmpPos.halfMoveClock >= 100;
         }
         if (valid)
         {
             drawState        = rep ? GameState.DRAW_REP : GameState.DRAW_50;
             drawStateMoveStr = null;
             if (m != null)
             {
                 drawStateMoveStr = TextIO.moveTostring(pos, m, false);
             }
         }
         else
         {
             pendingDrawOffer = true;
             if (m != null)
             {
                 processstring(ms);
             }
         }
         return(true);
     }
     else if (drawCmd.StartsWith("offer "))
     {
         pendingDrawOffer = true;
         string ms = drawCmd.Substring(drawCmd.IndexOf(" ") + 1);
         if (TextIO.stringToMove(pos, ms) != null)
         {
             processstring(ms);
         }
         return(true);
     }
     else if (drawCmd == "accept")
     {
         if (haveDrawOffer())
         {
             drawState = GameState.DRAW_AGREE;
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
Beispiel #13
0
        public string getMoveListstring(bool compressed)
        {
            string ret = "";

            // Undo all moves in move history.
            Position pos2 = new Position(pos /*this.pos*/);

            for (int i = currentMove; i > 0; i--)
            {
                pos2.unMakeMove(moveList[i - 1], uiInfoList[i - 1]);
            }

            // Print all moves
            string whiteMove = "";
            string blackMove = "";

            for (int i = 0; i < currentMove; i++)
            {
                Move   move    = moveList[i];
                string strMove = TextIO.moveTostring(pos2, move, false);
                if (drawOfferList[i])
                {
                    strMove += " (d)";
                }
                if (pos2.whiteMove)
                {
                    whiteMove = strMove;
                }
                else
                {
                    blackMove = strMove;
                    if (whiteMove.Length == 0)
                    {
                        whiteMove = "...";
                    }
                    if (compressed)
                    {
                        ret += pos2.fullMoveCounter.ToString() + ". " +
                               whiteMove + " " + blackMove + " ";
                    }
                    else
                    {
                        ret += pos2.fullMoveCounter.ToString() + ".   " +
                               whiteMove.PadRight(10) + " " + blackMove.PadRight(10) + " ";
                    }
                    whiteMove = "";
                    blackMove = "";
                }
                UndoInfo ui = new UndoInfo();
                pos2.makeMove(move, ui);
            }
            if ((whiteMove.Length > 0) || (blackMove.Length > 0))
            {
                if (whiteMove.Length == 0)
                {
                    whiteMove = "...";
                }

                if (compressed)
                {
                    ret += pos2.fullMoveCounter.ToString() + ". " +
                           whiteMove + " " + blackMove + " ";
                }
                else
                {
                    ret += pos2.fullMoveCounter.ToString() + ".   " +
                           whiteMove.PadRight(10) + " " + blackMove.PadRight(10) + " ";
                }
            }
            string gameResult = getPGNResultstring();

            if (gameResult != "*")
            {
                ret += gameResult;
            }
            return(ret);
        }
Beispiel #14
0
        /// <summary>
        /// Extract the PV starting from pos, using hash entries, both exact scores and bounds.
        /// </summary>
        /// <param name="pos"></param>
        /// <returns></returns>
        public string extractPV(Position pos)
        {
            pos = new Position(pos);

            string       ret         = "";
            bool         first       = true;
            TTEntry      ent         = probe(pos.historyHash());
            UndoInfo     ui          = new UndoInfo();
            List <ulong> hashHistory = new List <ulong>();
            bool         repetition  = false;

            while (ent.type != TTEntry.T_EMPTY)
            {
                string type = "";
                if (ent.type == TTEntry.T_LE)
                {
                    type = "<";
                }
                else if (ent.type == TTEntry.T_GE)
                {
                    type = ">";
                }
                Move m = new Move(0, 0, 0);
                ent.getMove(m);
                MoveGen          MG    = new MoveGen();
                MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
                MoveGen.RemoveIllegal(pos, moves);
                bool contains = false;
                for (int mi = 0; mi < moves.size; mi++)
                {
                    if (moves.m[mi].equals(m))
                    {
                        contains = true;
                        break;
                    }
                }
                if (!contains)
                {
                    break;
                }
                string moveStr = TextIO.moveTostring(pos, m, false);
                if (repetition)
                {
                    break;
                }
                if (!first)
                {
                    ret += " ";
                }
                ret += type + moveStr;
                pos.makeMove(m, ui);
                if (hashHistory.Contains(pos.zobristHash()))
                {
                    repetition = true;
                }
                hashHistory.Add(pos.zobristHash());
                ent   = probe(pos.historyHash());
                first = false;
            }
            return(ret);
        }