Example #1
0
        public bool AddMove(Move move)
		{
            // Add the piece that was there to the move stack
            _history.Push(new Square(move, _pieceArray[move.To], _colourArray[move.To], _enPassantTarget, _castling, _zobristHash));

            // ORDINARY MOVE
			if (move.Bits == 0)
			{
                MovePieceWithZobrist(move.From, move.To);
                SetEnPassant();
            }
            // EN PASSANT
            else if ((move.Bits & 4) != 0)
            {
                MovePieceWithZobrist(move.From, move.To);

                // Delete the en passant target square
                _zobristHash ^= _hashValues.PieceValue(_enPassantTarget - _turn * 10, _colourArray[_enPassantTarget - _turn * 10], _pieceArray[_enPassantTarget - _turn * 10]);

                _pieceArray[_enPassantTarget - _turn * 10] = Definitions.EMPTY;
                _colourArray[_enPassantTarget - _turn * 10] = Definitions.EMPTY;
                SetEnPassant();
            }
            // CAPTURE (todo: implement 50 move rule)
            else if ((move.Bits & 1) != 0)
            {
                if (_pieceArray[move.To] == Definitions.K)
                {
                    switch (_colourArray[move.To])
                    {
                        case Definitions.WHITE:
                            _whiteKing = Definitions.EMPTY;
                            break;
                        case Definitions.BLACK:
                            _blackKing = Definitions.EMPTY;
                            break;
                    }
                }

                MovePieceWithZobrist(move.From, move.To);
                SetEnPassant();
            }
            // DOUBLE PAWN PUSH (todo: implement 50 move rule)
            else if ((move.Bits & 8) != 0)
            {
                MovePieceWithZobrist(move.From, move.To);
                SetEnPassant(move.From + (10 * _turn));
            }
            // PAWN PUSH (todo: implement 50 move rule)
            else if ((move.Bits & 16) != 0)
            {
                MovePieceWithZobrist(move.From, move.To);
                SetEnPassant();
            }
            // CASTLING MOVE
            else if ((move.Bits & 2) != 0)
            {
                // move the king
                MovePieceWithZobrist(move.From, move.To);

                // figure out which rook to move
                switch (move.To)
                {
                    case 27: // white king side
                        MovePieceWithZobrist(28, 26); // right rook
                        break;
                    case 23: // white queen side
                        MovePieceWithZobrist(21, 24); // left rook
                        break;
                    case 97: // black king side
                        MovePieceWithZobrist(98, 96); // right rook
                        break;
                    case 93:  // black queen size
                        MovePieceWithZobrist(91, 94); // left rook
                        break;
                }

                SetEnPassant();
            }

            // PROMOTION (todo: implement 50 move rule)
            if ((move.Bits & 32) != 0)
            {
                // Everything else should be taken care of by this point.
                // Just overwrite the underlying piece.
                _zobristHash ^= _hashValues.PieceValue(move.To, _colourArray[move.To], _pieceArray[move.To]);
                _pieceArray[move.To] = move.Promote;
                _zobristHash ^= _hashValues.PieceValue(move.To, _colourArray[move.To], _pieceArray[move.To]);
            }

            // POST MOVE

            #region Remove castling rights and reset king
            if (_pieceArray[move.To] == Definitions.K)
            {
                if (_turn == Definitions.WHITE)
                {
                    // remove white's ability to castle
                    if ((_castling & 1) != 0)
                    {
                        _zobristHash ^= _hashValues.CastlingRights[0];
                        _castling = _castling - 1;
                    }
                    if ((_castling & 2) != 0)
                    {
                        _zobristHash ^= _hashValues.CastlingRights[1];
                        _castling = _castling - 2;
                    }
                    _whiteKing = move.To;
                }
                else
                {
                    // remove black's ability to castle
                    if ((_castling & 4) != 0)
                    {
                        _zobristHash ^= _hashValues.CastlingRights[2];
                        _castling = _castling - 4;
                    }
                    if ((_castling & 8) != 0)
                    {
                        _zobristHash ^= _hashValues.CastlingRights[3];
                        _castling = _castling - 8;
                    }
                    _blackKing = move.To;
                }
            }

            if ((move.From == 28 || move.To == 28) && (_castling & 1) != 0)
            {
                _zobristHash ^= _hashValues.CastlingRights[0];
                _castling -= 1;
            }
            else if ((move.From == 21 || move.To == 21) && (_castling & 2) != 0)
            {
                _zobristHash ^= _hashValues.CastlingRights[1];
                _castling -= 2;
            }
            else if ((move.From == 98 || move.To == 98) && (_castling & 4) != 0)
            {
                _zobristHash ^= _hashValues.CastlingRights[2];
                _castling -= 4;
            }
            else if ((move.From == 91 || move.To == 91) && (_castling & 8) != 0)
            {
                _zobristHash ^= _hashValues.CastlingRights[3];
                _castling -= 8;
            }

            #endregion

            // Increment the full move number after black
            if (_turn == Definitions.BLACK)
                _fullMoveNumber++;

            // Switch the active turn
            _turn = -1 * _turn;
            _zobristHash ^= _hashValues.IfBlackIsPlaying;

            // If the board is in check, subtract the move
            if (IsInCheck(-1 * _turn))
            {
                SubtractMove();
                return false;
            }
			return true;
		}
