public void TestKingRingMasks() { // King on e8. // Inner Ring var square = "e8"; var mask = Board.InnerRingMasks[(int)Board.GetSquare(square)]; WriteMessageLine($"King on {square} inner ring mask = "); WriteMessageLine(Position.ToString(mask)); Assert.That(Bitwise.IsBitSet(mask, Square.D8), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.D7), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.E7), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.F7), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.F8), Is.EqualTo(true)); mask &= Bitwise.CreateULongUnmask(Square.D8) & Bitwise.CreateULongUnmask(Square.D7) & Bitwise.CreateULongUnmask(Square.E7) & Bitwise.CreateULongUnmask(Square.F7) & Bitwise.CreateULongUnmask(Square.F8); Assert.That(mask & Bitwise.CreateULongMask((int)Square.A8, (int)Square.H1), Is.EqualTo(0)); // Outer Ring mask = Board.OuterRingMasks[(int)Board.GetSquare(square)]; WriteMessageLine($"King on {square} outer ring mask = "); WriteMessageLine(Position.ToString(mask)); Assert.That(Bitwise.IsBitSet(mask, Square.C8), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.C7), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.C6), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.D6), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.E6), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.F6), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.G6), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.G7), Is.EqualTo(true)); Assert.That(Bitwise.IsBitSet(mask, Square.G8), Is.EqualTo(true)); mask &= Bitwise.CreateULongUnmask(Square.C8) & Bitwise.CreateULongUnmask(Square.C7) & Bitwise.CreateULongUnmask(Square.C6) & Bitwise.CreateULongUnmask(Square.D6) & Bitwise.CreateULongUnmask(Square.E6) & Bitwise.CreateULongUnmask(Square.F6) & Bitwise.CreateULongUnmask(Square.G6) & Bitwise.CreateULongUnmask(Square.G7) & Bitwise.CreateULongUnmask(Square.G8); Assert.That(mask & Bitwise.CreateULongMask((int)Square.A8, (int)Square.H1), Is.EqualTo(0)); // King on c3. square = "c3"; mask = Board.InnerRingMasks[(int)Board.GetSquare(square)]; WriteMessageLine($"King on {square} inner ring mask = "); WriteMessageLine(Position.ToString(mask)); mask = Board.OuterRingMasks[(int)Board.GetSquare(square)]; WriteMessageLine($"King on {square} outer ring mask = "); WriteMessageLine(Position.ToString(mask)); }
// 6 6 6 6 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 // 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // To Horizon |Best From |Best To |BMP |Dynamic Score |DSP|Last // Best From = Best Move From (one extra bit for illegal square) // Best To = Best Move To (one extra bit for illegal square) // BMP = Best Move Promoted Piece // DSP = Dynamic Score Precision // Last = Last Accessed static CachedPositionData() { // Create bit shifts and masks. _toHorizonShift = 58; _toHorizonMask = Bitwise.CreateULongMask(58, 63); _toHorizonUnmask = Bitwise.CreateULongUnmask(58, 63); _bestMoveFromShift = 51; _bestMoveFromMask = Bitwise.CreateULongMask(51, 57); _bestMoveFromUnmask = Bitwise.CreateULongUnmask(51, 57); _bestMoveToShift = 44; _bestMoveToMask = Bitwise.CreateULongMask(44, 50); _bestMoveToUnmask = Bitwise.CreateULongUnmask(44, 50); _bestMovePromotedPieceShift = 40; _bestMovePromotedPieceMask = Bitwise.CreateULongMask(40, 43); _bestMovePromotedPieceUnmask = Bitwise.CreateULongUnmask(40, 43); _dynamicScoreShift = 10; _dynamicScoreMask = Bitwise.CreateULongMask(10, 39); _dynamicScoreUnmask = Bitwise.CreateULongUnmask(10, 39); _scorePrecisionShift = 8; _scorePrecisionMask = Bitwise.CreateULongMask(8, 9); _scorePrecisionUnmask = Bitwise.CreateULongUnmask(8, 9); _lastAccessedMask = Bitwise.CreateULongMask(0, 7); _lastAccessedUnmask = Bitwise.CreateULongUnmask(0, 7); }
// Move Bits // Higher priority moves have higher ulong value. // 6 6 6 6 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 // 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // B|CapV |CapA |Promo |Kil|History |!|O|K|E|2|P|To |From |Piece // B = Best Move // CapV = Capture Victim // CapA = Capture Attacker (inverted) // Promo = Promoted Piece // Kil = Killer Move // ! = Played // O = Castling // K = King Move // E = En Passant Capture // 2 = Double Pawn Move // P = Pawn Move // From = From (one extra bit for illegal square) // To = To (one extra bit for illegal square) static Move() { // Create bit masks and shifts. _bestShift = 63; _bestMask = Bitwise.CreateULongMask(63); _bestUnmask = Bitwise.CreateULongUnmask(63); _captureVictimShift = 59; _captureVictimMask = Bitwise.CreateULongMask(59, 62); _captureVictimUnmask = Bitwise.CreateULongUnmask(59, 62); _captureAttackerShift = 55; _captureAttackerMask = Bitwise.CreateULongMask(55, 58); _captureAttackerUnmask = Bitwise.CreateULongUnmask(55, 58); _promotedPieceShift = 51; _promotedPieceMask = Bitwise.CreateULongMask(51, 54); _promotedPieceUnmask = Bitwise.CreateULongUnmask(51, 54); _killerShift = 49; _killerMask = Bitwise.CreateULongMask(49, 50); _killerUnmask = Bitwise.CreateULongUnmask(49, 50); _historyShift = 24; _historyMask = Bitwise.CreateULongMask(24, 48); _historyUnmask = Bitwise.CreateULongUnmask(24, 48); _playedShift = 23; _playedMask = Bitwise.CreateULongMask(23); _playedUnmask = Bitwise.CreateULongUnmask(23); _castlingShift = 22; _castlingMask = Bitwise.CreateULongMask(22); _castlingUnmask = Bitwise.CreateULongUnmask(22); _kingMoveShift = 21; _kingMoveMask = Bitwise.CreateULongMask(21); _kingMoveUnmask = Bitwise.CreateULongUnmask(21); _enPassantShift = 20; _enPassantMask = Bitwise.CreateULongMask(20); _enPassantUnmask = Bitwise.CreateULongUnmask(20); _doublePawnMoveShift = 19; _doublePawnMoveMask = Bitwise.CreateULongMask(19); _doublePawnMoveUnmask = Bitwise.CreateULongUnmask(19); _pawnMoveShift = 18; _pawnMoveMask = Bitwise.CreateULongMask(18); _pawnMoveUnmask = Bitwise.CreateULongUnmask(18); _toShift = 11; _toMask = Bitwise.CreateULongMask(11, 17); _toUnmask = Bitwise.CreateULongUnmask(11, 17); _fromShift = 4; _fromMask = Bitwise.CreateULongMask(4, 10); _fromUnmask = Bitwise.CreateULongUnmask(4, 10); _pieceMask = Bitwise.CreateULongMask(0, 3); _pieceUnmask = Bitwise.CreateULongUnmask(0, 3); // Set null move. Null = 0; SetIsBest(ref Null, false); SetCaptureVictim(ref Null, Game.Piece.None); SetCaptureAttacker(ref Null, Game.Piece.None); SetPromotedPiece(ref Null, Game.Piece.None); SetKiller(ref Null, 0); SetHistory(ref Null, 0); SetPlayed(ref Null, false); SetIsCastling(ref Null, false); SetIsKingMove(ref Null, false); SetIsEnPassantCapture(ref Null, false); SetIsDoublePawnMove(ref Null, false); SetIsPawnMove(ref Null, false); SetTo(ref Null, Square.Illegal); SetFrom(ref Null, Square.Illegal); SetPiece(ref Null, Game.Piece.None); }