Beispiel #1
0
        public void BSFReturns63()
        {
            ulong test   = 0x8000000000000000;
            var   result = test.BitScanForward();

            Assert.Equal(63, result);
        }
        private IList <Move> GetPotentialJumpingMoves(Board board, ulong jumpingPieces, ulong jumpMask, int jumpMaskCenter, int piece)
        {
            var ownPieces = board.WhiteToMove ? board.WhitePieces : board.BlackPieces;
            var moves     = new List <Move>();

            while (jumpingPieces != 0)
            {
                var   i = jumpingPieces.BitScanForward();
                ulong jumps;
                if (i > jumpMaskCenter)
                {
                    jumps = jumpMask << (i - jumpMaskCenter);
                }
                else
                {
                    jumps = jumpMask >> (jumpMaskCenter - i);
                }

                jumps &= ~(i % 8 < 4 ? Board.Files[6] | Board.Files[7] : Board.Files[0] | Board.Files[1]);
                jumps &= ~ownPieces;

                foreach (var move in BitmaskToMoves(board, jumps, i, piece))
                {
                    moves.Add(move);
                }

                jumpingPieces &= ~(1UL << i);
            }
            return(moves);
        }
        private void GetPotentialJumpingMoves(Board board, Bitboard allowedTo, ulong jumpingPieces, Bitboard[] jumpTable, Piece piece, Move[] moves, ref int moveCount)
        {
            var ownPieces = board.WhiteToMove ? board.WhitePieces : board.BlackPieces;

            while (jumpingPieces != 0)
            {
                Position i     = jumpingPieces.BitScanForward();
                var      jumps = jumpTable[i];
                //Bitboard jumps;
                //if (i > jumpMaskCenter)
                //{
                //    jumps = jumpMask << (i - jumpMaskCenter);
                //}
                //else
                //{
                //    jumps = jumpMask >> (jumpMaskCenter - i);
                //}

                //jumps &= ~(i % 8 < 4 ? BitboardConstants.Files[6] | BitboardConstants.Files[7] : BitboardConstants.Files[0] | BitboardConstants.Files[1]);
                jumps &= ~ownPieces;
                jumps &= allowedTo;

                BitmaskToMoves(board, jumps, i, piece, moves, ref moveCount);

                jumpingPieces &= jumpingPieces - 1;
            }
        }
Beispiel #4
0
        private ulong GetAttackedBySlidingPieces(Board board, ulong slidingPieces, Func <Board, int, ulong> slideResolutionFunc)
        {
            var allSlide = 0UL;

            while (slidingPieces != 0)
            {
                var i     = slidingPieces.BitScanForward();
                var slide = slideResolutionFunc.Invoke(board, i);
                allSlide      |= slide;
                slidingPieces &= ~(1UL << i);
            }
            return(allSlide);
        }
        private IList <Move> GetPotentialSlidingPieceMoves(Board board, ulong slidingPieces, Func <Board, int, ulong> slideResolutionFunc, int piece)
        {
            var ownPieces = board.WhiteToMove ? board.WhitePieces : board.BlackPieces;
            var moves     = new List <Move>();

            while (slidingPieces != 0)
            {
                var i     = slidingPieces.BitScanForward();
                var slide = slideResolutionFunc.Invoke(board, i);
                slide &= ~ownPieces;
                foreach (var move in BitmaskToMoves(board, slide, i, piece))
                {
                    moves.Add(move);
                }
                slidingPieces &= ~(1UL << i);
            }
            return(moves);
        }
        bool next_idx(out int idx, ref uint offset, ref ulong v, Span <uint> mask, uint inDims)
        {
            while (v == 0)
            {
                offset += 8 * sizeof(ulong);
                if (offset >= inDims)
                {
                    idx = default;
                    return(false);
                }

                var offs  = (int)offset / 32 + 1;
                var offs2 = (int)offset / 32;
                v = (ulong)mask[offs] << 32 | mask[offs2];
                //memcpy(v, (char*)mask + (*offset / 8), sizeof(mask2_t));
            }
            idx = (int)offset + v.BitScanForward();
            v  &= v - 1;
            return(true);
        }
Beispiel #7
0
        private ulong GetAttackedByJumpingPieces(Board board, ulong jumpingPieces, ulong jumpMask, int jumpMaskCenter)
        {
            ulong allJumps = 0;

            while (jumpingPieces != 0)
            {
                var   i = jumpingPieces.BitScanForward();
                ulong jumps;
                if (i > jumpMaskCenter)
                {
                    jumps = jumpMask << (i - jumpMaskCenter);
                }
                else
                {
                    jumps = jumpMask >> (jumpMaskCenter - i);
                }

                jumps         &= ~(i % 8 < 4 ? Board.Files[6] | Board.Files[7] : Board.Files[0] | Board.Files[1]);
                allJumps      |= jumps;
                jumpingPieces &= ~(1UL << i);
            }
            return(allJumps);
        }
