Beispiel #1
0
        public void FilterMoves(FixedArray moves, Color playerColor)
        {
            var oppositeColor = 1 - (int)playerColor;
            var player        = this.playerBoards[(int)playerColor];
            var opponent      = this.playerBoards[oppositeColor];

            int index          = 0;
            int squeezed_index = 0;
            var innerArray     = moves.InnerArray;
            int size           = moves.Size;

            while (index < size)
            {
                var move = innerArray[index];

                if (move.Type == MoveType.KingCastle)
                {
                    innerArray[squeezed_index].From  = move.From;
                    innerArray[squeezed_index].To    = move.To;
                    innerArray[squeezed_index].Type  = move.Type;
                    innerArray[squeezed_index].Value = move.Value;
                    ++squeezed_index;
                    ++index;
                    continue;
                }

                this.ProcessMove(move, playerColor);

                // TODO write "from direction" method
                if (!player.IsUnderAttack(player.King.GetSquare(), opponent))
                {
                    innerArray[squeezed_index].From  = move.From;
                    innerArray[squeezed_index].To    = move.To;
                    innerArray[squeezed_index].Type  = move.Type;
                    innerArray[squeezed_index].Value = move.Value;
                    ++squeezed_index;
                }

                this.CancelLastMove(playerColor);

                ++index;
            }

            moves.Size = squeezed_index;
        }
Beispiel #2
0
        public MovesArrayAllocator(int historySize, int maxMovesSize)
        {
            this.HistorySize  = historySize;
            this.MaxMovesSize = maxMovesSize;

            AllocatedArrays = new FixedArray[HistorySize];
            for (int i = 0; i < HistorySize; ++i)
            {
                AllocatedArrays[i] = new FixedArray();
                var innerArray = new Move[MaxMovesSize];
                for (int j = 0; j < MaxMovesSize; ++j)
                {
                    innerArray[j] = new Move(Square.NoSquare, Square.NoSquare);
                }

                AllocatedArrays[i].InnerArray = innerArray;
            }

            CurrentIndex = -1;
        }
Beispiel #3
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);
        }