Skip to content

Instantly share code, notes, and snippets.

@Ocean-Moist
Last active November 14, 2024 19:15
Show Gist options
  • Save Ocean-Moist/0064caf583bc4ccf4151fd1a50601836 to your computer and use it in GitHub Desktop.
Save Ocean-Moist/0064caf583bc4ccf4151fd1a50601836 to your computer and use it in GitHub Desktop.
# Chess FEN Parser and Board Renderer
def parse_fen(fen):
"""Parses a FEN string and returns a dictionary with board state and game info."""
# Split the FEN string into its components
fields = fen.strip().split()
if len(fields) != 6:
raise ValueError("Invalid FEN: Incorrect number of fields.")
piece_placement, active_color, castling_availability, en_passant_target, halfmove_clock, fullmove_number = fields
# Create the board matrix and piece positions
board = []
piece_positions = {'White': {}, 'Black': {}, 'Empty': []}
ranks = piece_placement.split('/')
if len(ranks) != 8:
raise ValueError("Invalid FEN: Incorrect number of ranks.")
for rank_index, rank in enumerate(ranks):
board_row = []
file_index = 0 # Files from 'a' to 'h'
for char in rank:
if char.isdigit():
empty_squares = int(char)
for _ in range(empty_squares):
board_row.append('.')
file_char = chr(ord('a') + file_index)
rank_char = 8 - rank_index
position = f"{file_char}{rank_char}"
piece_positions['Empty'].append(position)
file_index += 1
else:
board_row.append(char)
color = 'White' if char.isupper() else 'Black'
piece = char.upper()
file_char = chr(ord('a') + file_index)
rank_char = 8 - rank_index
position = f"{file_char}{rank_char}"
if piece not in piece_positions[color]:
piece_positions[color][piece] = []
piece_positions[color][piece].append(position)
file_index += 1
if len(board_row) != 8:
raise ValueError("Invalid FEN: Incorrect number of files in a rank.")
board.append(board_row)
game_info = {
'active_color': 'White' if active_color == 'w' else 'Black',
'castling_availability': castling_availability if castling_availability != '-' else 'None',
'en_passant_target': en_passant_target if en_passant_target != '-' else 'None',
'halfmove_clock': int(halfmove_clock),
'fullmove_number': int(fullmove_number)
}
return board, piece_positions, game_info
def render_board(board):
"""Renders the board matrix into an ASCII diagram with labels on all sides."""
files = ' a b c d e f g h '
print(" " + files)
print(" +" + "----" * 8 + "+")
for rank_index, rank in enumerate(board):
rank_number = 8 - rank_index
rank_str = f"{rank_number} |"
for piece in rank:
rank_str += f" {piece} |"
rank_str += f" {rank_number}"
print(rank_str)
print(" +" + "----" * 8 + "+")
print(" " + files)
def list_piece_positions(piece_positions):
"""Lists the positions of each piece, including empty squares."""
for color in ['White', 'Black']:
print(f"{color} Pieces:")
if piece_positions[color]:
for piece in sorted(piece_positions[color].keys()):
positions = ', '.join(sorted(piece_positions[color][piece]))
piece_name = piece_full_name(piece)
print(f"- {piece_name}: {positions}")
else:
print("- None")
print()
# List empty squares
print("Empty Squares:")
if piece_positions['Empty']:
empty_positions = ', '.join(sorted(piece_positions['Empty']))
print(f"- {empty_positions}")
else:
print("- None")
print()
def piece_full_name(piece_symbol):
"""Returns the full name of a piece given its symbol."""
names = {'K': 'King', 'Q': 'Queen', 'R': 'Rook',
'B': 'Bishop', 'N': 'Knight', 'P': 'Pawn'}
return names.get(piece_symbol, 'Unknown')
def display_game_info(game_info):
"""Displays human-readable game information."""
print("Game Information:")
print(f"- Active Color: {game_info['active_color']}")
print(f"- Castling Availability: {game_info['castling_availability']}")
print(f"- En Passant Target Square: {game_info['en_passant_target']}")
print(f"- Halfmove Clock: {game_info['halfmove_clock']}")
print(f"- Fullmove Number: {game_info['fullmove_number']}")
print()
def main():
fen = input("<FEN String>\n")
print("</FEN String>")
try:
board, piece_positions, game_info = parse_fen(fen)
print("<ASCII Diagram of the Board>")
render_board(board)
print("</ASCII Diagram of the Board>")
print("<Piece Positions>")
list_piece_positions(piece_positions)
print("</Piece Positions>")
print("<Game Information>")
display_game_info(game_info)
print("</Game Information>")
print("<Instruction>")
print(f"Find the best, valid move for {game_info['active_color']}.")
print("</Instruction>")
except ValueError as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment