示例#1
0
        public bool IsUnderAttack(Square sq, PlayerBoard opponentBoard)
        {
            ulong occupied = 1UL << (int)sq;

            ulong pawnAttacks = opponentBoard.GetPawnAttacks();

            if ((occupied & pawnAttacks) != 0)
            {
                return(true);
            }

            ulong knights      = opponentBoard.bitboards[(int)Figure.Knight].GetInnerValue();
            ulong king         = opponentBoard.bitboards[(int)Figure.King].GetInnerValue();
            ulong otherFigures = opponentBoard.allFigures | this.allFigures;

            otherFigures &= (~occupied);

            var   knightAttackGenerator = this.attacksGenerators[(int)Figure.Knight];
            ulong occupiedKnightMoves   = knightAttackGenerator.GetAttacks(sq, otherFigures);

            if ((occupiedKnightMoves & knights) != 0)
            {
                return(true);
            }

            var   kingAttackGenerator = this.attacksGenerators[(int)Figure.King];
            ulong occupiedKingMoves   = kingAttackGenerator.GetAttacks(sq, otherFigures);

            if ((occupiedKingMoves & king) != 0)
            {
                return(true);
            }

            ulong rooksQueens   = opponentBoard.GetRooksQueens();
            ulong bishopsQueens = opponentBoard.GetBishopsQueens();

            var   rookAttackGenerator = this.attacksGenerators[(int)Figure.Rook];
            ulong occupiedRookMoves   = rookAttackGenerator.GetAttacks(sq, otherFigures);

            if ((occupiedRookMoves & rooksQueens) != 0)
            {
                return(true);
            }

            var   bishopAttackGenerator = this.attacksGenerators[(int)Figure.Bishop];
            ulong occupiedBishopMoves   = bishopAttackGenerator.GetAttacks(sq, otherFigures);

            if ((occupiedBishopMoves & bishopsQueens) != 0)
            {
                return(true);
            }

            return(false);
        }
示例#2
0
        private bool AreNoMoves(PlayerBoard player, PlayerBoard opponent)
        {
            var moves = player.GetMoves(opponent,
                                        this.History.GetLastMove(),
                                        MovesMask.AllMoves);

            this.FilterMoves(moves, player.FigureColor);
            bool result = (moves.Size == 0);

            this.allocator.ReleaseLast();
            return(result);
        }
示例#3
0
        private bool AreNoMoves(PlayerBoard player, PlayerBoard opponent)
        {
            var moves = player.GetMoves(opponent,
                                        this.History.GetLastMove(),
                                        MovesMask.AllMoves);

            this.FilterMoves(moves, player.FigureColor);
            bool result = (moves.Size == 0);
            this.allocator.ReleaseLast();
            return result;
        }
示例#4
0
 public bool IsUnderCheck(PlayerBoard opponent)
 {
     return(IsUnderAttack(this.King.GetSquare(), opponent));
 }
示例#5
0
        public List <Move[]> GetKingMoves(PlayerBoard opponent, ulong mask, MovesMask movesMask)
        {
            var otherFigures = opponent.allFigures | this.allFigures;
            var list         = this.moveGenerators[(int)Figure.King].GetMoves(otherFigures, mask);

            // ---------------------------------------------

            // castlings stuff

            // check king can move
            if (this.King.AlreadyMoved != 0)
            {
                return(list);
            }

            var rooks = this.Rooks;

            // if rooks cannot move
            if (rooks.GetInnerProperty() == 0)
            {
                return(list);
            }

            if (movesMask == MovesMask.Attacks)
            {
                return(list);
            }

            var allMasks = KingBitBoardHelper.CastlingMasks;

            ulong[] castlingMasks = allMasks[(int)this.color][(int)this.position];

            bool leftIsEmpty  = (castlingMasks[0] & otherFigures) == 0;
            bool rightIsEmpty = (castlingMasks[1] & otherFigures) == 0;

            // check other figures
            if (!(leftIsEmpty || rightIsEmpty))
            {
                return(list);
            }

            bool noCheck;
            var  squares     = KingBitBoardHelper.CastlingSquares[(int)this.color][(int)this.position];
            int  resultIndex = -1;

            // check checks
            if (leftIsEmpty && (rooks.LeftNotMoved != 0))
            {
                noCheck = true;
                for (int i = 0; i < squares[0].Length; ++i)
                {
                    if (this.IsUnderAttack(squares[0][i], opponent))
                    {
                        noCheck = false;
                        break;
                    }
                }
                if (noCheck)
                {
                    resultIndex = 0;
                }
            }

            if (rightIsEmpty && (rooks.RightNotMoved != 0))
            {
                noCheck = true;
                for (int i = 0; i < squares[1].Length; ++i)
                {
                    if (this.IsUnderAttack(squares[1][i], opponent))
                    {
                        noCheck = false;
                        break;
                    }
                }
                if (noCheck)
                {
                    resultIndex += 2;
                }
            }

            if (resultIndex != -1)
            {
                list.Add(KingBitBoardHelper.CastlingMoves[(int)this.color][(int)this.position][resultIndex]);
            }

            return(list);
        }
