Update-Chess
This commit is contained in:
@@ -6,6 +6,39 @@ B_KIN, B_QUE, B_BIS, B_NHT, B_ROO, B_PAW = range(6,12)
|
|||||||
WHITE, BLACK = 0, 1
|
WHITE, BLACK = 0, 1
|
||||||
# Piece Constants
|
# Piece Constants
|
||||||
KIN, QUE, BIS, NHT, ROO, PAW = range(6)
|
KIN, QUE, BIS, NHT, ROO, PAW = range(6)
|
||||||
|
NO_PIECE = 15
|
||||||
|
|
||||||
|
# 0 = Normaler Zug (Quiet Move)
|
||||||
|
QUIET = 0
|
||||||
|
|
||||||
|
# 1 = Doppelschritt Bauer (wichtig für En Passant im nächsten Zug)
|
||||||
|
DOUBLE_PAWN_PUSH = 1
|
||||||
|
|
||||||
|
# 2 & 3 = Rochaden
|
||||||
|
KING_CASTLE = 2
|
||||||
|
QUEEN_CASTLE = 3
|
||||||
|
|
||||||
|
# 4 = Normaler Schlagzug (Capture)
|
||||||
|
# Manche Engines codieren Captures extra, manche schauen einfach aufs Brett.
|
||||||
|
# Für den Anfang reicht es, Captures einfach als Flag 4 zu markieren.
|
||||||
|
CAPTURE = 4
|
||||||
|
|
||||||
|
# 5 = En Passant Schlag
|
||||||
|
EP_CAPTURE = 5
|
||||||
|
|
||||||
|
# 8-15 = Umwandlungen (Promotion)
|
||||||
|
# Struktur: 8 + Figur (Springer=0, Läufer=1, Turm=2, Dame=3)
|
||||||
|
PROMO_KNIGHT = 8
|
||||||
|
PROMO_BISHOP = 9
|
||||||
|
PROMO_ROOK = 10
|
||||||
|
PROMO_QUEEN = 11
|
||||||
|
|
||||||
|
# Umwandlung mit Schlagen (optional, spart Zeit beim Checken)
|
||||||
|
PROMO_N_CAPTURE = 12
|
||||||
|
PROMO_B_CAPTURE = 13
|
||||||
|
PROMO_R_CAPTURE = 14
|
||||||
|
PROMO_Q_CAPTURE = 15
|
||||||
|
|
||||||
# Square Constants
|
# Square Constants
|
||||||
A8, B8, C8, D8, E8, F8, G8, H8 = range(56, 64)
|
A8, B8, C8, D8, E8, F8, G8, H8 = range(56, 64)
|
||||||
A7, B7, C7, D7, E7, F7, G7, H7 = range(48, 56)
|
A7, B7, C7, D7, E7, F7, G7, H7 = range(48, 56)
|
||||||
@@ -22,17 +55,6 @@ NOT_AB = 0xfcfcfcfcfcfcfcfc
|
|||||||
NOT_GH = 0x3f3f3f3f3f3f3f3f
|
NOT_GH = 0x3f3f3f3f3f3f3f3f
|
||||||
FULL_MASK = 0xffffffffffffffff
|
FULL_MASK = 0xffffffffffffffff
|
||||||
|
|
||||||
INDEX_TO_FIELD = [
|
|
||||||
"a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1",
|
|
||||||
"a2", "b2", "c2", "d2", "e2", "f2", "g2", "h2",
|
|
||||||
"a3", "b3", "c3", "d3", "e3", "f3", "g3", "h3",
|
|
||||||
"a4", "b4", "c4", "d4", "e4", "f4", "g4", "h4",
|
|
||||||
"a5", "b5", "c5", "d5", "e5", "f5", "g5", "h5",
|
|
||||||
"a6", "b6", "c6", "d6", "e6", "f6", "g6", "h6",
|
|
||||||
"a7", "b7", "c7", "d7", "e7", "f7", "g7", "h7",
|
|
||||||
"a8", "b8", "c8", "d8", "e8", "f8", "g8", "h8",
|
|
||||||
]
|
|
||||||
|
|
||||||
class Bitboard():
|
class Bitboard():
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
||||||
@@ -56,83 +78,152 @@ class Bitboard():
|
|||||||
self.bitboards[B_NHT] = (1 << B8) | (1 << G8)
|
self.bitboards[B_NHT] = (1 << B8) | (1 << G8)
|
||||||
self.bitboards[B_ROO] = (1 << A8) | (1 << H8)
|
self.bitboards[B_ROO] = (1 << A8) | (1 << H8)
|
||||||
self.bitboards[B_PAW] = 0xFF << 48
|
self.bitboards[B_PAW] = 0xFF << 48
|
||||||
|
|
||||||
self.all_white = self.bitboards[W_KIN] | self.bitboards[W_QUE] | self.bitboards[W_BIS] | self.bitboards[W_NHT] | self.bitboards[W_ROO] | self.bitboards[W_PAW]
|
self.all_pieces = []
|
||||||
self.all_black = self.bitboards[W_KIN] | self.bitboards[W_QUE] | self.bitboards[W_BIS] | self.bitboards[W_NHT] | self.bitboards[W_ROO] | self.bitboards[W_PAW]
|
self.all_pieces[0] = self.bitboards[W_KIN] | self.bitboards[W_QUE] | self.bitboards[W_BIS] | self.bitboards[W_NHT] | self.bitboards[W_ROO] | self.bitboards[W_PAW]
|
||||||
self.all_piece = self.all_white | self.all_black
|
self.all_pieces[1] = self.bitboards[W_KIN] | self.bitboards[W_QUE] | self.bitboards[W_BIS] | self.bitboards[W_NHT] | self.bitboards[W_ROO] | self.bitboards[W_PAW]
|
||||||
|
|
||||||
self.move_list = []
|
self.move_list = []
|
||||||
|
|
||||||
def get_all_moves(self):
|
def get_all_moves(self):
|
||||||
turn_offset = self.side_to_move * 6
|
turn_offset = self.side_to_move * 6
|
||||||
|
opponent_pcs = self.all_pieces[not self.side_to_move]
|
||||||
|
friendly_pcs = self.all_pieces[self.side_to_move]
|
||||||
|
|
||||||
|
|
||||||
move_list = []
|
move_list = []
|
||||||
|
|
||||||
# King Moves
|
# King Moves
|
||||||
king = self.bitboards[KIN]
|
kin_sq = self.bitboards[KIN + turn_offset].bit_length() - 1
|
||||||
king_moves = 0
|
kin_moves = KIN_ATTACKS[kin_sq]
|
||||||
king_moves = (king & NOT_A) >> 1 | (king & NOT_A) << 7 | king << 8 | (king & NOT_H) << 9 | (king & NOT_H) << 1 | (king & NOT_H) >> 7 | king >> 8 | (king & NOT_A) >> 9
|
kin_moves &= ~friendly_pcs
|
||||||
king_moves &= FULL_MASK
|
|
||||||
|
while kin_moves:
|
||||||
|
flag = 0
|
||||||
|
to_sq = (kin_moves & -kin_moves).bit_length() - 1
|
||||||
|
move_list.append(to_sq | (kin_sq << 6) | flag << 12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_move(self, move):
|
def make_move(self, move):
|
||||||
# Setup
|
# Setup
|
||||||
# Bit 0-5: Target (6 Bit, Index: 0-63)
|
# Bit 0-5: Target (6 Bit, Index: 0-63)
|
||||||
# Bit 6-11: Source (6 Bit, Index: 0-63)
|
# Bit 6-11: Source (6 Bit, Index: 0-63)
|
||||||
# Bit 12-15: Flags (4 Bit)
|
# Bit 12-15: Piece moved (4 Bit) 0-11: W_KIN-B_PAW
|
||||||
# 0000: 0 Quiet 0100: 4 Capture 1000: 8 Promo NHT
|
# Bit 16-19: Piece Captured (4 Bit) 0-11: W_KIN-B_PAW, 15: Nothing
|
||||||
# 0001: 1 Double Pawn Push 0101: 5 En Passant 1001: 9 Promo BIS
|
#
|
||||||
# 0010: 2 King Castle 0110: 1010: 10 Promo ROO
|
# Bit 20-23: Flags (4 Bit)
|
||||||
# 0011: 3 Queen Castle 0111: 1011: 11 Promo QUE
|
# 0000: 0 Quiet 0100: 4 Capture 1000: 8 Promo NHT
|
||||||
|
# 0001: 1 Double Pawn Push 0101: 5 En Passant 1001: 9 Promo BIS
|
||||||
|
# 0010: 2 King Castle 0110: 1010: 10 Promo ROO
|
||||||
|
# 0011: 3 Queen Castle 0111: 1011: 11 Promo QUE
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def encode_move(start_sq, end_sq, flag):
|
||||||
|
move = 0
|
||||||
|
move |= end_sq
|
||||||
|
move |= start_sq << 6
|
||||||
|
move |= flag << 12
|
||||||
|
return move
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# move_constants.py
|
||||||
|
|
||||||
KIN_ATTACKS = [0] * 64
|
KIN_ATTACKS = [0] * 64
|
||||||
NHT_ATTACKS = [0] * 64
|
NHT_ATTACKS = [0] * 64
|
||||||
|
|
||||||
PAW_ATTACKS = [0] * 128 # 0-63 für Weiße Bauern, 64-127 für Schwarze Bauern
|
PAW_ATTACKS = [0] * 128 # 0-63 für Weiße Bauern, 64-127 für Schwarze Bauern
|
||||||
|
|
||||||
RAY_N = [0] * 64
|
|
||||||
RAY_NE = [0] * 64
|
|
||||||
RAY_E = [0] * 64
|
RAYS_N = [0] * 64
|
||||||
RAY_SE = [0] * 64
|
RAYS_NE = [0] * 64
|
||||||
RAY_S = [0] * 64
|
RAYS_E = [0] * 64
|
||||||
RAY_SW = [0] * 64
|
RAYS_SE = [0] * 64
|
||||||
RAY_W = [0] * 64
|
RAYS_S = [0] * 64
|
||||||
RAY_NW = [0] * 64
|
RAYS_SW = [0] * 64
|
||||||
|
RAYS_W = [0] * 64
|
||||||
|
RAYS_NW = [0] * 64
|
||||||
|
|
||||||
def initialize():
|
def initialize():
|
||||||
|
'''
|
||||||
|
Calculate all Attack patterns and Rays
|
||||||
|
'''
|
||||||
for sq in range(64):
|
for sq in range(64):
|
||||||
|
bit = 1 << sq
|
||||||
|
# --- Pieces ---
|
||||||
# King
|
# King
|
||||||
kin = 1 << sq
|
kin_attacks = (bit & NOT_A) << 7 | bit << 8 | (bit & NOT_H) << 9 | (bit & NOT_H) << 1 | \
|
||||||
kin_attacks = (kin & NOT_A) << 7 | kin << 8 | (kin & NOT_H) << 9 | (kin & NOT_H) << 1 | \
|
(bit & NOT_H) >> 7 | bit >> 8 | (bit & NOT_A) >> 9 | (bit & NOT_A) >> 1
|
||||||
(kin & NOT_H) >> 7 | kin >> 8 | (kin & NOT_A) >> 9 | (kin & NOT_A) >> 1
|
|
||||||
KIN_ATTACKS[sq] = kin_attacks & FULL_MASK
|
KIN_ATTACKS[sq] = kin_attacks & FULL_MASK
|
||||||
|
|
||||||
# Knight
|
# Knight
|
||||||
nht = 1 << sq
|
nht_attacks = (bit & NOT_AB) << 6 | (bit & NOT_A) << 15 | (bit & NOT_H) << 17 | (bit & NOT_GH) << 10 | \
|
||||||
nht_attacks = (nht & NOT_AB) << 6 | (nht & NOT_A) << 15 | (nht & NOT_H) << 17 | (nht & NOT_GH) << 10 | \
|
(bit & NOT_GH) >> 6 | (bit & NOT_H) >> 15 | (bit & NOT_A) >> 17 | (bit & NOT_AB) >> 10
|
||||||
(nht & NOT_GH) >> 6 | (nht & NOT_H) >> 15 | (nht & NOT_A) >> 17 | (nht & NOT_AB) >> 10
|
|
||||||
NHT_ATTACKS[sq] = nht_attacks & FULL_MASK
|
NHT_ATTACKS[sq] = nht_attacks & FULL_MASK
|
||||||
|
|
||||||
# Pawns
|
# Pawns
|
||||||
paw = 1 << sq
|
w_attacks = (bit & NOT_A) << 7 | (bit & NOT_H) << 9
|
||||||
|
|
||||||
w_attacks = (paw & NOT_A) << 7 | (paw & NOT_H) << 9
|
|
||||||
PAW_ATTACKS[sq] = w_attacks & FULL_MASK
|
PAW_ATTACKS[sq] = w_attacks & FULL_MASK
|
||||||
|
|
||||||
b_attacks = (paw & NOT_A) >> 9 | (paw & NOT_H) >> 7
|
b_attacks = (bit & NOT_A) >> 9 | (bit & NOT_H) >> 7
|
||||||
PAW_ATTACKS[sq + 64] = b_attacks & FULL_MASK
|
PAW_ATTACKS[sq + 64] = b_attacks & FULL_MASK
|
||||||
|
|
||||||
# Rays
|
# --- Rays ---
|
||||||
# North
|
r, f = sq // 8, sq % 8
|
||||||
|
|
||||||
|
# North (r+)
|
||||||
|
RAYS_N[sq] = 0
|
||||||
|
for i in range(r + 1, 8):
|
||||||
|
RAYS_N[sq] |= (1 << (i * 8 + f))
|
||||||
|
|
||||||
|
# South (r-)
|
||||||
|
RAYS_S[sq] = 0
|
||||||
|
for i in range(r - 1, -1, -1):
|
||||||
|
RAYS_S[sq] |= (1 << (i * 8 + f))
|
||||||
|
|
||||||
|
# East (f+)
|
||||||
|
RAYS_E[sq] = 0
|
||||||
|
for i in range(f + 1, 8):
|
||||||
|
RAYS_E[sq] |= (1 << (r * 8 + i))
|
||||||
|
|
||||||
|
# West (f-)
|
||||||
|
RAYS_W[sq] = 0
|
||||||
|
for i in range(f - 1, -1, -1):
|
||||||
|
RAYS_W[sq] |= (1 << (r * 8 + i))
|
||||||
|
|
||||||
|
# North-East (r+, f+)
|
||||||
|
RAYS_NE[sq] = 0
|
||||||
|
i, j = r + 1, f + 1
|
||||||
|
while i < 8 and j < 8:
|
||||||
|
RAYS_NE[sq] |= (1 << (i * 8 + j))
|
||||||
|
i += 1; j += 1
|
||||||
|
|
||||||
|
# North-West (r+, f-)
|
||||||
|
RAYS_NW[sq] = 0
|
||||||
|
i, j = r + 1, f - 1
|
||||||
|
while i < 8 and j >= 0:
|
||||||
|
RAYS_NW[sq] |= (1 << (i * 8 + j))
|
||||||
|
i += 1; j -= 1
|
||||||
|
|
||||||
|
# South-East (r-, f+)
|
||||||
|
RAYS_SE[sq] = 0
|
||||||
|
i, j = r - 1, f + 1
|
||||||
|
while i >= 0 and j < 8:
|
||||||
|
RAYS_SE[sq] |= (1 << (i * 8 + j))
|
||||||
|
i -= 1; j += 1
|
||||||
|
|
||||||
|
# South-West (r-, f-)
|
||||||
|
RAYS_SW[sq] = 0
|
||||||
|
i, j = r - 1, f - 1
|
||||||
|
while i >= 0 and j >= 0:
|
||||||
|
RAYS_SW[sq] |= (1 << (i * 8 + j))
|
||||||
|
i -= 1; j -= 1
|
||||||
|
|
||||||
''' Board Index:
|
''' Board Index:
|
||||||
a b c d e f g h
|
a b c d e f g h
|
||||||
@@ -147,3 +238,4 @@ def initialize():
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user