blob: afad90d08d51a1308b315e226708373bd87312a0 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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
}()
|