Пример #1
0
        /// <summary>
        /// 与えられた指し手に従い、局面を更新する。
        /// </summary>
        /// <param name="move"></param>
        public void DoMove(Move move)
        {
            Debug.Assert(SideToMove == move.SideToMove);
            Debug.Assert(move.Drop || Board[move.FileFrom, move.RankFrom] == move.PieceFrom);
            Debug.Assert(move.Drop || Board[move.FileTo, move.RankTo] == move.PieceTo);

            // 相手の駒を取る
            if (move.PieceTo != Piece.NoPiece)
            {
                RemovePiece(move.FileTo, move.RankTo);

                Debug.Assert(move.PieceTo.ToColor() != SideToMove);
                Debug.Assert(move.PieceTo.AsOpponentHandPiece().ToColor() == SideToMove);
                PutHandPiece(move.PieceTo.AsOpponentHandPiece());
            }

            if (move.Drop)
            {
                // 駒を打つ指し手
                Debug.Assert(move.PieceFrom.ToColor() == SideToMove);
                RemoveHandPiece(move.PieceFrom);
            }
            else
            {
                // 駒を移動する指し手
                RemovePiece(move.FileFrom, move.RankFrom);
            }

            PutPiece(move.FileTo, move.RankTo,
                     move.Promotion
                ? move.PieceFrom.AsPromoted()
                : move.PieceFrom);
            Debug.Assert(Board[move.FileTo, move.RankTo].ToColor() == SideToMove);

            SideToMove = SideToMove.ToOpponent();
            Hash      ^= Zobrist.Instance.Side;

            if (move.PieceFrom == Piece.BlackKing)
            {
                BlackKingFile = move.FileTo;
                BlackKingRank = move.RankTo;
            }
            else if (move.PieceFrom == Piece.WhiteKing)
            {
                WhiteKingFile = move.FileTo;
                WhiteKingRank = move.RankTo;
            }

            ++Play;

            LastMove = move;

            var newState = new PositionState();

            newState.Previous = State;
            State             = newState;
        }
Пример #2
0
        /// <summary>
        /// sfen文字列をセットする
        /// </summary>
        /// <param name="sfen"></param>
        public void Set(string sfen)
        {
            SideToMove = Color.Black;
            Array.Clear(Board, 0, Board.Length);
            Array.Clear(HandPieces, 0, HandPieces.Length);
            Play          = 1;
            Hash          = 0;
            BlackKingFile = 0;
            BlackKingRank = 0;
            WhiteKingFile = 0;
            WhiteKingRank = 0;
            State         = null;
            LastMove      = null;

            // 盤面
            int  file      = BoardSize - 1;
            int  rank      = 0;
            int  index     = 0;
            bool promotion = false;

            while (true)
            {
                var ch = sfen[index++];
                if (ch == ' ')
                {
                    break;
                }
                else if (ch == '/')
                {
                    Debug.Assert(file == -1);
                    ++rank;
                    file = BoardSize - 1;
                }
                else if (ch == '+')
                {
                    promotion = true;
                }
                else if (Char.IsDigit(ch))
                {
                    int numNoPieces = ch - '0';
                    do
                    {
                        Board[file, rank] = Piece.NoPiece;
                        --file;
                    } while (--numNoPieces > 0);
                }
                else
                {
                    var piece = CharToPiece[ch];
                    Debug.Assert(piece != Piece.NoPiece);
                    if (promotion)
                    {
                        piece     = piece.AsPromoted();
                        promotion = false;
                    }
                    Board[file, rank] = piece;
                    Hash += Zobrist.Instance.PieceSquare[(int)piece, file, rank];

                    if (piece == Piece.BlackKing)
                    {
                        BlackKingFile = file;
                        BlackKingRank = rank;
                    }
                    else if (piece == Piece.WhiteKing)
                    {
                        WhiteKingFile = file;
                        WhiteKingRank = rank;
                    }

                    --file;
                }
            }

            // 手番
            var sideToMove = sfen[index++];

            Debug.Assert(sideToMove == 'b' || sideToMove == 'w');
            if (sideToMove == 'b')
            {
                SideToMove = Color.Black;
            }
            else
            {
                SideToMove = Color.White;
                Hash      ^= Zobrist.Instance.Side;
            }
            ++index;

            // 持ち駒
            for (int handPieceIndex = 0; handPieceIndex < (int)Piece.NumPieces; ++handPieceIndex)
            {
                HandPieces[handPieceIndex] = 0;
            }
            int numAddedHandPieces = 0;

            while (true)
            {
                var ch = sfen[index++];
                if (ch == ' ')
                {
                    break;
                }
                else if (ch == '-')
                {
                    continue;
                }
                else if (Char.IsDigit(ch))
                {
                    // 2桁の場合に対応する
                    numAddedHandPieces *= 10;
                    numAddedHandPieces += ch - '0';
                    continue;
                }

                var piece = CharToPiece[ch];
                Debug.Assert(piece != Piece.NoPiece);
                HandPieces[(int)piece] += Max(1, numAddedHandPieces);
                Hash += Zobrist.Instance.HandPiece[(int)piece];
                numAddedHandPieces = 0;
            }

            Play = int.Parse(sfen.Substring(index));

            State = new PositionState();
        }