public void Add(int ix, MagicMoveTable.Info info) { Debug.Assert(ix >= 0 && ix < 64); if (!MagicFinder.CheckMagic(info.Mask, info.Magic)) { // we don't need to warn that magic was invalid if they didn't provide a magic if (info.Magic != 0) { _magicFailed = true; } info.Magic = _magicFinder.FindMagic(info.Mask); } _infos.Add(ix, info); }
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); }