aboutsummaryrefslogtreecommitdiff
path: root/Sources/SwiftChessNeo/Tables.swift
diff options
context:
space:
mode:
authorNavan Chauhan <navanchauhan@gmail.com>2024-04-17 12:02:38 -0600
committerNavan Chauhan <navanchauhan@gmail.com>2024-04-17 12:02:38 -0600
commite7e30f219c0129db7cb72f04e200098417ce25d0 (patch)
tree3d34da76f3a45e93d4d2fc31aad13a3712208e53 /Sources/SwiftChessNeo/Tables.swift
parentebfdb87512e7e32787b71e7a162ff109584f6fcf (diff)
initial commit
Diffstat (limited to 'Sources/SwiftChessNeo/Tables.swift')
-rw-r--r--Sources/SwiftChessNeo/Tables.swift114
1 files changed, 114 insertions, 0 deletions
diff --git a/Sources/SwiftChessNeo/Tables.swift b/Sources/SwiftChessNeo/Tables.swift
new file mode 100644
index 0000000..afad90d
--- /dev/null
+++ b/Sources/SwiftChessNeo/Tables.swift
@@ -0,0 +1,114 @@
+//
+// Tables.swift
+// Sage
+//
+// Copyright 2016-2017 Nikolai Vazquez
+// Modified by SuperGeroy
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+/// Returns the pawn attack table for `color`.
+internal func _pawnAttackTable(for color: Color) -> [Bitboard] {
+ if color.isWhite {
+ return _whitePawnAttackTable
+ } else {
+ return _blackPawnAttackTable
+ }
+}
+
+/// A lookup table of all white pawn attack bitboards.
+internal let _whitePawnAttackTable = Square.all.map { square in
+ return Bitboard(square: square)._pawnAttacks(for: ._white)
+}
+
+/// A lookup table of all black pawn attack bitboards.
+internal let _blackPawnAttackTable = Square.all.map { square in
+ return Bitboard(square: square)._pawnAttacks(for: ._black)
+}
+
+/// A lookup table of all king attack bitboards.
+internal let _kingAttackTable = Square.all.map { square in
+ return Bitboard(square: square)._kingAttacks()
+}
+
+/// A lookup table of all knight attack bitboards.
+internal let _knightAttackTable = Square.all.map { square in
+ return Bitboard(square: square)._knightAttacks()
+}
+
+/// Returns the squares between `start` and `end`.
+private func _between(_ start: Square, _ end: Square) -> Bitboard {
+ let start = UInt64(start.hashValue)
+ let end = UInt64(end.hashValue)
+ let max = UInt64.max
+ let a2a7: UInt64 = 0x0001010101010100
+ let b2g7: UInt64 = 0x0040201008040200
+ let h1b7: UInt64 = 0x0002040810204080
+
+ let between = (max << start) ^ (max << end)
+ let file = (end & 7) &- (start & 7)
+ let rank = ((end | 7) &- start) >> 3
+
+ var line = ((file & 7) &- 1) & a2a7
+ line += 2 &* (((rank & 7) &- 1) >> 58)
+ line += (((rank &- file) & 15) &- 1) & b2g7
+ line += (((rank &+ file) & 15) &- 1) & h1b7
+ line = line &* (between & (0 &- between))
+
+ return Bitboard(rawValue: line & between)
+}
+
+/// Returns the triangle index for `start` and `end`.
+internal func _triangleIndex(_ start: Square, _ end: Square) -> Int {
+ var a = start.hashValue
+ var b = end.hashValue
+ var d = a &- b
+ d &= d >> 31
+ b = b &+ d
+ a = a &- d
+ b = b &* (b ^ 127)
+ return (b >> 1) + a
+}
+
+/// A lookup table of squares between two squares.
+internal let _betweenTable: [Bitboard] = {
+ var table = [Bitboard](repeating: 0, count: 2080)
+ for start in Square.all {
+ for end in Square.all {
+ let index = _triangleIndex(start, end)
+ table[index] = _between(start, end)
+ }
+ }
+ return table
+}()
+
+/// A lookup table of lines for two squares.
+internal let _lineTable: [Bitboard] = {
+ var table = [Bitboard](repeating: 0, count: 2080)
+ for start in Square.all {
+ for end in Square.all {
+ let startBB = Bitboard(square: start)
+ let endBB = Bitboard(square: end)
+ let index = _triangleIndex(start, end)
+ let rookAttacks = startBB._rookAttacks()
+ let bishopAttacks = startBB._bishopAttacks()
+ if rookAttacks[end] {
+ table[index] = startBB | endBB | (rookAttacks & endBB._rookAttacks())
+ } else if bishopAttacks[end] {
+ table[index] = startBB | endBB | (bishopAttacks & endBB._bishopAttacks())
+ }
+ }
+ }
+ return table
+}()