static BishopMoveTable() { var magicFinder = new MagicFinder(new MTRandom(0)); MagicMoveTableBuilder builder = new MagicMoveTableBuilder(magicFinder); foreach (var(file, rank) in Position.GetAllFilesRanks()) { AddMovesFromSquare(builder, file, rank); } BishopMoveMagicTable = builder.Build(); }
static PawnDoubleMoveTable() { DoubleMovesMagicTables = new MagicMoveTable[2]; var magicFinder = new MagicFinder(new MTRandom(0)); foreach (var color in new[] { Color.White, Color.Black }) { MagicMoveTableBuilder builder = new MagicMoveTableBuilder(magicFinder); foreach (var(file, rank) in Position.GetAllFilesRanks()) { AddMovesFromSquare(builder, file, rank, color); } DoubleMovesMagicTables[(int)color] = builder.Build(); } }
private static void AddMovesFromSquare(MagicMoveTableBuilder builder, int srcFile, int srcRank, Color color) { ulong mask = 0; List <ulong> occupancies = new List <ulong>(); List <ulong> moves = new List <ulong>(); int direction = color.GetPawnDirection(); var dstRank = srcRank + (direction * 2); var inbetweenRank = srcRank + direction; if (IsStartingRank(srcRank, color)) { mask |= Position.ValueFromFileRank(srcFile, inbetweenRank); mask |= Position.ValueFromFileRank(srcFile, dstRank); } int maskBits = Bits.PopCount(mask); int maskPermutations = 1 << maskBits; for (int permutation = 0; permutation < maskPermutations; permutation++) { ulong occupancy = Bits.ParallelBitDeposit((ulong)permutation, mask); ulong singularMoves = 0; // if there are any pieces in the 2 squares we're checking, then if (IsStartingRank(srcRank, color) && occupancy == 0) { singularMoves |= Position.ValueFromFileRank(srcFile, dstRank); } occupancies.Add(occupancy); moves.Add(singularMoves); } var ix = Position.IxFromFileRank(srcFile, srcRank); var info = new MagicMoveTable.Info { Magic = Magics[(int)color].GetOrDefault(ix), Mask = mask, MaskedOccupancyKeys = occupancies.ToArray(), MovesValues = moves.ToArray(), }; builder.Add(ix, info); }
private static void AddMovesFromSquare(MagicMoveTableBuilder builder, int srcFile, int srcRank) { ulong mask = 0; List <ulong> occupancies = new List <ulong>(); List <ulong> moves = new List <ulong>(); // populate mask // Note: mask rays don't extend to the edge of the map; this is because if a ray reaches all the way to the edge of the board, that square's occupancy doesn't affect move generation. // up/left for (int i = 1;; i++) { int dstFile = srcFile - i; int dstRank = srcRank + i; if (!InsideOuterRing(dstFile, dstRank)) { break; } mask |= Position.ValueFromFileRank(dstFile, dstRank); } // up/right for (int i = 1; ; i++) { int dstFile = srcFile + i; int dstRank = srcRank + i; if (!InsideOuterRing(dstFile, dstRank)) { break; } mask |= Position.ValueFromFileRank(dstFile, dstRank); } // down/left for (int i = 1; ; i++) { int dstFile = srcFile - i; int dstRank = srcRank - i; if (!InsideOuterRing(dstFile, dstRank)) { break; } mask |= Position.ValueFromFileRank(dstFile, dstRank); } // down/right for (int i = 1; ; i++) { int dstFile = srcFile + i; int dstRank = srcRank - i; if (!InsideOuterRing(dstFile, dstRank)) { break; } mask |= Position.ValueFromFileRank(dstFile, dstRank); } int maskBits = Bits.PopCount(mask); int maskPermutations = 1 << maskBits; for (int permutation = 0; permutation < maskPermutations; permutation++) { ulong occupancy = Bits.ParallelBitDeposit((ulong)permutation, mask); ulong singularMoves = 0; // Note: rays do now reach all the way to the edge of the board; we do want to generate moves that would reach the end of the board. // up/left for (int i = 1; ; i++) { int dstFile = srcFile - i; int dstRank = srcRank + i; if (!Position.FileRankOnBoard(dstFile, dstRank)) { break; } ulong move = Position.ValueFromFileRank(dstFile, dstRank); singularMoves |= move; if ((occupancy & move) > 0) { break; } } // up/right for (int i = 1; ; i++) { int dstFile = srcFile + i; int dstRank = srcRank + i; if (!Position.FileRankOnBoard(dstFile, dstRank)) { break; } ulong move = Position.ValueFromFileRank(dstFile, dstRank); singularMoves |= move; if ((occupancy & move) > 0) { break; } } // down/left for (int i = 1; ; i++) { int dstFile = srcFile - i; int dstRank = srcRank - i; if (!Position.FileRankOnBoard(dstFile, dstRank)) { break; } ulong move = Position.ValueFromFileRank(dstFile, dstRank); singularMoves |= move; if ((occupancy & move) > 0) { break; } } // down/right for (int i = 1; ; i++) { int dstFile = srcFile + i; int dstRank = srcRank - i; if (!Position.FileRankOnBoard(dstFile, dstRank)) { break; } ulong move = Position.ValueFromFileRank(dstFile, dstRank); singularMoves |= move; if ((occupancy & move) > 0) { break; } } occupancies.Add(occupancy); moves.Add(singularMoves); } var ix = Position.IxFromFileRank(srcFile, srcRank); var info = new MagicMoveTable.Info { Magic = Magics.GetOrDefault(ix), Mask = mask, MaskedOccupancyKeys = occupancies.ToArray(), MovesValues = moves.ToArray(), }; builder.Add(ix, info); }