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; } }
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); }
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); }
//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); }