Reinitialize repository and add working move generation for all pieces
This commit is contained in:
commit
951a8bbec6
28 changed files with 3373 additions and 0 deletions
60
helper_scripts/generate_king_attacks.py
Normal file
60
helper_scripts/generate_king_attacks.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
def generate_king_attacks():
|
||||
"""
|
||||
Generates a list of 64 u64 bitboards, where each bitboard represents
|
||||
the squares a king can attack from a given source square.
|
||||
Uses Little-Endian File-Rank (LEFR) mapping: A1=0, H1=7, A2=8, ..., H8=63.
|
||||
"""
|
||||
all_attacks = []
|
||||
|
||||
# All 8 possible king move offsets (delta_file, delta_rank)
|
||||
king_moves = [
|
||||
(0, 1), (0, -1), (1, 0), (-1, 0), # Orthogonal
|
||||
(1, 1), (1, -1), (-1, 1), (-1, -1) # Diagonal
|
||||
]
|
||||
|
||||
for sq in range(64):
|
||||
attacks_bb = 0
|
||||
|
||||
# Calculate rank and file for the source square
|
||||
rank = sq // 8
|
||||
file = sq % 8
|
||||
|
||||
for df, dr in king_moves:
|
||||
target_rank = rank + dr
|
||||
target_file = file + df
|
||||
|
||||
# Check if the target square is on the board
|
||||
if 0 <= target_rank <= 7 and 0 <= target_file <= 7:
|
||||
# Convert target rank and file back to a square index
|
||||
target_sq = target_rank * 8 + target_file
|
||||
# Set the corresponding bit in the bitboard
|
||||
attacks_bb |= (1 << target_sq)
|
||||
|
||||
all_attacks.append(attacks_bb)
|
||||
|
||||
return all_attacks
|
||||
|
||||
def print_rust_array(attacks, const_name):
|
||||
"""
|
||||
Prints the list of attack bitboards as a Rust array.
|
||||
"""
|
||||
print(f"pub const {const_name}: [u64; 64] = [")
|
||||
|
||||
for i, attacks_bb in enumerate(attacks):
|
||||
# Format as 64-bit zero-padded binary string
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
|
||||
# Insert underscores every 8 bits for readability
|
||||
chunks = [raw_binary_string[i:i+8] for i in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
|
||||
# Correctly index the string 'ABCDEFGH'
|
||||
print(f" {binary_string}, // Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
|
||||
print("];")
|
||||
|
||||
if __name__ == "__main__":
|
||||
attacks = generate_king_attacks()
|
||||
print_rust_array(attacks, "KING_ATTACKS")
|
||||
60
helper_scripts/generate_knight_attacks.py
Normal file
60
helper_scripts/generate_knight_attacks.py
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
def generate_knight_attacks():
|
||||
"""
|
||||
Generates a list of 64 u64 bitboards, where each bitboard represents
|
||||
the squares a knight can attack from a given source square.
|
||||
Uses Little-Endian File-Rank (LEFR) mapping: A1=0, H1=7, A2=8, ..., H8=63.
|
||||
"""
|
||||
all_attacks = []
|
||||
|
||||
# All 8 possible knight move offsets (delta_file, delta_rank)
|
||||
knight_moves = [
|
||||
(1, 2), (1, -2), (-1, 2), (-1, -2),
|
||||
(2, 1), (2, -1), (-2, 1), (-2, -1)
|
||||
]
|
||||
|
||||
for sq in range(64):
|
||||
attacks_bb = 0
|
||||
|
||||
# Calculate rank and file for the source square
|
||||
rank = sq // 8
|
||||
file = sq % 8
|
||||
|
||||
for df, dr in knight_moves:
|
||||
target_rank = rank + dr
|
||||
target_file = file + df
|
||||
|
||||
# Check if the target square is on the board
|
||||
if 0 <= target_rank <= 7 and 0 <= target_file <= 7:
|
||||
# Convert target rank and file back to a square index
|
||||
target_sq = target_rank * 8 + target_file
|
||||
# Set the corresponding bit in the bitboard
|
||||
attacks_bb |= (1 << target_sq)
|
||||
|
||||
all_attacks.append(attacks_bb)
|
||||
|
||||
return all_attacks
|
||||
|
||||
def print_rust_array(attacks):
|
||||
"""
|
||||
Prints the list of attack bitboards as a Rust array.
|
||||
"""
|
||||
print("pub const KNIGHT_ATTACKS: [u64; 64] = [")
|
||||
|
||||
for i, attacks_bb in enumerate(attacks):
|
||||
# Format as 64-bit zero-padded binary string
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
|
||||
# Insert underscores every 8 bits for readability
|
||||
chunks = [raw_binary_string[i:i+8] for i in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
|
||||
# Correctly index the string 'ABCDEFGH'
|
||||
print(f" {binary_string}, // Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
|
||||
print("];")
|
||||
|
||||
if __name__ == "__main__":
|
||||
attacks = generate_knight_attacks()
|
||||
print_rust_array(attacks)
|
||||
87
helper_scripts/generate_pawn_attacks.py
Normal file
87
helper_scripts/generate_pawn_attacks.py
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
def generate_pawn_attacks():
|
||||
"""
|
||||
Generates a list of 64 u64 bitboards for each color (White, Black),
|
||||
where each bitboard represents the squares a pawn can attack from
|
||||
a given source square.
|
||||
Uses Little-Endian File-Rank (LEFR) mapping: A1=0, H1=7, A2=8, ..., H8=63.
|
||||
|
||||
Returns:
|
||||
[[u64; 64]; 2] (represented as a list of two lists)
|
||||
Index 0: White attacks
|
||||
Index 1: Black attacks
|
||||
"""
|
||||
|
||||
# all_attacks[0] = White, all_attacks[1] = Black
|
||||
all_attacks = [[], []]
|
||||
|
||||
for sq in range(64):
|
||||
rank = sq // 8
|
||||
file = sq % 8
|
||||
|
||||
white_attacks_bb = 0
|
||||
black_attacks_bb = 0
|
||||
|
||||
# --- White Attacks (Index 0) ---
|
||||
# Pawns attack "up" the board (increasing square index)
|
||||
# We only generate attacks if the pawn is not on the 8th rank
|
||||
if rank < 7:
|
||||
# Attack Up-Left (e.g., B2 -> A3)
|
||||
# Not possible if pawn is on the A-file
|
||||
if file > 0:
|
||||
white_attacks_bb |= (1 << (sq + 7))
|
||||
|
||||
# Attack Up-Right (e.g., B2 -> C3)
|
||||
# Not possible if pawn is on the H-file
|
||||
if file < 7:
|
||||
white_attacks_bb |= (1 << (sq + 9))
|
||||
|
||||
# --- Black Attacks (Index 1) ---
|
||||
# Pawns attack "down" the board (decreasing square index)
|
||||
# We only generate attacks if the pawn is not on the 1st rank
|
||||
if rank > 0:
|
||||
# Attack Down-Left (e.g., G7 -> F6)
|
||||
# Not possible if pawn is on the A-file
|
||||
if file > 0:
|
||||
black_attacks_bb |= (1 << (sq - 9))
|
||||
|
||||
# Attack Down-Right (e.g., G7 -> H6)
|
||||
# Not possible if pawn is on the H-file
|
||||
if file < 7:
|
||||
black_attacks_bb |= (1 << (sq - 7))
|
||||
|
||||
all_attacks[0].append(white_attacks_bb)
|
||||
all_attacks[1].append(black_attacks_bb)
|
||||
|
||||
return all_attacks
|
||||
|
||||
def print_rust_array(attacks_by_color, const_name):
|
||||
"""
|
||||
Prints the list of attack bitboards as a nested Rust array.
|
||||
"""
|
||||
print(f"pub const {const_name}: [[u64; 64]; 2] = [")
|
||||
|
||||
# --- Print White Attacks ---
|
||||
print(" [ // Color 0: White")
|
||||
for i, attacks_bb in enumerate(attacks_by_color[0]):
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
chunks = [raw_binary_string[i:i+8] for i in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
print(f" {binary_string}, // Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
print(" ],")
|
||||
|
||||
# --- Print Black Attacks ---
|
||||
print(" [ // Color 1: Black")
|
||||
for i, attacks_bb in enumerate(attacks_by_color[1]):
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
chunks = [raw_binary_string[i:i+8] for i in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
print(f" {binary_string}, // Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
print(" ]")
|
||||
|
||||
print("];")
|
||||
|
||||
if __name__ == "__main__":
|
||||
attacks = generate_pawn_attacks()
|
||||
print_rust_array(attacks, "PAWN_ATTACKS")
|
||||
110
helper_scripts/generate_premasks.py
Normal file
110
helper_scripts/generate_premasks.py
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
def generate_premasks():
|
||||
"""
|
||||
Generiert relevante Belegungsmasken (relevant occupancy masks) für
|
||||
Türme (Rooks) und Läufer (Bishops) auf allen 64 Feldern.
|
||||
|
||||
Diese Masken enthalten alle Felder zwischen der Figur und dem Rand,
|
||||
ABER AUSSCHLIESSLICH der Randfelder selbst.
|
||||
"""
|
||||
all_rook_masks = []
|
||||
all_bishop_masks = []
|
||||
|
||||
# Richtungen für beide Figurentypen
|
||||
rook_directions = [
|
||||
(1, 0), # Hoch
|
||||
(-1, 0), # Runter
|
||||
(0, 1), # Rechts
|
||||
(0, -1) # Links
|
||||
]
|
||||
bishop_directions = [
|
||||
(1, 1), # Hoch-Rechts
|
||||
(1, -1), # Hoch-Links
|
||||
(-1, 1), # Runter-Rechts
|
||||
(-1, -1) # Runter-Links
|
||||
]
|
||||
|
||||
for sq in range(64):
|
||||
rook_mask_bb = 0
|
||||
bishop_mask_bb = 0
|
||||
|
||||
rank = sq // 8
|
||||
file = sq % 8
|
||||
|
||||
# --- 1. Turm (Rook) Masken-Generierung ---
|
||||
# (Dies ist die korrigierte Logik)
|
||||
for dr, df in rook_directions:
|
||||
target_rank = rank + dr
|
||||
target_file = file + df
|
||||
|
||||
# Schleife, solange wir auf dem Brett sind (0-7)
|
||||
while 0 <= target_rank <= 7 and 0 <= target_file <= 7:
|
||||
is_relevant = False
|
||||
|
||||
# Prüfen, ob das Feld *vor* dem Rand liegt.
|
||||
if df != 0: # Horizontale Bewegung
|
||||
if 1 <= target_file <= 6: # Files 'b' bis 'g'
|
||||
is_relevant = True
|
||||
elif dr != 0: # Vertikale Bewegung
|
||||
if 1 <= target_rank <= 6: # Ranks 2 bis 7
|
||||
is_relevant = True
|
||||
|
||||
if is_relevant:
|
||||
target_sq = target_rank * 8 + target_file
|
||||
rook_mask_bb |= (1 << target_sq)
|
||||
|
||||
# Zum nächsten Feld in dieser Richtung
|
||||
target_rank += dr
|
||||
target_file += df
|
||||
|
||||
all_rook_masks.append(rook_mask_bb)
|
||||
|
||||
# --- 2. Läufer (Bishop) Masken-Generierung ---
|
||||
# (Diese Logik war in deinem "Rook"-Skript und ist hier korrekt)
|
||||
for dr, df in bishop_directions:
|
||||
target_rank = rank + dr
|
||||
target_file = file + df
|
||||
|
||||
# Schleife, solange wir *von allen* Rändern entfernt sind (1-6)
|
||||
while 1 <= target_rank <= 6 and 1 <= target_file <= 6:
|
||||
target_sq = target_rank * 8 + target_file
|
||||
bishop_mask_bb |= (1 << target_sq)
|
||||
|
||||
# Zum nächsten Feld in dieser Richtung
|
||||
target_rank += dr
|
||||
target_file += df
|
||||
|
||||
all_bishop_masks.append(bishop_mask_bb)
|
||||
|
||||
# Gibt beide Listen als Tupel zurück
|
||||
return all_rook_masks, all_bishop_masks
|
||||
|
||||
def print_rust_array(attacks, const_name):
|
||||
"""
|
||||
Gibt die Liste der Bitboards als Rust-Array aus.
|
||||
"""
|
||||
print(f"pub const {const_name}: [u64; 64] = [")
|
||||
|
||||
for i, attacks_bb in enumerate(attacks):
|
||||
# Formatieren als 64-Bit binärer String mit Nullen
|
||||
raw_binary_string = f"{attacks_bb:064b}"
|
||||
|
||||
# Unterstriche alle 8 Bits zur Lesbarkeit einfügen
|
||||
chunks = [raw_binary_string[j:j+8] for j in range(0, 64, 8)]
|
||||
binary_string = f"0b{'_'.join(chunks)}"
|
||||
|
||||
# Index 'ABCDEFGH' korrekt zuordnen
|
||||
print(f" {binary_string}, // Square {i} ({'ABCDEFGH'[i%8]}{i//8 + 1})")
|
||||
|
||||
print("];")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Entpackt das Tupel mit beiden Masken-Listen
|
||||
rook_masks, bishop_masks = generate_premasks()
|
||||
|
||||
print("--- ROOK MASKS ---")
|
||||
print_rust_array(rook_masks, "ROOK_RELEVANT_OCCUPANCY")
|
||||
|
||||
print("\n--- BISHOP MASKS ---")
|
||||
print_rust_array(bishop_masks, "BISHOP_RELEVANT_OCCUPANCY")
|
||||
197
helper_scripts/grafical_bitboard_generator.py
Normal file
197
helper_scripts/grafical_bitboard_generator.py
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
import tkinter as tk
|
||||
|
||||
class ChessBitboardApp:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("Chess Bitboard Generator")
|
||||
|
||||
# The bitboard, stored as a 64-bit integer
|
||||
self.bitboard = 0
|
||||
|
||||
# A dictionary to keep track of squares and their marked state
|
||||
# Key: (row, col), Value: {
|
||||
# 'widget': tk.Frame, 'label_alg': tk.Label, 'label_idx': tk.Label,
|
||||
# 'marked': bool, 'original_color': str
|
||||
# }
|
||||
self.squares = {}
|
||||
|
||||
# --- Create the GUI ---
|
||||
|
||||
# Frame for the chessboard
|
||||
board_frame = tk.Frame(root)
|
||||
board_frame.pack()
|
||||
|
||||
# Create the 8x8 grid of squares
|
||||
# We loop from row 7 (rank 8) down to 0 (rank 1) for visual layout
|
||||
for r in range(7, -1, -1): # 7, 6, 5, ... 0
|
||||
for c in range(8): # 0, 1, 2, ... 7
|
||||
|
||||
# Determine the square's original color
|
||||
is_light_square = (r + c) % 2 == 1
|
||||
original_color = "#F0D9B5" if is_light_square else "#B58863"
|
||||
|
||||
# Create the square as a Frame
|
||||
square = tk.Frame(
|
||||
board_frame,
|
||||
width=50,
|
||||
height=50,
|
||||
bg=original_color,
|
||||
relief="sunken",
|
||||
borderwidth=1
|
||||
)
|
||||
# Make frame *not* resize to labels
|
||||
square.pack_propagate(False) # Use pack_propagate since we use place/pack inside
|
||||
square.grid(row=7 - r, column=c)
|
||||
|
||||
# --- Add labels to the square (Feature 2) ---
|
||||
algebraic_not = f"{'abcdefgh'[c]}{r + 1}"
|
||||
bit_index = r * 8 + c
|
||||
|
||||
label_alg = tk.Label(square, text=algebraic_not, bg=original_color, font=("Arial", 8, "bold"))
|
||||
label_alg.place(x=2, y=1) # Use place to position label
|
||||
|
||||
label_idx = tk.Label(square, text=f"{bit_index}", bg=original_color, font=("Arial", 8))
|
||||
label_idx.place(relx=1.0, rely=1.0, anchor='se', x=-2, y=-1) # Use place for bottom-right
|
||||
|
||||
# Bind the click event to all parts of the square
|
||||
click_lambda = lambda event, row=r, col=c: self.on_square_click(event, row, col)
|
||||
square.bind("<Button-1>", click_lambda)
|
||||
label_alg.bind("<Button-1>", click_lambda)
|
||||
label_idx.bind("<Button-1>", click_lambda)
|
||||
|
||||
# Store the square's info
|
||||
self.squares[(r, c)] = {
|
||||
'widget': square,
|
||||
'label_alg': label_alg,
|
||||
'label_idx': label_idx,
|
||||
'marked': False,
|
||||
'original_color': original_color
|
||||
}
|
||||
|
||||
# Frame for the bitboard display
|
||||
info_frame = tk.Frame(root, pady=10)
|
||||
info_frame.pack()
|
||||
|
||||
# --- Make display labels copyable (Feature 1) ---
|
||||
self.binary_var = tk.StringVar()
|
||||
self.int_var = tk.StringVar()
|
||||
|
||||
tk.Label(info_frame, text="Binary:").pack()
|
||||
self.binary_label = tk.Entry(
|
||||
info_frame,
|
||||
textvariable=self.binary_var,
|
||||
state="readonly",
|
||||
font=("Courier", 10),
|
||||
width=77 # 64 chars + 15 underscores + 'b'
|
||||
)
|
||||
self.binary_label.pack()
|
||||
|
||||
tk.Label(info_frame, text="Integer:").pack()
|
||||
self.int_label = tk.Entry(
|
||||
info_frame,
|
||||
textvariable=self.int_var,
|
||||
state="readonly",
|
||||
font=("Courier", 12, "bold"),
|
||||
width=22
|
||||
)
|
||||
self.int_label.pack()
|
||||
|
||||
# --- Add Entry for pasting bitboard (Feature 3) ---
|
||||
input_frame = tk.Frame(root, pady=5)
|
||||
input_frame.pack()
|
||||
|
||||
tk.Label(input_frame, text="Paste Bitboard (int) and Press Enter:").pack(side=tk.LEFT)
|
||||
self.paste_entry = tk.Entry(input_frame, font=("Courier", 12), width=22)
|
||||
self.paste_entry.pack(side=tk.LEFT, padx=5)
|
||||
self.paste_entry.bind("<Return>", self.on_paste_bitboard)
|
||||
|
||||
# Initialize display
|
||||
self.update_display()
|
||||
|
||||
def on_square_click(self, event, row, col):
|
||||
"""Handles the click event for a square."""
|
||||
square_info = self.squares[(row, col)]
|
||||
|
||||
# Toggle the marked state
|
||||
square_info['marked'] = not square_info['marked']
|
||||
|
||||
self.update_square_visuals(row, col)
|
||||
|
||||
# Recalculate the bitboard and update the display
|
||||
self.recalculate_bitboard()
|
||||
self.update_display()
|
||||
|
||||
def update_square_visuals(self, row, col):
|
||||
"""Updates a single square's color based on its 'marked' state."""
|
||||
square_info = self.squares[(row, col)]
|
||||
|
||||
is_marked = square_info['marked']
|
||||
new_color = "#50C878" if is_marked else square_info['original_color']
|
||||
label_fg_color = "white" if is_marked else "black" # Make text white on green
|
||||
|
||||
square_info['widget'].config(bg=new_color)
|
||||
square_info['label_alg'].config(bg=new_color, fg=label_fg_color)
|
||||
square_info['label_idx'].config(bg=new_color, fg=label_fg_color)
|
||||
|
||||
def recalculate_bitboard(self):
|
||||
"""Recalculates the 64-bit integer from the marked squares."""
|
||||
self.bitboard = 0
|
||||
|
||||
for r in range(8):
|
||||
for c in range(8):
|
||||
if self.squares[(r, c)]['marked']:
|
||||
bit_index = r * 8 + c
|
||||
self.bitboard |= (1 << bit_index)
|
||||
|
||||
def update_display(self):
|
||||
"""Updates the binary and integer labels."""
|
||||
|
||||
# Update the integer label
|
||||
self.int_var.set(f"{self.bitboard}")
|
||||
|
||||
# Update the binary label
|
||||
binary_string = f"{self.bitboard:064b}"
|
||||
formatted_binary = "b" + "_".join(binary_string[i:i+8] for i in range(0, 64, 4))
|
||||
self.binary_var.set(f"{formatted_binary}")
|
||||
|
||||
def on_paste_bitboard(self, event):
|
||||
"""Handles the 'Enter' key press in the paste entry box."""
|
||||
try:
|
||||
# Get text from entry and convert to integer
|
||||
new_bitboard = int(self.paste_entry.get())
|
||||
if 0 <= new_bitboard <= (1 << 64) - 1:
|
||||
self.bitboard = new_bitboard
|
||||
# Update the board visuals from the new bitboard
|
||||
self.update_board_from_bitboard()
|
||||
# Update the display labels
|
||||
self.update_display()
|
||||
else:
|
||||
# Handle out-of-range numbers
|
||||
self.paste_entry.delete(0, tk.END)
|
||||
self.paste_entry.insert(0, "Out of 64-bit range")
|
||||
|
||||
except ValueError:
|
||||
# Handle non-integer input
|
||||
self.paste_entry.delete(0, tk.END)
|
||||
self.paste_entry.insert(0, "Invalid Integer")
|
||||
|
||||
def update_board_from_bitboard(self):
|
||||
"""Updates the visual state of all squares based on self.bitboard."""
|
||||
for r in range(8):
|
||||
for c in range(8):
|
||||
bit_index = r * 8 + c
|
||||
square_info = self.squares[(r, c)]
|
||||
|
||||
# Check if the bit at bit_index is set
|
||||
if (self.bitboard >> bit_index) & 1:
|
||||
square_info['marked'] = True
|
||||
else:
|
||||
square_info['marked'] = False
|
||||
|
||||
# Update the square's color
|
||||
self.update_square_visuals(r, c)
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
app = ChessBitboardApp(root)
|
||||
root.mainloop()
|
||||
205
helper_scripts/hexlist_to_binlist.py
Normal file
205
helper_scripts/hexlist_to_binlist.py
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
a = """
|
||||
[
|
||||
0x8a80104000800020,
|
||||
0x140002000100040,
|
||||
0x2801880a0017001,
|
||||
0x100081001000420,
|
||||
0x200020010080420,
|
||||
0x3001c0002010008,
|
||||
0x8480008002000100,
|
||||
0x2080088004402900,
|
||||
0x800098204000,
|
||||
0x2024401000200040,
|
||||
0x100802000801000,
|
||||
0x120800800801000,
|
||||
0x208808088000400,
|
||||
0x2802200800400,
|
||||
0x2200800100020080,
|
||||
0x801000060821100,
|
||||
0x80044006422000,
|
||||
0x100808020004000,
|
||||
0x12108a0010204200,
|
||||
0x140848010000802,
|
||||
0x481828014002800,
|
||||
0x8094004002004100,
|
||||
0x4010040010010802,
|
||||
0x20008806104,
|
||||
0x100400080208000,
|
||||
0x2040002120081000,
|
||||
0x21200680100081,
|
||||
0x20100080080080,
|
||||
0x2000a00200410,
|
||||
0x20080800400,
|
||||
0x80088400100102,
|
||||
0x80004600042881,
|
||||
0x4040008040800020,
|
||||
0x440003000200801,
|
||||
0x4200011004500,
|
||||
0x188020010100100,
|
||||
0x14800401802800,
|
||||
0x2080040080800200,
|
||||
0x124080204001001,
|
||||
0x200046502000484,
|
||||
0x480400080088020,
|
||||
0x1000422010034000,
|
||||
0x30200100110040,
|
||||
0x100021010009,
|
||||
0x2002080100110004,
|
||||
0x202008004008002,
|
||||
0x20020004010100,
|
||||
0x2048440040820001,
|
||||
0x101002200408200,
|
||||
0x40802000401080,
|
||||
0x4008142004410100,
|
||||
0x2060820c0120200,
|
||||
0x1001004080100,
|
||||
0x20c020080040080,
|
||||
0x2935610830022400,
|
||||
0x44440041009200,
|
||||
0x280001040802101,
|
||||
0x2100190040002085,
|
||||
0x80c0084100102001,
|
||||
0x4024081001000421,
|
||||
0x20030a0244872,
|
||||
0x12001008414402,
|
||||
0x2006104900a0804,
|
||||
0x1004081002402,
|
||||
]
|
||||
""".replace("[", "").replace("]", "").replace(",", "").strip().split("\n")
|
||||
a = [int(x, 16) for x in a]
|
||||
|
||||
b = """
|
||||
[
|
||||
0x8a80104000800020,
|
||||
0x140002000100040,
|
||||
0x2801880a0017001,
|
||||
0x100081001000420,
|
||||
0x200020010080420,
|
||||
0x3001c0002010008,
|
||||
0x8480008002000100,
|
||||
0x2080088004402900,
|
||||
0x800098204000,
|
||||
0x2024401000200040,
|
||||
0x100802000801000,
|
||||
0x120800800801000,
|
||||
0x208808088000400,
|
||||
0x2802200800400,
|
||||
0x2200800100020080,
|
||||
0x801000060821100,
|
||||
0x80044006422000,
|
||||
0x100808020004000,
|
||||
0x12108a0010204200,
|
||||
0x140848010000802,
|
||||
0x481828014002800,
|
||||
0x8094004002004100,
|
||||
0x4010040010010802,
|
||||
0x20008806104,
|
||||
0x100400080208000,
|
||||
0x2040002120081000,
|
||||
0x21200680100081,
|
||||
0x20100080080080,
|
||||
0x2000a00200410,
|
||||
0x20080800400,
|
||||
0x80088400100102,
|
||||
0x80004600042881,
|
||||
0x4040008040800020,
|
||||
0x440003000200801,
|
||||
0x4200011004500,
|
||||
0x188020010100100,
|
||||
0x14800401802800,
|
||||
0x2080040080800200,
|
||||
0x124080204001001,
|
||||
0x200046502000484,
|
||||
0x480400080088020,
|
||||
0x1000422010034000,
|
||||
0x30200100110040,
|
||||
0x100021010009,
|
||||
0x2002080100110004,
|
||||
0x202008004008002,
|
||||
0x20020004010100,
|
||||
0x2048440040820001,
|
||||
0x101002200408200,
|
||||
0x40802000401080,
|
||||
0x4008142004410100,
|
||||
0x2060820c0120200,
|
||||
0x1001004080100,
|
||||
0x20c020080040080,
|
||||
0x2935610830022400,
|
||||
0x44440041009200,
|
||||
0x280001040802101,
|
||||
0x2100190040002085,
|
||||
0x80c0084100102001,
|
||||
0x4024081001000421,
|
||||
0x20030a0244872,
|
||||
0x12001008414402,
|
||||
0x2006104900a0804,
|
||||
0x1004081002402,
|
||||
]
|
||||
""".replace("[", "").replace("]", "").replace(",", "").strip().split("\n")
|
||||
b = [int(x, 16) for x in b]
|
||||
|
||||
def format_rust_array(data_list, array_name="GeneratedArray"):
|
||||
"""
|
||||
Converts a list of integers/hex into a formatted Rust array
|
||||
with binary representation and chess square comments.
|
||||
"""
|
||||
print(f"pub const {array_name}: [u64; {len(data_list)}] = [")
|
||||
|
||||
files = "ABCDEFGH"
|
||||
|
||||
for i, val in enumerate(data_list):
|
||||
# 1. Convert to 64-bit binary string (MSB on left)
|
||||
bin_str = f"{val:064b}"
|
||||
|
||||
# 2. Insert underscores every 8 bits for readability
|
||||
# Range 0 to 64 with step 8
|
||||
chunks = [bin_str[j:j+8] for j in range(0, 64, 8)]
|
||||
formatted_bin = "_".join(chunks)
|
||||
|
||||
# 3. Calculate Square and Algebraic Notation for the comment
|
||||
# Assuming standard Little-Endian Rank-File mapping (A1=0, B1=1 ... H8=63)
|
||||
file_idx = i % 8
|
||||
rank_idx = i // 8
|
||||
|
||||
if rank_idx < 8:
|
||||
algebraic = f"{files[file_idx]}{rank_idx + 1}"
|
||||
else:
|
||||
algebraic = "N/A" # Handle lists larger than 64 items gracefully
|
||||
|
||||
# 4. Print the formatted line
|
||||
print(f" 0b{formatted_bin}, // Square {i} ({algebraic})")
|
||||
|
||||
print("];")
|
||||
|
||||
# --- OPTION 1: Convert your specific hex list ---
|
||||
my_hex_list = [
|
||||
0x8a80104000800020,
|
||||
0x140002000100040
|
||||
]
|
||||
|
||||
# --- OPTION 2: Generate the actual King Attacks (to match your example) ---
|
||||
def generate_king_attacks():
|
||||
king_moves = []
|
||||
for square in range(64):
|
||||
attacks = 0
|
||||
file = square % 8
|
||||
rank = square // 8
|
||||
|
||||
# Iterate over all 8 neighbors
|
||||
for d_file in [-1, 0, 1]:
|
||||
for d_rank in [-1, 0, 1]:
|
||||
if d_file == 0 and d_rank == 0:
|
||||
continue
|
||||
|
||||
target_file = file + d_file
|
||||
target_rank = rank + d_rank
|
||||
|
||||
if 0 <= target_file < 8 and 0 <= target_rank < 8:
|
||||
target_square = target_rank * 8 + target_file
|
||||
attacks |= (1 << target_square)
|
||||
king_moves.append(attacks)
|
||||
return king_moves
|
||||
|
||||
if __name__ == "__main__":
|
||||
format_rust_array(a, "MAGICS_ROOK")
|
||||
format_rust_array(b, "MAGICS_BISHOP")
|
||||
Loading…
Add table
Add a link
Reference in a new issue