-
Notifications
You must be signed in to change notification settings - Fork 0
/
Chess.py
116 lines (93 loc) · 3.79 KB
/
Chess.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import pandas as pd
import random
import tkinter as tk
from PIL import Image, ImageTk
import chess
import chess.svg
from cairosvg import svg2png
# Function to load puzzle data from a CSV file
def load_puzzles_from_csv(csv_file):
df = pd.read_csv(csv_file)
return df
# Function to preprocess a UCI move
def preprocess_uci_move(uci_move):
return ''.join(filter(str.isalnum, uci_move))
# Function to pick a random puzzle from the puzzle data
def pick_random_puzzle(df):
random_index = random.randint(0, len(df) - 1)
return df.iloc[random_index]
# Function to display the chessboard
def display_chessboard(fen, canvas):
board = chess.Board(fen)
svg_data = chess.svg.board(board=board, size=250)
png_data = svg2png(bytestring=svg_data.encode('utf-8'))
tk_img = ImageTk.PhotoImage(data=png_data)
canvas.create_image(0, 0, anchor=tk.NW, image=tk_img)
canvas.image = tk_img
# Chess Puzzle App class
class ChessPuzzleApp:
def __init__(self, csv_file):
self.puzzle_data = load_puzzles_from_csv(csv_file)
self.root = tk.Tk()
self.root.title("Chess Puzzle")
self.root.geometry("400x600")
self.board = chess.Board()
self.move_index = 0
self.canvas = tk.Canvas(self.root, width=300, height=300)
self.canvas.pack()
# Next Move button
self.next_button = tk.Button(self.root, text="Next Move", command=self.load_next_move, state=tk.DISABLED)
self.next_button.pack()
# Previous Move button
self.prev_button = tk.Button(self.root, text="Previous Move", command=self.load_prev_move, state=tk.DISABLED)
self.prev_button.pack()
# Next Puzzle button
self.next_puzzle_button = tk.Button(self.root, text="Next Puzzle", command=self.load_next_puzzle)
self.next_puzzle_button.pack()
# Load the first puzzle
self.load_next_puzzle()
self.root.mainloop()
# Function to update the displayed moves and chessboard
def update_moves(self):
to_play_color = "black" if self.fen.split()[1] == 'w' else "white"
self.display_current_board(to_play_color)
if self.move_index >= len(self.uci_moves) - 1:
self.next_button.config(state=tk.DISABLED)
else:
self.next_button.config(state=tk.NORMAL)
if self.move_index <= 0:
self.prev_button.config(state=tk.DISABLED)
else:
self.prev_button.config(state=tk.NORMAL)
# Function to display the current board state
def display_current_board(self, to_play_color):
board = chess.Board(self.fen)
for uci_move in self.uci_moves[:self.move_index + 1]:
move = chess.Move.from_uci(uci_move)
if move in board.legal_moves:
board.push(move)
display_chessboard(board.fen(), self.canvas)
# Function to load the next puzzle
def load_next_puzzle(self):
self.puzzle = pick_random_puzzle(self.puzzle_data)
self.fen = self.puzzle.get('FEN', "")
self.uci_moves = [preprocess_uci_move(move) for move in self.puzzle.get('Moves', "").split()]
self.move_index = 0
self.next_button.config(state=tk.NORMAL)
self.prev_button.config(state=tk.DISABLED)
# Update the board's state after updating puzzle data
self.update_moves()
# Print the FEN in the terminal
print("Current FEN:", self.fen)
# Function to load the next move
def load_next_move(self):
self.move_index += 1
self.update_moves()
# Function to load the previous move
def load_prev_move(self):
self.move_index -= 1
self.update_moves()
# Entry point of the program
if __name__ == "__main__":
csv_file = "lichess_db_puzzle.csv" # Change this to the path of your CSV file
app = ChessPuzzleApp(csv_file)