-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for built-in opening book in source code
- Loading branch information
Showing
69 changed files
with
4,113 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,315 @@ | ||
# Define the initial board as a list of strings | ||
original_board = [ | ||
" /*", | ||
" a7 ----- d7 ----- g7", | ||
" | | |", | ||
" | b6 -- d6 -- f6 |", | ||
" | | | | |", | ||
" | | c5-d5-e5 | |", | ||
" a4-b4-c4 e4-f4-g4", | ||
" | | c3-d3-e3 | |", | ||
" | | | | |", | ||
" | b2 -- d2 -- f2 |", | ||
" | | |", | ||
" a1 ----- d1 ----- g1", | ||
" */", | ||
] | ||
|
||
# Map positions to their coordinates (line index, column index) | ||
positions_coords = { | ||
# Outer ring positions | ||
'a7': (1, 4), 'd7': (1, 13), 'g7': (1, 22), | ||
'a4': (6, 4), 'g4': (6, 22), | ||
'a1': (11, 4), 'd1': (11, 13), 'g1': (11, 22), | ||
# Middle ring positions | ||
'b6': (3, 7), 'd6': (3, 13), 'f6': (3, 19), | ||
'b4': (6, 7), 'f4': (6, 19), | ||
'b2': (9, 7), 'd2': (9, 13), 'f2': (9, 19), | ||
# Inner ring positions | ||
'c5': (5, 10), 'd5': (5, 13), 'e5': (5, 16), | ||
'c4': (6, 10), 'e4': (6, 16), | ||
'c3': (7, 10), 'd3': (7, 13), 'e3': (7, 16), | ||
} | ||
|
||
# Positions in the order they appear in the FEN string | ||
inner_ring_positions = ['d5', 'e5', 'e4', 'e3', 'd3', 'c3', 'c4', 'c5'] | ||
middle_ring_positions = ['d6', 'f6', 'f4', 'f2', 'd2', 'b2', 'b4', 'b6'] | ||
outer_ring_positions = ['d7', 'g7', 'g4', 'g1', 'd1', 'a1', 'a4', 'a7'] | ||
|
||
# Build mappings between position names and their ring and index | ||
positions_index = {} # Map position name to (ring, index) | ||
index_to_position = {} # Map (ring, index) to position name | ||
|
||
# Assign indices to positions in each ring | ||
for idx, pos_name in enumerate(outer_ring_positions): | ||
ring = 3 # Outer ring | ||
index = idx | ||
positions_index[pos_name] = (ring, index) | ||
index_to_position[(ring, index)] = pos_name | ||
|
||
for idx, pos_name in enumerate(middle_ring_positions): | ||
ring = 2 # Middle ring | ||
index = idx | ||
positions_index[pos_name] = (ring, index) | ||
index_to_position[(ring, index)] = pos_name | ||
|
||
for idx, pos_name in enumerate(inner_ring_positions): | ||
ring = 1 # Inner ring | ||
index = idx | ||
positions_index[pos_name] = (ring, index) | ||
index_to_position[(ring, index)] = pos_name | ||
|
||
# Function to parse the FEN string and build the board state | ||
def parse_fen(fen_string): | ||
parts = fen_string.strip().split(' ', 1) | ||
positions_fen = parts[0] | ||
rest_of_fen = parts[1] if len(parts) > 1 else '' | ||
|
||
fen_parts = positions_fen.split('/') | ||
|
||
if len(fen_parts) != 3: | ||
raise ValueError("Invalid FEN string: expected 3 parts separated by '/'") | ||
|
||
inner_fen, middle_fen, outer_fen = fen_parts | ||
|
||
board_state = {} | ||
|
||
# Process inner ring | ||
for i, fen_char in enumerate(inner_fen): | ||
if fen_char != '*': | ||
pos_name = inner_ring_positions[i] | ||
board_state[pos_name] = fen_char | ||
|
||
# Process middle ring | ||
for i, fen_char in enumerate(middle_fen): | ||
if fen_char != '*': | ||
pos_name = middle_ring_positions[i] | ||
board_state[pos_name] = fen_char | ||
|
||
# Process outer ring | ||
for i, fen_char in enumerate(outer_fen): | ||
if fen_char != '*': | ||
pos_name = outer_ring_positions[i] | ||
board_state[pos_name] = fen_char | ||
|
||
return board_state, rest_of_fen | ||
|
||
# Function to update the board display based on the board state | ||
def update_board(board_state, board): | ||
for pos_name, piece in board_state.items(): | ||
if pos_name in positions_coords: | ||
line_idx, col_idx = positions_coords[pos_name] | ||
# Replace the first character with a space and the second with the piece symbol | ||
line = list(board[line_idx]) | ||
line[col_idx] = ' ' | ||
line[col_idx + 1] = piece | ||
board[line_idx] = ''.join(line) | ||
|
||
# Function to apply transformations to the board state | ||
def apply_transformation(board_state, transformation): | ||
rotation_steps, flip_v, flip_h, flip_io = transformation | ||
transformed_board_state = {} | ||
|
||
for pos_name, piece in board_state.items(): | ||
ring, index = positions_index[pos_name] | ||
|
||
# Apply inner/outer flip | ||
if flip_io: | ||
if ring == 1: | ||
ring = 3 | ||
elif ring == 3: | ||
ring = 1 | ||
# Middle ring remains the same | ||
|
||
# Apply vertical flip (reflection over horizontal axis) | ||
if flip_v: | ||
index = (8 - index) % 8 | ||
|
||
# Apply horizontal flip (reflection over vertical axis) | ||
if flip_h: | ||
index = (4 - index) % 8 | ||
|
||
# Apply rotation (in 45-degree increments) | ||
index = (index + rotation_steps) % 8 | ||
|
||
# Map back to position name | ||
new_pos_name = index_to_position.get((ring, index)) | ||
if new_pos_name: | ||
transformed_board_state[new_pos_name] = piece | ||
|
||
return transformed_board_state | ||
|
||
# Function to transform a single position | ||
def transform_position(pos_name, transformation): | ||
rotation_steps, flip_v, flip_h, flip_io = transformation | ||
if pos_name not in positions_index: | ||
raise ValueError(f"Invalid position name: {pos_name}") | ||
ring, index = positions_index[pos_name] | ||
|
||
# Apply inner/outer flip | ||
if flip_io: | ||
if ring == 1: | ||
ring = 3 | ||
elif ring == 3: | ||
ring = 1 | ||
# Middle ring remains the same | ||
|
||
# Apply vertical flip (reflection over horizontal axis) | ||
if flip_v: | ||
index = (8 - index) % 8 | ||
|
||
# Apply horizontal flip (reflection over vertical axis) | ||
if flip_h: | ||
index = (4 - index) % 8 | ||
|
||
# Apply rotation (in 45-degree increments) | ||
index = (index + rotation_steps) % 8 | ||
|
||
# Map back to position name | ||
new_pos_name = index_to_position.get((ring, index)) | ||
if not new_pos_name: | ||
raise ValueError(f"Transformation resulted in invalid position for ring {ring} and index {index}") | ||
return new_pos_name | ||
|
||
# Function to represent the board state in a canonical form for comparison | ||
def board_state_to_canonical(board_state): | ||
items = sorted(board_state.items()) | ||
return tuple(items) | ||
|
||
# Function to generate the FEN string from the board state | ||
def board_state_to_fen(board_state, rest_of_fen=''): | ||
# Inner ring | ||
inner_fen_list = [] | ||
for pos_name in inner_ring_positions: | ||
piece = board_state.get(pos_name, '*') | ||
inner_fen_list.append(piece) | ||
inner_fen = ''.join(inner_fen_list) | ||
|
||
# Middle ring | ||
middle_fen_list = [] | ||
for pos_name in middle_ring_positions: | ||
piece = board_state.get(pos_name, '*') | ||
middle_fen_list.append(piece) | ||
middle_fen = ''.join(middle_fen_list) | ||
|
||
# Outer ring | ||
outer_fen_list = [] | ||
for pos_name in outer_ring_positions: | ||
piece = board_state.get(pos_name, '*') | ||
outer_fen_list.append(piece) | ||
outer_fen = ''.join(outer_fen_list) | ||
|
||
# Combine the FEN parts | ||
positions_fen = '/'.join([inner_fen, middle_fen, outer_fen]) | ||
|
||
if rest_of_fen: | ||
fen_string = positions_fen + ' ' + rest_of_fen | ||
else: | ||
fen_string = positions_fen | ||
|
||
return fen_string | ||
|
||
# Main code for processing user input | ||
import re | ||
from itertools import product | ||
|
||
# Read the multi-line input | ||
print("Enter the input (end with an empty line):") | ||
input_lines = [] | ||
while True: | ||
try: | ||
line = input() | ||
if not line.strip(): | ||
break | ||
input_lines.append(line) | ||
except EOFError: | ||
break # End of input | ||
|
||
# Combine the lines into a single string | ||
input_text = '\n'.join(input_lines) | ||
|
||
# Pattern to match the FEN string inside quotes | ||
fen_pattern = r'"([^"]+)"' | ||
|
||
fen_match = re.search(fen_pattern, input_text) | ||
if fen_match: | ||
fen_string = fen_match.group(1) | ||
else: | ||
raise ValueError("FEN string not found in the input.") | ||
|
||
# Pattern to match the positions inside <String>[ ... ] | ||
positions_pattern = r'<String>\[\s*(.*?)\s*\]' | ||
positions_match = re.search(positions_pattern, input_text, re.DOTALL) | ||
if positions_match: | ||
positions_text = positions_match.group(1) | ||
# Split the positions by commas and strip quotes | ||
positions_list = [pos.strip().strip('"') for pos in positions_text.split(',') if pos.strip()] | ||
else: | ||
raise ValueError("Positions not found in the input.") | ||
|
||
try: | ||
# Parse the FEN string to get the board state | ||
board_state, rest_of_fen = parse_fen(fen_string) | ||
|
||
# Prepare to generate transformations | ||
rotation_steps_list = [0, 2, 4, 6] # Corresponds to 0°, 90°, 180°, 270° | ||
flip_v_options = [False, True] # Vertical flip | ||
flip_h_options = [False, True] # Horizontal flip | ||
flip_io_options = [False, True] # Inner/outer flip | ||
|
||
# Generate all combinations of transformations | ||
transformations = list(product(rotation_steps_list, flip_v_options, flip_h_options, flip_io_options)) | ||
|
||
unique_board_states = set() | ||
board_states_list = [] | ||
|
||
# Apply each transformation and collect unique board states | ||
for transformation in transformations: | ||
transformed_board_state = apply_transformation(board_state, transformation) | ||
canonical_state = board_state_to_canonical(transformed_board_state) | ||
if canonical_state not in unique_board_states: | ||
unique_board_states.add(canonical_state) | ||
board_states_list.append((transformation, transformed_board_state)) | ||
|
||
# Output the transformed boards | ||
print("") | ||
print("") | ||
print("") | ||
print("") | ||
print("") | ||
print("") | ||
print("") | ||
print("") | ||
print(" //////////////////////////////////////////////////////////////////////////////") | ||
print("") | ||
for idx, (transformation, transformed_board_state) in enumerate(board_states_list): | ||
rotation_steps, flip_v, flip_h, flip_io = transformation | ||
# Reset the board to the original state for each transformation | ||
board = original_board[:] | ||
update_board(transformed_board_state, board) | ||
# Print the board drawing | ||
print(" /*") | ||
for line in board[1:-1]: # Skip the first and last line (the /* and */ comments) | ||
print(line) | ||
print(" */") | ||
# Transform the positions_list with handling of optional 'x' prefix | ||
transformed_positions_list = [] | ||
for pos in positions_list: | ||
if pos.startswith('x'): | ||
prefix = 'x' | ||
coord = pos[1:] | ||
else: | ||
prefix = '' | ||
coord = pos | ||
transformed_coord = transform_position(coord, transformation) | ||
transformed_pos = prefix + transformed_coord | ||
transformed_positions_list.append(transformed_pos) | ||
# Generate the transformed FEN string | ||
transformed_fen_string = board_state_to_fen(transformed_board_state, rest_of_fen) | ||
# Output the Dart code snippet | ||
print(f' "{transformed_fen_string}": <String>[') | ||
for pos in transformed_positions_list: | ||
print(f' "{pos}",') | ||
print(' ],\n') | ||
except Exception as e: | ||
print("Invalid input. Please provide a valid FEN string or positions.") |
Oops, something went wrong.