Пример #1
0
        // deep copy constructor
        public PiecePositions(PiecePositions source)
        {
            _Pawns   = source._Pawns;
            _Knights = source._Knights;
            _Bishops = source._Bishops;
            _Rooks   = source.Rooks;
            _Queens  = source._Queens;
            _Kings   = source._Kings;

            Black     = new Player(this);
            Black.All = source.Black.All;
            White     = new Player(this);
            White.All = source.White.All;

            Black.Opponent = White;
            White.Opponent = Black;
        }
Пример #2
0
        // create a board with a FEN string
        public Board(string fen)
        {
            Match Match = FenParser.Match(fen);

            if (!Match.Success)
            {
                throw new ArgumentException(string.Format("invalid FEN string \"{0}\"", fen));
            }

            // piece placement
            string Field = Match.Groups[1].Value;

            string[]     RankPlacement = Field.Split('/');
            BoardAddress Location;
            int          File;

            Pieces = new PiecePositions();
            for (int rank = 0; rank < 8; rank++)
            {
                File = 0;
                foreach (char c in RankPlacement[7 - rank])
                {
                    Location = new BoardAddress((char)('a' + File), rank);

                    switch (c)
                    {
                    case 'p':
                        Pieces.Black.Pawns |= Location.Position;
                        break;

                    case 'P':
                        Pieces.White.Pawns |= Location.Position;
                        break;

                    case 'n':
                        Pieces.Black.Knights |= Location.Position;
                        break;

                    case 'N':
                        Pieces.White.Knights |= Location.Position;
                        break;

                    case 'b':
                        Pieces.Black.Bishops |= Location.Position;
                        break;

                    case 'B':
                        Pieces.White.Bishops |= Location.Position;
                        break;

                    case 'r':
                        Pieces.Black.Rooks |= Location.Position;
                        break;

                    case 'R':
                        Pieces.White.Rooks |= Location.Position;
                        break;

                    case 'q':
                        Pieces.Black.Queens |= Location.Position;
                        break;

                    case 'Q':
                        Pieces.White.Queens |= Location.Position;
                        break;

                    case 'k':
                        Pieces.Black.King |= Location.Position;
                        break;

                    case 'K':
                        Pieces.White.King |= Location.Position;
                        break;

                    default:     // num empty spaces
                        if (!char.IsDigit(c))
                        {
                            throw new ArgumentException(string.Format("invalid character \"{0}\" in piece placement field", c));
                        }
                        File += c - '1';     // convert char to int
                        break;
                    }

                    File++;
                }
            }

            // active color
            Field = Match.Groups[2].Value.ToLower();
            if (Field == "w")
            {
                ActiveColorWhite = true;
            }
            else
            {
                ActiveColorWhite = false;
            }

            // castling availablity
            CastlingAvailability = new Castling();
            Field = Match.Groups[3].Value;
            if (Field == "-")   // not available
            {
                CastlingAvailability.White = Castling.Move.Disallowed;
                CastlingAvailability.Black = Castling.Move.Disallowed;
            }
            else     // available to at least one player
            // check white
            {
                if (Field.Contains("K") && Field.Contains("Q"))
                {
                    CastlingAvailability.White = Castling.Move.BothSides;
                }
                else if (Field.Contains("K"))
                {
                    CastlingAvailability.White = Castling.Move.KingSide;
                }
                else if (Field.Contains("Q"))
                {
                    CastlingAvailability.White = Castling.Move.QueenSide;
                }
                else
                {
                    CastlingAvailability.White = Castling.Move.Disallowed;
                }

                // check black
                if (Field.Contains("k") && Field.Contains("q"))
                {
                    CastlingAvailability.Black = Castling.Move.BothSides;
                }
                else if (Field.Contains("k"))
                {
                    CastlingAvailability.Black = Castling.Move.KingSide;
                }
                else if (Field.Contains("q"))
                {
                    CastlingAvailability.Black = Castling.Move.QueenSide;
                }
                else
                {
                    CastlingAvailability.Black = Castling.Move.Disallowed;
                }
            }

            // enpassant location
            Field = Match.Groups[4].Value;
            if (Field == "-")
            {
                EnPassantTarget = 0;
            }
            else
            {
                EnPassantTarget = new BoardAddress(Field).Position;
            }

            // halfmove clock
            Field = Match.Groups[5].Value;
            if (!byte.TryParse(Field, out HalfMoveClock))
            {
                throw new ArgumentException(string.Format("could not parse halfmove clock \"{0}\"", Field));
            }

            // halfmove clock
            Field = Match.Groups[6].Value;
            if (!int.TryParse(Field, out FullMoveNumber))
            {
                throw new ArgumentException(string.Format("could not parse full move number \"{0}\"", Field));
            }
        }
Пример #3
0
 public Player(PiecePositions p)
 {
     Parent = p;
 }
Пример #4
0
        // create a move from ACN string and the piece positions
        public Move(string acn, PiecePositions pieces)
        {
            int Len = acn.Length;

            if (Len < 4 || Len > 5)
            {
                throw new ArgumentException(string.Format("ACN strings must be 4 or 5 characters long: \"{0}\"", acn));
            }
            string f = acn.Substring(0, 2);
            string t = acn.Substring(2, 2);

            From = new BoardAddress(f);
            To   = new BoardAddress(t);

            // determine the type of piece that is moving
            if ((pieces.Pawns & From.Position) != 0)
            {
                MoveType = PieceMoveType.Pawn;
            }
            else if ((pieces.Knights & From.Position) != 0)
            {
                MoveType = PieceMoveType.Knight;
            }
            else if ((pieces.Bishops & From.Position) != 0)
            {
                MoveType = PieceMoveType.Bishop;
            }
            else if ((pieces.Rooks & From.Position) != 0)
            {
                MoveType = PieceMoveType.Rook;
            }
            else if ((pieces.Queens & From.Position) != 0)
            {
                MoveType = PieceMoveType.Queen;
            }
            else if ((pieces.Kings & From.Position) != 0)
            {
                MoveType = PieceMoveType.King;
            }
            else
            {
                throw new ArgumentException(string.Format("move \"{0}\" invalid given current piece positions", acn));
            }

            // promotion on this move?
            if (Len == 5)   // yes
            {
                if (MoveType != PieceMoveType.Pawn)
                {
                    throw new ArgumentException("tried to promote from a piece type other than pawn");
                }
                char promo = char.ToLower(acn[4]);
                switch (promo)
                {
                case 'n':
                    MoveType = PieceMoveType.PawnKnight;
                    break;

                case 'b':
                    MoveType = PieceMoveType.PawnBishop;
                    break;

                case 'r':
                    MoveType = PieceMoveType.PawnRook;
                    break;

                case 'q':
                    MoveType = PieceMoveType.PawnQueen;
                    break;

                default:
                    throw new ArgumentException(string.Format("ACN string contains invalid promotion character \"{0}\"", promo));
                }
            }
        }