-
-
Notifications
You must be signed in to change notification settings - Fork 203
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into Support_impossible_checks_when_validate_po…
…sition
- Loading branch information
Showing
31 changed files
with
554 additions
and
744 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
version = "3.7.9" | ||
version = "3.7.10" | ||
runner.dialect = scala3 | ||
|
||
align.preset = more | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package chess | ||
package bitboard | ||
|
||
object Attacks: | ||
private val all = -1L | ||
|
||
private[bitboard] val RANKS = Array.fill(8)(0L) | ||
private[bitboard] val FILES = Array.fill(8)(0L) | ||
private[bitboard] val BETWEEN = Array.ofDim[Long](64, 64) | ||
private[bitboard] val RAYS = Array.ofDim[Long](64, 64) | ||
|
||
// Large overlapping attack table indexed using magic multiplication. | ||
private[bitboard] val ATTACKS = Array.fill(88772)(0L) | ||
private[bitboard] val KNIGHT_ATTACKS = Array.fill(64)(0L) | ||
private[bitboard] val KING_ATTACKS = Array.fill(64)(0L) | ||
private[bitboard] val WHITE_PAWN_ATTACKS = Array.fill(64)(0L) | ||
private[bitboard] val BLACK_PAWN_ATTACKS = Array.fill(64)(0L) | ||
|
||
private val KNIGHT_DELTAS = Array[Int](17, 15, 10, 6, -17, -15, -10, -6) | ||
private val BISHOP_DELTAS = Array[Int](7, -7, 9, -9) | ||
private val ROOK_DELTAS = Array[Int](1, -1, 8, -8) | ||
private val KING_DELTAS = Array[Int](1, 7, 8, 9, -1, -7, -8, -9) | ||
private val WHITE_PAWN_DELTAS = Array[Int](7, 9) | ||
private val BLACK_PAWN_DELTAS = Array[Int](-7, -9) | ||
|
||
/** Slow attack set generation. Used only to bootstrap the attack tables. | ||
*/ | ||
private def slidingAttacks(square: Int, occupied: Long, deltas: Array[Int]): Long = | ||
var attacks = 0L | ||
deltas.foreach: delta => | ||
var sq = square | ||
var i = 0 | ||
while | ||
i += 1 | ||
sq += delta | ||
val con = (sq < 0 || 64 <= sq || distance(sq, sq - delta) > 2) | ||
if !con then attacks |= 1L << sq | ||
|
||
!(occupied.contains(sq) || con) | ||
do () | ||
attacks | ||
|
||
private def initMagics(square: Int, magic: Magic, shift: Int, deltas: Array[Int]) = | ||
var subset = 0L | ||
while | ||
val attack = slidingAttacks(square, subset, deltas) | ||
val idx = ((magic.factor * subset) >>> (64 - shift)).toInt + magic.offset | ||
ATTACKS(idx) = attack | ||
|
||
// Carry-rippler trick for enumerating subsets. | ||
subset = (subset - magic.mask) & magic.mask | ||
|
||
subset != 0 | ||
do () | ||
|
||
private def initialize() = | ||
(0 until 8).foreach: i => | ||
RANKS(i) = 0xffL << (i * 8) | ||
FILES(i) = 0x0101010101010101L << i | ||
|
||
val squareRange = 0 until 64 | ||
squareRange.foreach: sq => | ||
KNIGHT_ATTACKS(sq) = slidingAttacks(sq, all, KNIGHT_DELTAS) | ||
KING_ATTACKS(sq) = slidingAttacks(sq, all, KING_DELTAS) | ||
WHITE_PAWN_ATTACKS(sq) = slidingAttacks(sq, all, WHITE_PAWN_DELTAS) | ||
BLACK_PAWN_ATTACKS(sq) = slidingAttacks(sq, all, BLACK_PAWN_DELTAS) | ||
|
||
initMagics(sq, Magic.ROOK(sq), 12, ROOK_DELTAS) | ||
initMagics(sq, Magic.BISHOP(sq), 9, BISHOP_DELTAS) | ||
|
||
for | ||
a <- squareRange | ||
b <- squareRange | ||
_ = | ||
if slidingAttacks(a, 0, ROOK_DELTAS).contains(b) then | ||
BETWEEN(a)(b) = slidingAttacks(a, 1L << b, ROOK_DELTAS) & slidingAttacks(b, 1L << a, ROOK_DELTAS) | ||
RAYS(a)(b) = | ||
(1L << a) | (1L << b) | slidingAttacks(a, 0, ROOK_DELTAS) & slidingAttacks(b, 0, ROOK_DELTAS) | ||
else if slidingAttacks(a, 0, BISHOP_DELTAS).contains(b) then | ||
BETWEEN(a)(b) = | ||
slidingAttacks(a, 1L << b, BISHOP_DELTAS) & slidingAttacks(b, 1L << a, BISHOP_DELTAS) | ||
RAYS(a)(b) = | ||
(1L << a) | (1L << b) | slidingAttacks(a, 0, BISHOP_DELTAS) & slidingAttacks(b, 0, BISHOP_DELTAS) | ||
yield () | ||
|
||
initialize() | ||
|
||
extension (l: Long) | ||
private def contains(s: Int): Boolean = | ||
(l & (1L << s)) != 0L | ||
|
||
private def distance(a: Int, b: Int): Int = | ||
inline def file(s: Int) = s & 7 | ||
inline def rank(s: Int) = s >>> 3 | ||
Math.max(Math.abs(file(a) - file(b)), Math.abs(rank(a) - rank(b))) |
Oops, something went wrong.