Example #2
0
        /// <summary>
        /// Given input such as "e2e4" it runs the appropriate move without the bits.
        /// Use the AddMoveNoBits() function with these moves.
        /// </summary>
        /// <param name="move"></param>
        /// <returns></returns>
        public static Move StringToMove(string movestring)
        {
            Move move = new Move();

            move.From = ChessPieceToIndex(movestring.Substring(0, 2));
            move.To = ChessPieceToIndex(movestring.Substring(2, 2));
            if (movestring.EndsWith("q"))
            {
                move.Bits += 32;
                move.Promote = Definitions.Q;
            }
            else if (movestring.EndsWith("r"))
            {
                move.Bits += 32;
                move.Promote = Definitions.R;
            }
            else if (movestring.EndsWith("b"))
            {
                move.Bits += 32;
                move.Promote = Definitions.B;
            }
            else if (movestring.EndsWith("n"))
            {
                move.Bits += 32;
                move.Promote = Definitions.N;
            }

            return move;
        }
Example #3
0
        /// <summary>
        /// Add move without the bits field set. Determines the bit fields.
        /// Note: It does not attempt to determine promotion bits. That should
        /// be taken care of by StringToMove()
        /// </summary>
        /// <param name="move">Move without bits</param>
        /// <returns>whether the addition was successful</returns>
        public bool AddMoveNoBits(Move move)
        {
            // Capture
            if (_colourArray[move.To] == -1 * _turn)
                move.Bits += 1;

            // Castling
            if (move.From == 25 && (move.To == 27 || move.To == 23))
                move.Bits += 2;
            else if (move.From == 95 && (move.To == 97 || move.To == 93))
                move.Bits += 2;

            // En passant capture (rather naive for now)
            if (_pieceArray[move.From] == Definitions.P && (move.To == move.From + 9 * _turn || move.To == move.From + 11 * _turn) && _pieceArray[move.To] == Definitions.EMPTY) 
                move.Bits += 4;

            // Double pawn push
            if (_pieceArray[move.From] == Definitions.P && move.To == move.From + 20 * _turn)
                move.Bits += 8;

            // Pawn move
            if (_pieceArray[move.From] == Definitions.P)
                move.Bits += 16;

            // Add to the opening book if we're in it
            if (!_book.OutOfOpeningBook)
            {
                _book.OpeningBookDepth++;
                _book.OpeningLine += Definitions.MoveToString(move);
            }
            return AddMove(move);
        }
Example #4
0
        public static string MoveToString(Move move)
        {
            string moveString = string.Empty;

            int fromColumn = GetColumn(move.From);
            int fromRow = GetRow(move.From);
            moveString += columnNames[fromColumn - 1] + fromRow;

            int toColumn = GetColumn(move.To);
            int toRow = GetRow(move.To);
            moveString += columnNames[toColumn - 1] + toRow;

            return moveString;
        }