示例#6
0
        public FixedArray GetMoves(PlayerBoard opponent, Move lastMove, MovesMask movesMask)
        {
            FixedArray moves      = this.allocator.CreateNewArray();
            var        innerArray = moves.InnerArray;
            int        index      = 0;

            ulong mask = 0;

            if (movesMask == MovesMask.AllMoves)
            {
                mask = ~this.allFigures;
            }
            else
            {
                mask = opponent.allFigures;
            }

            var opponentFigures = opponent.allFigures;
            var otherFigures    = opponentFigures | this.allFigures;

            // add knight, bishop, rook, queen moves
            for (int i = 0; i < PlayerBoard.KnightBishopRookQueen.Length; ++i)
            {
                var figure       = PlayerBoard.KnightBishopRookQueen[i];
                var newMovesList = this.moveGenerators[(int)figure].GetMoves(otherFigures, mask);

                for (int j = 0; j < newMovesList.Count; ++j)
                {
                    var newMovesArray = newMovesList[j];

                    for (int k = 0; k < newMovesArray.Length; ++k)
                    {
                        var item = newMovesArray[k];
                        innerArray[index].From = item.From;
                        innerArray[index].To   = item.To;

                        int destinationFigure = (int)opponent.figures[(int)item.To];
                        innerArray[index].Type =
                            BitBoardHelper.MoveTypes[(int)figure][destinationFigure][(int)item.From][(int)item.To];

                        innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight +
                                                  (int)opponent.figures[(int)item.To];

                        index++;
                    }
                }
            }

            // add king moves
            var kingMoves = this.GetKingMoves(opponent, mask, movesMask);

            for (int j = 0; j < kingMoves.Count; ++j)
            {
                var newMovesArray = kingMoves[j];

                for (int k = 0; k < newMovesArray.Length; ++k)
                {
                    var item = newMovesArray[k];
                    innerArray[index].From = item.From;
                    innerArray[index].To   = item.To;
                    int destinationFigure = (int)opponent.figures[(int)item.To];

                    if (Math.Abs((int)item.From - (int)item.To) == 2)
                    {
                        innerArray[index].Type = MoveType.KingCastle;
                    }
                    else
                    {
                        innerArray[index].Type =
                            BitBoardHelper.MoveTypes[(int)Figure.King][destinationFigure][(int)item.From][(int)item.To];
                    }

                    innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight +
                                              (int)opponent.figures[(int)item.To];

                    index++;
                }
            }

            // add to mask value
            mask = opponent.allFigures;
            // pawn in passing state bit
            int  lastFrom           = (int)lastMove.From;
            int  lastTo             = (int)lastMove.To;
            int  middle             = (lastFrom + lastTo) >> 1;
            bool wasLastMovePassing = false;

            if (Math.Abs(lastFrom - lastTo) == 16)
            {
                if (opponent.Pawns.IsBitSet(lastMove.To))
                {
                    mask              |= 1UL << middle;
                    otherFigures      |= mask;
                    wasLastMovePassing = true;
                }
            }

            if (movesMask == MovesMask.Attacks)
            {
                ulong pawns = this.bitboards[(int)Figure.Pawn].GetInnerValue();
                otherFigures |= pawns >> 8;
                otherFigures |= pawns << 8;
            }

            // add pawns moves
            var pawnMoves = this.moveGenerators[(int)Figure.Pawn].GetMoves(otherFigures, mask);
            int moveTo;

            for (int j = 0; j < pawnMoves.Count; ++j)
            {
                var newMovesArray = pawnMoves[j];

                for (int k = 0; k < newMovesArray.Length; ++k)
                {
                    var item = innerArray[index];

                    item.From = newMovesArray[k].From;
                    item.To   = newMovesArray[k].To;

                    moveTo = (int)item.To;
                    int destinationFigure = (int)opponent.figures[(int)item.To];
                    item.Value = (int)opponent.figures[(int)item.To];
                    item.Type  = BitBoardHelper.MoveTypes[(int)Figure.Pawn][destinationFigure][(int)item.From][moveTo];

                    if (wasLastMovePassing)
                    {
                        if (item.To == (Square)middle)
                        {
                            item.Type = MoveType.EpCapture;
                        }
                    }

                    if ((moveTo < 8) ||
                        (moveTo >= 56))
                    {
                        // add 4 moves
                        for (int m = 1; m < 4; ++m)
                        {
                            innerArray[index + m].From  = item.From;
                            innerArray[index + m].To    = item.To;
                            innerArray[index + m].Value = (int)opponent.figures[(int)item.To];
                        }

                        this.AddPromotionMoves(innerArray, index, (Figure)j);
                        index += 3;
                    }
                    else
                    {
                        item.Value += (int)item.Type;
                    }

                    index++;
                }
            }

            moves.Size = index;
            return(moves);
        }
