コード例 #1
0
ファイル: TextIO.cs プロジェクト: Chessforeva/Csharp4chess
        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) {
                        ret += ((char)(x1 + 'a'));   // Only file info needed
                    } else if (numSameRow < 2) {
                        ret += ((char)(y1 + '1'));   // Only row info needed
                    } else {
                        ret += ((char)(x1 + 'a'));   // File and row info needed
                        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;
        }
コード例 #2
0
 /**
  * Extract a list of PV moves, starting from "rootPos" and first move "m".
  */
 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;
 }
コード例 #3
0
 /** Extract the PV starting from pos, using hash entries, both exact scores and bounds. */
 public string extractPV(Position pos)
 {
     string ret = "";
     pos = new Position(pos);    // To avoid modifying the input parameter
     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;
 }
コード例 #4
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;
 }
コード例 #5
0
ファイル: MoveGen.cs プロジェクト: Chessforeva/Csharp4chess
 /**
  * Remove all illegal moves from moveList.
  * "moveList" is assumed to be a list of pseudo-legal moves.
  * This function removes the moves that don't defend from check threats.
  */
 public static void RemoveIllegal(Position pos, MoveList moveList)
 {
     int length = 0;
     UndoInfo ui = new UndoInfo();
     for (int mi = 0; mi < moveList.size; mi++) {
     Move m = moveList.m[mi];
     pos.makeMove(m, ui);
     pos.setWhiteMove(!pos.whiteMove);
     if (!inCheck(pos))
         moveList.m[length++].copyFrom(m);
     pos.setWhiteMove(!pos.whiteMove);
     pos.unMakeMove(m, ui);
     }
     moveList.size = length;
 }
コード例 #6
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);
        }
コード例 #7
0
ファイル: Game.cs プロジェクト: Chessforeva/Csharp4chess
 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;
     }
 }
コード例 #8
0
ファイル: Game.cs プロジェクト: Chessforeva/Csharp4chess
 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;
 }
コード例 #9
0
ファイル: Game.cs プロジェクト: Chessforeva/Csharp4chess
        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;
        }
コード例 #10
0
ファイル: Game.cs プロジェクト: Chessforeva/Csharp4chess
        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;
        }