Beispiel #8
0
        //evaluates exchanges on a square initiated by stm
        public static int Eval(Board b, Move m, int stm)
        {
            ulong[] attackers = new ulong[2];
            int     score     = 0;
            var     sq        = m.To;
            var     pieceVal  = Evaluator.PieceValueOnSquare(b, sq);
            var     attacks   = MoveGenerator.Attacks(b, sq);
            var     mystm     = stm ^ 1;

            attackers[mystm] = attacks & b.Pieces[mystm];
            attackers[stm]   = attacks & b.Pieces[stm];

            //change the pieceVal to be the new piece

            //if there is a promotion, then stm is already up material
            if (m.Promotion > 0)
            {
                pieceVal = Evaluator.PieceValues[m.Promotion];
                score    = pieceVal - 100; //lose the initial pawn
            }
            else
            {
                pieceVal = Evaluator.PieceValues[(int)Move.GetPiece((MoveBits)m.Bits)];
            }

            //add in any material taken on the first capture
            if ((m.Bits & (byte)MoveBits.Capture) > 0)
            {
                score += Evaluator.PieceValueOnSquare(b, m.To);
            }

            //remove the first Move, unless this was a straight pawn push
            if (!((m.Bits & (byte)MoveBits.Pawn) > 0 && Math.Abs(m.From - m.To) == 8))
            {
                attackers[stm] ^= BitMask.Mask[m.From];
            }

            while (attackers[mystm] > 0)
            {
                var  tempAttackers = attackers[mystm];
                var  leastValuable = int.MaxValue;
                int  leastValSq = -1;
                bool promote, promoting = false;

                //make a pass over the attackers to find the lowest valued piece
                while (tempAttackers > 0)
                {
                    promote = false;
                    var attack_sq = tempAttackers.BitScanForward();
                    tempAttackers ^= BitMask.Mask[attack_sq];
                    var attackerVal = Evaluator.PieceValueOnSquare(b, attack_sq);

                    //if we found a pawn capturing onto the 8th rank, we need to consider promotion
                    if (attackerVal == 100 && (sq.Rank() == 0 || sq.Rank() == 7))
                    {
                        //we will treat this attacker as if it were a queen
                        attackerVal = Evaluator.PieceValues[(int)Piece.Queen];
                        promote     = true;
                    }

                    if (attackerVal < leastValuable)
                    {
                        promoting     = promote;
                        leastValSq    = attack_sq;
                        leastValuable = attackerVal;
                    }
                }

                //now we have the least valuable attacker
                //remove whatever value is on the square
                if (mystm == stm)
                {
                    score += pieceVal;
                    if (promoting)
                    {
                        score += leastValuable - 100;//lose the promoting pawn, add in queen
                    }
                }
                else
                {
                    score -= pieceVal;
                    if (promoting)
                    {
                        score -= leastValuable + 100;//lose the promoting pawn, add in queen
                    }
                }

                //update the attacked piece
                pieceVal = leastValuable;

                //remove the attacker
                attackers[mystm] ^= BitMask.Mask[leastValSq];

                //now we check for x-ray attacks
                //the idea here is that if any rooks, queens, or bishops attack the temporary
                //square from the same direction that the temporary square is attacking the target
                //then we have an xray attacker
                var   direction   = MoveGenerator.Directions[leastValSq, sq];
                ulong xrayAttacks = 0;
                switch (Math.Abs(direction))
                {
                case 1:
                case 8:
                    if (((b.Rooks[mystm] | b.Queens[mystm]) & Board.FileMask[sq.File()]) > 0)
                    {
                        xrayAttacks = MoveGenerator.RookAttacks(b, leastValSq) & (b.Rooks[mystm] | b.Queens[mystm]) & attackers[mystm];
                    }
                    break;

                case 7:
                case 9:
                    xrayAttacks = MoveGenerator.BishopAttacks(b, leastValSq) & (b.Bishops[mystm] | b.Queens[mystm]) & attackers[mystm];
                    break;
                }

                while (xrayAttacks > 0)
                {
                    var xraySq = xrayAttacks.BitScanForward();
                    xrayAttacks ^= BitMask.Mask[xraySq];
                    if (MoveGenerator.Directions[xraySq, sq] == direction)
                    {
                        //put this piece in main attackers bitboard
                        attackers[mystm] |= BitMask.Mask[xraySq];
                    }
                }
                //switch stm
                mystm ^= 1;
            }

            return(score);
        }