示例#7
0
 public bool IsUnderCheck(PlayerBoard opponent)
 {
     return IsUnderAttack(this.King.GetSquare(), opponent);
 }
示例#8
0
        public bool IsUnderAttack(Square sq, PlayerBoard opponentBoard)
        {
            ulong occupied = 1UL << (int)sq;

            ulong pawnAttacks = opponentBoard.GetPawnAttacks();
            if ((occupied & pawnAttacks) != 0)
                return true;

            ulong knights = opponentBoard.bitboards[(int)Figure.Knight].GetInnerValue();
            ulong king = opponentBoard.bitboards[(int)Figure.King].GetInnerValue();
            ulong otherFigures = opponentBoard.allFigures | this.allFigures;
            otherFigures &= (~occupied);

            var knightAttackGenerator = this.attacksGenerators[(int)Figure.Knight];
            ulong occupiedKnightMoves = knightAttackGenerator.GetAttacks(sq, otherFigures);
            if ((occupiedKnightMoves & knights) != 0)
                return true;

            var kingAttackGenerator = this.attacksGenerators[(int)Figure.King];
            ulong occupiedKingMoves = kingAttackGenerator.GetAttacks(sq, otherFigures);
            if ((occupiedKingMoves & king) != 0)
                return true;

            ulong rooksQueens = opponentBoard.GetRooksQueens();
            ulong bishopsQueens = opponentBoard.GetBishopsQueens();

            var rookAttackGenerator = this.attacksGenerators[(int)Figure.Rook];
            ulong occupiedRookMoves = rookAttackGenerator.GetAttacks(sq, otherFigures);
            if ((occupiedRookMoves & rooksQueens) != 0)
                return true;

            var bishopAttackGenerator = this.attacksGenerators[(int)Figure.Bishop];
            ulong occupiedBishopMoves = bishopAttackGenerator.GetAttacks(sq, otherFigures);
            if ((occupiedBishopMoves & bishopsQueens) != 0)
                return true;

            return false;
        }
