Beispiel #1
0
        private Move findSemiRandomMove(Search sc, MoveGen.MoveList moves)
        {
            sc.timeLimit(minTimeMillis, maxTimeMillis);
            Move bestM     = sc.iterativeDeepening(moves, 1, maxNodes, verbose);
            int  bestScore = bestM.score;

            long   t0     = SystemHelper.currentTimeMillis();
            Random rndGen = new Random((int)t0);

            int sum = 0;

            for (int mi = 0; mi < moves.size; mi++)
            {
                sum += moveProbWeight(moves.m[mi].score, bestScore);
            }
            int rnd = rndGen.Next(sum);

            for (int mi = 0; mi < moves.size; mi++)
            {
                int weight = moveProbWeight(moves.m[mi].score, bestScore);
                if (rnd < weight)
                {
                    return(moves.m[mi]);
                }
                rnd -= weight;
            }
            SystemHelper.println("Assert error. Should never get here!");
            return(null);
        }
Beispiel #2
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 #3
0
        /// <summary>
        /// Remove pseudo-legal EP square if it is not legal, ie would leave king in check.
        /// </summary>
        /// <param name="pos"></param>
        public static void fixupEPSquare(Position pos)
        {
            int epSquare = pos.getEpSquare();

            if (epSquare >= 0)
            {
                MoveGen          MG    = new MoveGen();
                MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
                MoveGen.RemoveIllegal(pos, moves);
                bool epValid = false;
                for (int mi = 0; mi < moves.size; mi++)
                {
                    Move m = moves.m[mi];
                    if (m.to == epSquare)
                    {
                        if (pos.getPiece(m.from) == (pos.whiteMove ? Piece.WPAWN : Piece.BPAWN))
                        {
                            epValid = true;
                            break;
                        }
                    }
                }
                if (!epValid)
                {
                    pos.setEpSquare(-1);
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Convert a chess move to human readable form.
        /// </summary>
        /// <param name="pos">The chess position.</param>
        /// <param name="move">The executed move.</param>
        /// <param name="ulongForm">If true, use ulong notation, eg Ng1-f3. Otherwise, use short notation, eg Nf3</param>
        /// <returns></returns>
        public static string moveTostring(Position pos, Move move, bool ulongForm)
        {
            MoveGen MG = new MoveGen();

            MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
            MoveGen.RemoveIllegal(pos, moves);
            return(moveTostring(pos, move, ulongForm, moves));
        }
Beispiel #5
0
        /// <summary>
        /// To get all valid moves in one text-string
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="ulongForm"></param>
        /// <returns></returns>
        public static string AllMovesTostring(Position pos, bool ulongForm)
        {
            string  ret = "";
            MoveGen MG  = new MoveGen();

            MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
            MoveGen.RemoveIllegal(pos, moves);
            for (int i = 0; i < moves.size; i++)
            {
                ret += moveTostring(pos, moves.m[i], ulongForm, moves) + ";";
            }
            return(ret);
        }
Beispiel #6
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 #7
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);
        }
Beispiel #8
0
        /// <summary>
        /// Convert a chess move string to a Move object. Any prefix of the string representation of a valid move counts as a legal move string, as ulong as the string only matches one valid move.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="strMove"></param>
        /// <returns></returns>
        public static Move stringToMove(Position pos, string strMove)
        {
            strMove = strMove.Replace("=", "");
            Move move = null;

            if (strMove.Length == 0)
            {
                return(move);
            }
            MoveGen MG = new MoveGen();

            MoveGen.MoveList moves = MG.pseudoLegalMoves(pos);
            MoveGen.RemoveIllegal(pos, moves);
            {
                char lastChar = strMove[strMove.Length - 1];
                if ((lastChar == '#') || (lastChar == '+'))
                {
                    MoveGen.MoveList subMoves = new MoveGen.MoveList();
                    int len = 0;
                    for (int mi = 0; mi < moves.size; mi++)
                    {
                        Move   m    = moves.m[mi];
                        string str1 = TextIO.moveTostring(pos, m, true, moves);
                        if (str1[str1.Length - 1] == lastChar)
                        {
                            subMoves.m[len++] = m;
                        }
                    }
                    subMoves.size = len;
                    moves         = subMoves;
                    strMove       = normalizeMovestring(strMove);
                }
            }

            for (int i = 0; i < 2; i++)
            {
                // Search for full match
                for (int mi = 0; mi < moves.size; mi++)
                {
                    Move   m    = moves.m[mi];
                    string str1 = normalizeMovestring(TextIO.moveTostring(pos, m, true, moves));
                    string str2 = normalizeMovestring(TextIO.moveTostring(pos, m, false, moves));
                    if (i == 0)
                    {
                        if ((str1 == strMove) || (str2 == strMove))
                        {
                            return(m);
                        }
                    }
                    else
                    {
                        if ((strMove.ToLower() == str1.ToLower()) ||
                            (strMove.ToLower() == str2.ToLower()))
                        {
                            return(m);
                        }
                    }
                }
            }

            for (int i = 0; i < 2; i++)
            {
                // Search for unique substring match
                for (int mi = 0; mi < moves.size; mi++)
                {
                    Move   m    = moves.m[mi];
                    string str1 = normalizeMovestring(TextIO.moveTostring(pos, m, true));
                    string str2 = normalizeMovestring(TextIO.moveTostring(pos, m, false));
                    bool   match;
                    if (i == 0)
                    {
                        match = (str1.StartsWith(strMove) || str2.StartsWith(strMove));
                    }
                    else
                    {
                        match = (str1.ToLower().StartsWith(strMove.ToLower()) ||
                                 str2.ToLower().StartsWith(strMove.ToLower()));
                    }
                    if (match)
                    {
                        if (move != null)
                        {
                            // More than one match, not ok
                            return(null);
                        }
                        else
                        {
                            move = m;
                        }
                    }
                }
                if (move != null)
                {
                    return(move);
                }
            }
            return(move);
        }
Beispiel #9
0
        private static string moveTostring(Position pos, Move move, bool ulongForm, MoveGen.MoveList moves)
        {
            string ret          = "";
            int    wKingOrigPos = Position.getSquare(4, 0);
            int    bKingOrigPos = Position.getSquare(4, 7);

            if (move.from == wKingOrigPos && pos.getPiece(wKingOrigPos) == Piece.WKING)
            {
                // Check white castle
                if (move.to == Position.getSquare(6, 0))
                {
                    ret += ("O-O");
                }
                else if (move.to == Position.getSquare(2, 0))
                {
                    ret += ("O-O-O");
                }
            }
            else if (move.from == bKingOrigPos && pos.getPiece(bKingOrigPos) == Piece.BKING)
            {
                // Check white castle
                if (move.to == Position.getSquare(6, 7))
                {
                    ret += ("O-O");
                }
                else if (move.to == Position.getSquare(2, 7))
                {
                    ret += ("O-O-O");
                }
            }
            if (ret.Length == 0)
            {
                int p = pos.getPiece(move.from);
                ret += pieceToChar(p);
                int x1 = Position.getX(move.from);
                int y1 = Position.getY(move.from);
                int x2 = Position.getX(move.to);
                int y2 = Position.getY(move.to);
                if (ulongForm)
                {
                    ret += ((char)(x1 + 'a'));
                    ret += ((char)(y1 + '1'));
                    ret += (isCapture(pos, move) ? 'x' : '-');
                }
                else
                {
                    if (p == (pos.whiteMove ? Piece.WPAWN : Piece.BPAWN))
                    {
                        if (isCapture(pos, move))
                        {
                            ret += ((char)(x1 + 'a'));
                        }
                    }
                    else
                    {
                        int numSameTarget = 0;
                        int numSameFile   = 0;
                        int numSameRow    = 0;
                        for (int mi = 0; mi < moves.size; mi++)
                        {
                            Move m = moves.m[mi];
                            if (m == null)
                            {
                                break;
                            }
                            if ((pos.getPiece(m.from) == p) && (m.to == move.to))
                            {
                                numSameTarget++;
                                if (Position.getX(m.from) == x1)
                                {
                                    numSameFile++;
                                }
                                if (Position.getY(m.from) == y1)
                                {
                                    numSameRow++;
                                }
                            }
                        }
                        if (numSameTarget < 2)
                        {
                            // No file/row info needed
                        }
                        else if (numSameFile < 2)
                        {
                            // Only file info needed
                            ret += ((char)(x1 + 'a'));
                        }
                        else if (numSameRow < 2)
                        {
                            // Only row info needed
                            ret += ((char)(y1 + '1'));
                        }
                        else
                        {
                            // File and row info needed
                            ret += ((char)(x1 + 'a'));
                            ret += ((char)(y1 + '1'));
                        }
                    }
                    if (isCapture(pos, move))
                    {
                        ret += ('x');
                    }
                }
                ret += ((char)(x2 + 'a'));
                ret += ((char)(y2 + '1'));
                if (move.promoteTo != Piece.EMPTY)
                {
                    ret += (pieceToChar(move.promoteTo));
                }
            }
            UndoInfo ui = new UndoInfo();

            if (MoveGen.givesCheck(pos, move))
            {
                pos.makeMove(move, ui);
                MoveGen          MG        = new MoveGen();
                MoveGen.MoveList nextMoves = MG.pseudoLegalMoves(pos);
                MoveGen.RemoveIllegal(pos, nextMoves);
                if (nextMoves.size == 0)
                {
                    ret += ('#');
                }
                else
                {
                    ret += ('+');
                }
                pos.unMakeMove(move, ui);
            }

            return(ret);
        }