Falguni commited on
Commit
4b7d2b8
·
0 Parent(s):

Initial commit

Browse files
Files changed (7) hide show
  1. .DS_Store +0 -0
  2. .gitattributes +36 -0
  3. README.md +13 -0
  4. app.py +79 -0
  5. bin/stockfish +3 -0
  6. requirements.txt +1 -0
  7. src/thinksqure_engine.py +67 -0
.DS_Store ADDED
Binary file (6.15 kB). View file
 
.gitattributes ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ bin/stockfish filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: ThinkSquare
3
+ emoji: 🏆
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: gradio
7
+ sdk_version: 5.32.1
8
+ app_file: app.py
9
+ pinned: false
10
+ license: apache-2.0
11
+ ---
12
+
13
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional, Tuple
2
+ import gradio as gr
3
+
4
+ from ThinkSquare.src.thinksqure_engine import ThinkSquareEngine
5
+
6
+
7
+ def play_chess(
8
+ move: Optional[str] = "", fen: Optional[str] = "", draw_ascii: bool = True
9
+ ) -> Tuple:
10
+ """Play a move in a chess game.
11
+ Prerequisites:
12
+ - User must be asked if they want to play as white or black. If user chooses black, pass an empty string in the first move for the engine to play as white.
13
+ - User must be asked if they want a board drawn in ASCII format.
14
+ - If a move is provided, it must be in long algebraic notation (e.g., "e4", "Nf3", "Bb5").
15
+
16
+ To start a new game:
17
+ - Pass empty string for fen.
18
+ - Pass empty string for engine to play as white.
19
+ - Pass a move in long algebraic notation (e.g., "e4", "Nf3", "Bb5") for engine to play as black.
20
+
21
+ To coninue a game:
22
+ - Pass the FEN string representing the board state prior to the user's last move.
23
+ - Pass a move in long algebraic notation (e.g., "e4", "Nf3", "Bb5") for engine to play the next move.
24
+
25
+ Args:
26
+ move: The move to play in long algebraic notation. If None, the engine will play a move.
27
+ fen: The FEN string representing the board state prior to the user's last move. If None, the game starts from the initial position.
28
+ draw_ascii: Whether to draw the board in ASCII format. Defaults to True.
29
+
30
+ Returns:
31
+ The best move played by the engine, the updated board state in FEN notation, and a string representation of the board if draw_ascii is True else None.
32
+ """
33
+
34
+ if move is None or move == "" or move.lower() == "none" or move.lower() == "null":
35
+ move = None
36
+ if fen is None or fen == "" or fen.lower() == "none" or fen.lower() == "null":
37
+ fen = None
38
+
39
+ if move is not None:
40
+ is_valid = ThinkSquareEngine.is_valid_move(move, fen)
41
+
42
+ if not is_valid:
43
+ return "Invalid move", "", ""
44
+
45
+ fen = ThinkSquareEngine.get_fen_after_move(move, fen)
46
+
47
+ assert fen is not None, "FEN after move should not be None"
48
+
49
+ bestmove_san = ThinkSquareEngine.get_best_move(fen)
50
+ fen_after_move = ThinkSquareEngine.get_fen_after_move(bestmove_san, fen)
51
+
52
+ board_str = (
53
+ ThinkSquareEngine.get_ascii_board(fen_after_move) if draw_ascii else None
54
+ )
55
+
56
+ return bestmove_san, fen_after_move, board_str
57
+
58
+
59
+ demo = gr.Interface(
60
+ fn=play_chess,
61
+ inputs=[
62
+ gr.Textbox(
63
+ label="Your Move (in standard algebraic notation - SAN) (Optional)",
64
+ placeholder="e.g. e4, Nf3, Bb5, etc. Optional - ",
65
+ value=None,
66
+ ),
67
+ gr.Textbox(
68
+ label="FEN String (optional)",
69
+ placeholder="Optional - Leave blank to start from initial position",
70
+ value=None,
71
+ ),
72
+ gr.Checkbox(label="Draw ASCII Board", value=True),
73
+ ],
74
+ outputs=("text", "text", "text"),
75
+ title="Play Chess with an engine",
76
+ description="This interface allows you to play chess against the Stockfish engine. You can provide a move in standard algebraic notation and an optional FEN string representing the board state. The engine will respond with its best move, the updated FEN string, and an ASCII representation of the board if requested.",
77
+ )
78
+
79
+ demo.launch(mcp_server=True)
bin/stockfish ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7fecbc0b26454b62be5e3b237b58dc5666401b56e520aeb1b0bf8f53fa8f2ef3
3
+ size 78768416
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ chess==1.11.2
src/thinksqure_engine.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Optional
2
+ import chess
3
+ import chess.engine
4
+
5
+
6
+ class ThinkSquareEngine:
7
+ _ENGINE = "ThinkSquare/bin/stockfish"
8
+
9
+ @staticmethod
10
+ def get_best_move(fen: Optional[str] = None, time_limit=0.1):
11
+ if fen is None:
12
+ fen = chess.STARTING_FEN
13
+
14
+ board = chess.Board(fen)
15
+
16
+ with chess.engine.SimpleEngine.popen_uci(ThinkSquareEngine._ENGINE) as engine:
17
+ result = engine.play(board, chess.engine.Limit(time=time_limit))
18
+ best_move = result.move
19
+ bestmove_san = board.san(best_move)
20
+
21
+ return bestmove_san
22
+
23
+ @staticmethod
24
+ def is_valid_move(
25
+ move_san: str,
26
+ fen: Optional[str] = None,
27
+ ) -> bool:
28
+ if fen is None:
29
+ fen = chess.STARTING_FEN
30
+
31
+ board = chess.Board(fen)
32
+
33
+ try:
34
+ move = board.parse_san(move_san)
35
+ return board.is_legal(move)
36
+ except ValueError:
37
+ return False
38
+
39
+ @staticmethod
40
+ def get_fen_after_move(
41
+ move_san: str,
42
+ fen: Optional[str] = None,
43
+ ) -> Optional[str]:
44
+ if fen is None:
45
+ fen = chess.STARTING_FEN
46
+
47
+ board = chess.Board(fen)
48
+
49
+ try:
50
+ move = board.parse_san(move_san)
51
+ if board.is_legal(move):
52
+ board.push(move)
53
+ return board.fen()
54
+ else:
55
+ return None
56
+ except ValueError:
57
+ return None
58
+
59
+ @staticmethod
60
+ def get_ascii_board(fen: Optional[str] = None) -> str:
61
+ if fen is None:
62
+ fen = chess.STARTING_FEN
63
+
64
+ board = chess.Board(fen)
65
+ ascii_representation = str(board)
66
+
67
+ return ascii_representation