Compare commits
4 Commits
46d9d142e8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86b537e3eb | ||
|
|
3be3030a37 | ||
|
|
bbe3a648fb | ||
|
|
0ba7a7c8a0 |
@@ -1,5 +1,6 @@
|
|||||||
|
from cmd import PROMPT
|
||||||
|
import os
|
||||||
# region Constants
|
# region Constants
|
||||||
|
|
||||||
# White Constants
|
# White Constants
|
||||||
W_KIN, W_QUE, W_BIS, W_NHT, W_ROO, W_PAW = range(6)
|
W_KIN, W_QUE, W_BIS, W_NHT, W_ROO, W_PAW = range(6)
|
||||||
# Black Constans
|
# Black Constans
|
||||||
@@ -10,7 +11,18 @@ WHITE, BLACK = 0, 1
|
|||||||
KIN, QUE, BIS, NHT, ROO, PAW = range(6)
|
KIN, QUE, BIS, NHT, ROO, PAW = range(6)
|
||||||
NO_PIECE = 15
|
NO_PIECE = 15
|
||||||
|
|
||||||
PIECE_TO_STR = ["wK", "wQ", "wB", "wN", "wR", "wP", "bK", "bQ", "bB", "bN", "bR", "bP"]
|
class COL():
|
||||||
|
FG_WHITE = "\033[38;5;253m"
|
||||||
|
FG_BLACK = "\033[38;5;232m"
|
||||||
|
BG_WHITE = "\033[48;5;230m"
|
||||||
|
BG_DARK = "\033[48;5;71m"
|
||||||
|
BG_MOVE = "\033[48;5;249m"
|
||||||
|
RESET = "\033[0m"
|
||||||
|
|
||||||
|
PIECE_TO_STR = ["wK", "wQ", "wB", "wN", "wR", "wP",
|
||||||
|
"bK", "bQ", "bB", "bN", "bR", "bP"]
|
||||||
|
PIECE_TO_SYM = ["♔", "♕", "♗", "♘", "♖", "♙",
|
||||||
|
"♚", "♛", "♝", "♞", "♜", "♟"]
|
||||||
|
|
||||||
# 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)
|
||||||
@@ -22,6 +34,21 @@ A3, B3, C3, D3, E3, F3, G3, H3 = range(16, 24)
|
|||||||
A2, B2, C2, D2, E2, F2, G2, H2 = range(8, 16)
|
A2, B2, C2, D2, E2, F2, G2, H2 = range(8, 16)
|
||||||
A1, B1, C1, D1, E1, F1, G1, H1 = range(8)
|
A1, B1, C1, D1, E1, F1, G1, H1 = range(8)
|
||||||
|
|
||||||
|
# Convert Piece to number
|
||||||
|
PCE_TO_NUM = {"K":0, "Q":1, "B":2, "N":3, "R":4, "P":5}
|
||||||
|
|
||||||
|
# Convert Field to index
|
||||||
|
STR_TO_SQ = {}
|
||||||
|
files = "ABCDEFGH" # Oder "abcdefgh" je nach UCI Standard
|
||||||
|
ranks = "12345678"
|
||||||
|
|
||||||
|
for r_idx, r in enumerate(ranks):
|
||||||
|
for f_idx, f in enumerate(files):
|
||||||
|
# Berechne Index (Little Endian: A1=0, B1=1 ... H8=63)
|
||||||
|
sq = r_idx * 8 + f_idx
|
||||||
|
key = f + r # z.B. "A1"
|
||||||
|
STR_TO_SQ[key] = sq
|
||||||
|
|
||||||
# Move Flags
|
# Move Flags
|
||||||
QUIET = 0
|
QUIET = 0
|
||||||
DOUBLE_PAWN_PUSH = 1
|
DOUBLE_PAWN_PUSH = 1
|
||||||
@@ -57,6 +84,9 @@ RAYS_S = [0] * 64
|
|||||||
RAYS_SW = [0] * 64
|
RAYS_SW = [0] * 64
|
||||||
RAYS_W = [0] * 64
|
RAYS_W = [0] * 64
|
||||||
RAYS_NW = [0] * 64
|
RAYS_NW = [0] * 64
|
||||||
|
|
||||||
|
clear = lambda: os.system('clear')
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
class Bitboard():
|
class Bitboard():
|
||||||
@@ -68,6 +98,7 @@ class Bitboard():
|
|||||||
0, 0, 0, 0, 0, 0]
|
0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
self.side_to_move = WHITE
|
self.side_to_move = WHITE
|
||||||
|
self.playing = True
|
||||||
|
|
||||||
self.bitboards[W_KIN] = 1 << E1
|
self.bitboards[W_KIN] = 1 << E1
|
||||||
self.bitboards[W_QUE] = 1 << D1
|
self.bitboards[W_QUE] = 1 << D1
|
||||||
@@ -345,6 +376,145 @@ class Bitboard():
|
|||||||
# endregion
|
# endregion
|
||||||
# endregion Bishop Moves
|
# endregion Bishop Moves
|
||||||
|
|
||||||
|
# region --- Rook Moves ---
|
||||||
|
|
||||||
|
roo_bb = bbs [roo + turn_offset]
|
||||||
|
while roo_bb:
|
||||||
|
roo_sq = (roo_bb & -roo_bb).bit_length() -1
|
||||||
|
roo_bb &= (roo_bb -1)
|
||||||
|
|
||||||
|
# region North
|
||||||
|
ray = rays_n[roo_sq]
|
||||||
|
blockers = ray & occupancy
|
||||||
|
if blockers:
|
||||||
|
blocker_sq = blockers.bit_length() - 1
|
||||||
|
ray_to_del = rays_n[blocker_sq]
|
||||||
|
roo_attacks = (ray ^ ray_to_del) & ~friendly_pcs
|
||||||
|
else:
|
||||||
|
roo_attacks = ray
|
||||||
|
|
||||||
|
while roo_attacks:
|
||||||
|
to_sq = (roo_attacks & -roo_attacks).bit_length() - 1
|
||||||
|
to_mask = 1 << to_sq
|
||||||
|
roo_attacks &= (roo_attacks - 1)
|
||||||
|
|
||||||
|
if to_mask & opponent_pcs:
|
||||||
|
if to_mask & bbs[paw + opp_offset]:
|
||||||
|
captured = paw + opp_offset
|
||||||
|
elif to_mask & bbs[nht + opp_offset]:
|
||||||
|
captured = nht + opp_offset
|
||||||
|
elif to_mask & bbs[bis + opp_offset]:
|
||||||
|
captured = bis + opp_offset
|
||||||
|
elif to_mask & bbs[roo + opp_offset]:
|
||||||
|
captured = roo + opp_offset
|
||||||
|
else:
|
||||||
|
captured = que + opp_offset
|
||||||
|
captures.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (captured << 16) | capture << 20)
|
||||||
|
else:
|
||||||
|
moves.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (no_piece << 16) | quiet << 20)
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region East
|
||||||
|
ray = rays_e[roo_sq]
|
||||||
|
blockers = ray & occupancy
|
||||||
|
if blockers:
|
||||||
|
blocker_sq = blockers.bit_length() - 1
|
||||||
|
ray_to_del = rays_e[blocker_sq]
|
||||||
|
roo_attacks = (ray ^ ray_to_del) & ~friendly_pcs
|
||||||
|
else:
|
||||||
|
roo_attacks = ray
|
||||||
|
|
||||||
|
while roo_attacks:
|
||||||
|
to_sq = (roo_attacks & -roo_attacks).bit_length() - 1
|
||||||
|
to_mask = 1 << to_sq
|
||||||
|
roo_attacks &= (roo_attacks - 1)
|
||||||
|
|
||||||
|
if to_mask & opponent_pcs:
|
||||||
|
if to_mask & bbs[paw + opp_offset]:
|
||||||
|
captured = paw + opp_offset
|
||||||
|
elif to_mask & bbs[nht + opp_offset]:
|
||||||
|
captured = nht + opp_offset
|
||||||
|
elif to_mask & bbs[bis + opp_offset]:
|
||||||
|
captured = bis + opp_offset
|
||||||
|
elif to_mask & bbs[roo + opp_offset]:
|
||||||
|
captured = roo + opp_offset
|
||||||
|
else:
|
||||||
|
captured = que + opp_offset
|
||||||
|
captures.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (captured << 16) | capture << 20)
|
||||||
|
else:
|
||||||
|
moves.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (no_piece << 16) | quiet << 20)
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region South
|
||||||
|
ray = rays_s[roo_sq]
|
||||||
|
blockers = ray & occupancy
|
||||||
|
if blockers:
|
||||||
|
blocker_sq = blockers.bit_length() - 1
|
||||||
|
ray_to_del = rays_s[blocker_sq]
|
||||||
|
roo_attacks = (ray ^ ray_to_del) & ~friendly_pcs
|
||||||
|
else:
|
||||||
|
roo_attacks = ray
|
||||||
|
|
||||||
|
while roo_attacks:
|
||||||
|
to_sq = (roo_attacks & -roo_attacks).bit_length() - 1
|
||||||
|
to_mask = 1 << to_sq
|
||||||
|
roo_attacks &= (roo_attacks - 1)
|
||||||
|
|
||||||
|
if to_mask & opponent_pcs:
|
||||||
|
if to_mask & bbs[paw + opp_offset]:
|
||||||
|
captured = paw + opp_offset
|
||||||
|
elif to_mask & bbs[nht + opp_offset]:
|
||||||
|
captured = nht + opp_offset
|
||||||
|
elif to_mask & bbs[bis + opp_offset]:
|
||||||
|
captured = bis + opp_offset
|
||||||
|
elif to_mask & bbs[roo + opp_offset]:
|
||||||
|
captured = roo + opp_offset
|
||||||
|
else:
|
||||||
|
captured = que + opp_offset
|
||||||
|
captures.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (captured << 16) | capture << 20)
|
||||||
|
else:
|
||||||
|
moves.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (no_piece << 16) | quiet << 20)
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
# region West
|
||||||
|
ray = rays_w[roo_sq]
|
||||||
|
blockers = ray & occupancy
|
||||||
|
if blockers:
|
||||||
|
blocker_sq = blockers.bit_length() - 1
|
||||||
|
ray_to_del = rays_w[blocker_sq]
|
||||||
|
roo_attacks = (ray ^ ray_to_del) & ~friendly_pcs
|
||||||
|
else:
|
||||||
|
roo_attacks = ray
|
||||||
|
|
||||||
|
while roo_attacks:
|
||||||
|
to_sq = (roo_attacks & -roo_attacks).bit_length() - 1
|
||||||
|
to_mask = 1 << to_sq
|
||||||
|
roo_attacks &= (roo_attacks - 1)
|
||||||
|
|
||||||
|
if to_mask & opponent_pcs:
|
||||||
|
if to_mask & bbs[paw + opp_offset]:
|
||||||
|
captured = paw + opp_offset
|
||||||
|
elif to_mask & bbs[nht + opp_offset]:
|
||||||
|
captured = nht + opp_offset
|
||||||
|
elif to_mask & bbs[bis + opp_offset]:
|
||||||
|
captured = bis + opp_offset
|
||||||
|
elif to_mask & bbs[roo + opp_offset]:
|
||||||
|
captured = roo + opp_offset
|
||||||
|
else:
|
||||||
|
captured = que + opp_offset
|
||||||
|
captures.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (captured << 16) | capture << 20)
|
||||||
|
else:
|
||||||
|
moves.append(to_sq | (roo_sq << 6) | ((roo + turn_offset) << 12) | (no_piece << 16) | quiet << 20)
|
||||||
|
# endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# endregion Rook Moves
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return captures, moves
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -373,23 +543,59 @@ class Bitboard():
|
|||||||
self.bitboards[captured] ^= (1 << end)
|
self.bitboards[captured] ^= (1 << end)
|
||||||
self.all_pieces[turn ^ 1] ^= (1 << end)
|
self.all_pieces[turn ^ 1] ^= (1 << end)
|
||||||
|
|
||||||
|
self.move_list.append(move)
|
||||||
|
|
||||||
self.side_to_move ^= 1 # Seite Wechseln
|
self.side_to_move ^= 1 # Seite Wechseln
|
||||||
|
|
||||||
|
def encode_and_make_move(self, move_str: str):
|
||||||
|
piece = move_str[0]
|
||||||
|
start = move_str[1:3]
|
||||||
|
end = move_str[3:5]
|
||||||
|
|
||||||
|
piece_int = (PCE_TO_NUM[piece.upper()] + 6) if self.side_to_move else PCE_TO_NUM[piece.upper()]
|
||||||
|
start_int = STR_TO_SQ[start.upper()]
|
||||||
|
end_int = STR_TO_SQ[end.upper()]
|
||||||
|
|
||||||
|
move_input = end_int | start_int << 6 | piece_int << 12
|
||||||
|
|
||||||
|
captures, moves = self.get_all_moves()
|
||||||
|
|
||||||
|
for move in captures:
|
||||||
|
if (move & 0xFFFF) == (move_input & 0xFFFF):
|
||||||
|
self.make_move(move)
|
||||||
|
return True
|
||||||
|
|
||||||
|
for move in moves:
|
||||||
|
if (move & 0xFFFF) == (move_input & 0xFFFF):
|
||||||
|
self.make_move(move)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def print_board(self):
|
def print_board(self):
|
||||||
board = [" ."] * 64
|
board = [" "] * 64
|
||||||
|
if self.move_list:
|
||||||
|
move = self.move_list[-1]
|
||||||
|
last_sq = (move >> 6) & 0x3F
|
||||||
|
board[last_sq] = f"{COL.BG_MOVE} "
|
||||||
for pce in range(12):
|
for pce in range(12):
|
||||||
locations = self.bitboards[pce]
|
locations = self.bitboards[pce]
|
||||||
while locations:
|
while locations:
|
||||||
index = (locations & -locations).bit_length() - 1
|
index = (locations & -locations).bit_length() - 1
|
||||||
board[index] = PIECE_TO_STR[pce]
|
board[index] = PIECE_TO_SYM[pce]
|
||||||
locations &= (locations - 1)
|
locations &= (locations - 1)
|
||||||
|
|
||||||
for c in range(7, -1, -1):
|
for c in range(7, -1, -1):
|
||||||
print(f"{c+1} ", end="")
|
print(f"{c+1} ", end="")
|
||||||
for r in range(8):
|
for r in range(8):
|
||||||
print(board[r + (c * 8)], end=" ")
|
|
||||||
print("")
|
bg_col = COL.BG_WHITE if (r + c) % 2 != 0 else COL.BG_DARK
|
||||||
print(" A B C D E F G H /n")
|
#fg_col = COL.FG_WHITE if (board[r + (c * 8)][0]) != "b" else COL.FG_BLACK
|
||||||
|
|
||||||
|
print(f"{bg_col}{COL.FG_BLACK}{board[r + (c * 8)]}", end=" ")
|
||||||
|
|
||||||
|
|
||||||
|
print(COL.RESET)
|
||||||
|
print(" A B C D E F G H\n")
|
||||||
|
|
||||||
def initialize():
|
def initialize():
|
||||||
'''
|
'''
|
||||||
@@ -466,20 +672,27 @@ def initialize():
|
|||||||
RAYS_SW[sq] |= (1 << (i * 8 + j))
|
RAYS_SW[sq] |= (1 << (i * 8 + j))
|
||||||
i -= 1; j -= 1
|
i -= 1; j -= 1
|
||||||
|
|
||||||
|
|
||||||
initialize()
|
initialize()
|
||||||
board = Bitboard()
|
board = Bitboard()
|
||||||
board.print_board()
|
turn = 0
|
||||||
board.make_move(1835036) #e2-e4
|
text = f"Please input move: "
|
||||||
board.print_board()
|
while board.playing:
|
||||||
board.make_move(1837347) #(d7-d5)
|
clear()
|
||||||
board.print_board()
|
print(f"{COL.RESET}\n ---- CHESS ---- Turn: {turn}")
|
||||||
board.make_move(4590371) #(exd5 - Capture!)
|
board.print_board()
|
||||||
board.print_board()
|
move = input(text)
|
||||||
board.make_move(4245795) #(Qxd5 - Capture!)
|
if move == "exit":
|
||||||
board.print_board()
|
break
|
||||||
board.make_move(804882) #(Nc3)
|
if len(move) !=5 or not board.encode_and_make_move(move):
|
||||||
board.print_board()
|
text = "Move not possible new move: "
|
||||||
board.make_move(829216) #(Qa5)
|
continue
|
||||||
|
|
||||||
|
|
||||||
|
turn += 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
''' Board Index:
|
''' Board Index:
|
||||||
a b c d e f g h
|
a b c d e f g h
|
||||||
|
|||||||
Reference in New Issue
Block a user