示例#9
0
        public FixedArray GetMoves(PlayerBoard opponent, Move lastMove, MovesMask movesMask)
        {
            FixedArray moves = this.allocator.CreateNewArray();
            var innerArray = moves.InnerArray;
            int index = 0;

            ulong mask = 0;
            if (movesMask == MovesMask.AllMoves)
                mask = ~this.allFigures;
            else
                mask = opponent.allFigures;

            var opponentFigures = opponent.allFigures;
            var otherFigures = opponentFigures | this.allFigures;

            // add knight, bishop, rook, queen moves
            for (int i = 0; i < PlayerBoard.KnightBishopRookQueen.Length; ++i)
            {
                var figure = PlayerBoard.KnightBishopRookQueen[i];
                var newMovesList = this.moveGenerators[(int)figure].GetMoves(otherFigures, mask);

                for (int j = 0; j < newMovesList.Count; ++j)
                {
                    var newMovesArray = newMovesList[j];

                    for (int k = 0; k < newMovesArray.Length; ++k)
                    {
                        var item = newMovesArray[k];
                        innerArray[index].From = item.From;
                        innerArray[index].To = item.To;

                        int destinationFigure = (int)opponent.figures[(int)item.To];
                        innerArray[index].Type =
                            BitBoardHelper.MoveTypes[(int)figure][destinationFigure][(int)item.From][(int)item.To];

                        innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight +
                            (int)opponent.figures[(int)item.To];

                        index++;
                    }
                }
            }

            // add king moves
            var kingMoves = this.GetKingMoves(opponent, mask, movesMask);

            for (int j = 0; j < kingMoves.Count; ++j)
            {
                var newMovesArray = kingMoves[j];

                for (int k = 0; k < newMovesArray.Length; ++k)
                {
                    var item = newMovesArray[k];
                    innerArray[index].From = item.From;
                    innerArray[index].To = item.To;
                    int destinationFigure = (int)opponent.figures[(int)item.To];

                    if (Math.Abs((int)item.From - (int)item.To) == 2)
                        innerArray[index].Type = MoveType.KingCastle;
                    else
                        innerArray[index].Type =
                            BitBoardHelper.MoveTypes[(int)Figure.King][destinationFigure][(int)item.From][(int)item.To];

                    innerArray[index].Value = (int)innerArray[index].Type * MoveTypeWeight +
                            (int)opponent.figures[(int)item.To];

                    index++;
                }
            }

            // add to mask value
            mask = opponent.allFigures;
            // pawn in passing state bit
            int lastFrom = (int)lastMove.From;
            int lastTo = (int)lastMove.To;
            int middle = (lastFrom + lastTo) >> 1;
            bool wasLastMovePassing = false;

            if (Math.Abs(lastFrom - lastTo) == 16)
                if (opponent.Pawns.IsBitSet(lastMove.To))
                {
                    mask |= 1UL << middle;
                    otherFigures |= mask;
                    wasLastMovePassing = true;
                }

            if (movesMask == MovesMask.Attacks)
            {
                ulong pawns = this.bitboards[(int)Figure.Pawn].GetInnerValue();
                otherFigures |= pawns >> 8;
                otherFigures |= pawns << 8;
            }

            // add pawns moves
            var pawnMoves = this.moveGenerators[(int)Figure.Pawn].GetMoves(otherFigures, mask);
            int moveTo;
            for (int j = 0; j < pawnMoves.Count; ++j)
            {
                var newMovesArray = pawnMoves[j];

                for (int k = 0; k < newMovesArray.Length; ++k)
                {
                    var item = innerArray[index];

                    item.From = newMovesArray[k].From;
                    item.To = newMovesArray[k].To;

                    moveTo = (int)item.To;
                    int destinationFigure = (int)opponent.figures[(int)item.To];
                    item.Value = (int)opponent.figures[(int)item.To];
                    item.Type = BitBoardHelper.MoveTypes[(int)Figure.Pawn][destinationFigure][(int)item.From][moveTo];

                    if (wasLastMovePassing)
                        if (item.To == (Square)middle)
                            item.Type = MoveType.EpCapture;

                    if ((moveTo < 8) ||
                        (moveTo >= 56))
                    {
                        // add 4 moves
                        for (int m = 1; m < 4; ++m)
                        {
                            innerArray[index + m].From = item.From;
                            innerArray[index + m].To = item.To;
                            innerArray[index + m].Value = (int)opponent.figures[(int)item.To];
                        }

                        this.AddPromotionMoves(innerArray, index, (Figure)j);
                        index += 3;
                    }
                    else
                        item.Value += (int)item.Type;

                    index++;
                }
            }

            moves.Size = index;
            return moves;
        }
示例#10
0
        public List<Move[]> GetKingMoves(PlayerBoard opponent, ulong mask, MovesMask movesMask)
        {
            var otherFigures = opponent.allFigures | this.allFigures;
            var list = this.moveGenerators[(int)Figure.King].GetMoves(otherFigures, mask);

            // ---------------------------------------------

            // castlings stuff

            // check king can move
            if (this.King.AlreadyMoved != 0)
                return list;

            var rooks = this.Rooks;
            // if rooks cannot move
            if (rooks.GetInnerProperty() == 0)
                return list;

            if (movesMask == MovesMask.Attacks)
                return list;

            var allMasks = KingBitBoardHelper.CastlingMasks;
            ulong[] castlingMasks = allMasks[(int)this.color][(int)this.position];

            bool leftIsEmpty = (castlingMasks[0] & otherFigures) == 0;
            bool rightIsEmpty = (castlingMasks[1] & otherFigures) == 0;

            // check other figures
            if (!(leftIsEmpty || rightIsEmpty))
                return list;

            bool noCheck;
            var squares = KingBitBoardHelper.CastlingSquares[(int)this.color][(int)this.position];
            int resultIndex = -1;
            // check checks
            if (leftIsEmpty && (rooks.LeftNotMoved != 0))
            {
                noCheck = true;
                for (int i = 0; i < squares[0].Length; ++i)
                {
                    if (this.IsUnderAttack(squares[0][i], opponent))
                    {
                        noCheck = false;
                        break;
                    }
                }
                if (noCheck)
                    resultIndex = 0;
            }

            if (rightIsEmpty && (rooks.RightNotMoved != 0))
            {
                noCheck = true;
                for (int i = 0; i < squares[1].Length; ++i)
                {
                    if (this.IsUnderAttack(squares[1][i], opponent))
                    {
                        noCheck = false;
                        break;
                    }
                }
                if (noCheck)
                    resultIndex += 2;
            }

            if (resultIndex != -1)
                list.Add(KingBitBoardHelper.CastlingMoves[(int)this.color][(int)this.position][resultIndex]);

            return list;
        }