Lyte commited on
Commit
ab7af41
·
verified ·
1 Parent(s): 5a7773e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -32
app.py CHANGED
@@ -1,31 +1,41 @@
1
  import os
2
  import gradio as gr
3
  from llama_cpp import Llama
4
- from huggingface_hub import hf_hub_download#, login
5
  import numpy as np
6
 
7
- #login(os.getenv("HF_TOKEN")) my bad now its public
8
-
9
  model = Llama(
10
  model_path=hf_hub_download(
11
- repo_id=os.environ.get("REPO_ID", "Lyte/QuadConnect2.5-0.5B-v0.0.3b"),
12
- filename=os.environ.get("MODEL_FILE", "quadconnect_q8_0.gguf"),
13
  )
14
  )
15
 
16
- SYSTEM_PROMPT = """You are a Connect Four player. Connect Four is played on a 6x7 grid. Given the current board state, predict the next *column* to play in. Moves are specified by the column letter (a-g). Respond in the following format:
 
 
 
 
 
 
 
 
 
17
  <reasoning>
18
- Explain your reasoning, considering the board state and potential future moves.
 
 
 
19
  </reasoning>
20
  <move>
21
- The column letter (a-g) of your move.
22
  </move>
23
  """
24
 
25
  class ConnectFour:
26
  def __init__(self):
27
  self.board = np.zeros((6, 7))
28
- self.current_player = 1 # 1 for player, 2 for AI
29
  self.game_over = False
30
 
31
  def make_move(self, col):
@@ -81,14 +91,19 @@ class ConnectFour:
81
  if self.board[row][col] != 0:
82
  col_letter = chr(ord('a') + col)
83
  row_num = str(6 - row) # Convert to 1-based indexing
84
- #player = "X" if self.board[row][col] == 1 else "O"
85
- moves.append(f"{col_letter}{row_num}")#={player}")
86
- return ", ".join(moves)
87
 
88
  def parse_ai_move(self, move_str):
89
- # Parse move like 'a1', 'b3', etc.
90
- col = ord(move_str[0].lower()) - ord('a')
91
- return col
 
 
 
 
 
92
 
93
  def create_interface():
94
  game = ConnectFour()
@@ -155,7 +170,7 @@ def create_interface():
155
 
156
  with gr.Blocks(css=css) as interface:
157
  gr.Markdown("# 🎮 Connect Four vs AI")
158
- gr.Markdown("### This is just a quick prototype for now, and the current model was trained just for 200 steps to test the concept, the reward functions were flawed, update coming soon!")
159
 
160
  with gr.Row():
161
  with gr.Column(scale=2):
@@ -163,22 +178,22 @@ def create_interface():
163
  status = gr.Markdown("Your turn! Click a button to drop your piece!", elem_id="ai-status")
164
 
165
  # Column buttons
166
- with gr.Group(elem_id="column-buttons", elem_classes=["fitter"]):
167
  col_buttons = []
168
  for i in range(7):
169
- btn = gr.Button(f"⬇️ {i+1}", scale=1)
170
  col_buttons.append(btn)
171
 
172
  # Game board
173
  board_display = gr.HTML(render_board(), elem_id="board-display")
174
  reset_btn = gr.Button("🔄 New Game", variant="primary")
175
 
176
- with gr.Column(scale=1):
177
- # AI reasoning display
178
- gr.Markdown("### 🤖 AI's Thoughts")
179
- reasoning_display = gr.HTML(
180
- value='<div id="ai-reasoning">Waiting for your move...</div>',
181
- elem_id="ai-reasoning-container"
182
  )
183
 
184
  def handle_move(col):
@@ -211,9 +226,8 @@ def create_interface():
211
  # AI move
212
  game.current_player = 2
213
  board_state = game.board_to_string()
214
-
215
- prompt = f"Current Board: {board_state}. Make a move."
216
- #print(prompt)
217
 
218
  # Get AI response
219
  response = model.create_chat_completion(
@@ -233,13 +247,16 @@ def create_interface():
233
  move_str = ai_response.split("<move>")[1].split("</move>")[0].strip()
234
  ai_col = game.parse_ai_move(move_str)
235
 
 
 
 
236
  # Format reasoning for display
237
  reasoning_html = f'''
238
  <div id="ai-reasoning">
239
  <div class="reasoning-box">
240
  <p><strong>🤔 Reasoning:</strong></p>
241
  <p>{reasoning}</p>
242
- <p><strong>📍 Move chosen:</strong> {move_str}</p>
243
  </div>
244
  </div>
245
  '''
@@ -320,7 +337,5 @@ def render_board(board=None):
320
  html += "</div>"
321
  return html
322
 
323
- # Launch the interface
324
- if __name__ == "__main__":
325
- interface = create_interface()
326
- interface.launch()
 
1
  import os
2
  import gradio as gr
3
  from llama_cpp import Llama
4
+ from huggingface_hub import hf_hub_download
5
  import numpy as np
6
 
 
 
7
  model = Llama(
8
  model_path=hf_hub_download(
9
+ repo_id=os.environ.get("REPO_ID", "Lyte/QuadConnect2.5-0.5B-v0.0.4b"),
10
+ filename=os.environ.get("MODEL_FILE", "unsloth.Q8_0.gguf"),
11
  )
12
  )
13
 
14
+ SYSTEM_PROMPT = """You are an expert Connect Four player. The game is played on a 6x7 grid where pieces fall to the lowest available position in each column due to gravity.
15
+
16
+ Board representation:
17
+ - The board is described as a list of occupied positions in the format: <column><row>(<piece>).
18
+ - Columns are labeled a-g (from left to right) and rows are numbered 1-6 (with 1 as the bottom row).
19
+ - For example: 'a1(O), a2(X), b1(O)' indicates that cell a1 has an O, a2 has an X, and b1 has an O.
20
+ - An empty board is simply represented by an empty list.
21
+ - To win, you must connect 4 of your pieces horizontally, vertically, or diagonally.
22
+
23
+ Respond in the following XML format:
24
  <reasoning>
25
+ Explain your reasoning, including:
26
+ - Identifying winning opportunities for yourself.
27
+ - Blocking your opponent's potential wins.
28
+ - Strategic positioning, such as center control and setting up future moves.
29
  </reasoning>
30
  <move>
31
+ Indicate the column letter (a-g) where you want to drop your piece.
32
  </move>
33
  """
34
 
35
  class ConnectFour:
36
  def __init__(self):
37
  self.board = np.zeros((6, 7))
38
+ self.current_player = 1 # 1 for player (X), 2 for AI (O)
39
  self.game_over = False
40
 
41
  def make_move(self, col):
 
91
  if self.board[row][col] != 0:
92
  col_letter = chr(ord('a') + col)
93
  row_num = str(6 - row) # Convert to 1-based indexing
94
+ piece = "X" if self.board[row][col] == 1 else "O"
95
+ moves.append(f"{col_letter}{row_num}({piece})")
96
+ return ", ".join(moves) if moves else ""
97
 
98
  def parse_ai_move(self, move_str):
99
+ # Parse move like 'a', 'b', etc.
100
+ try:
101
+ col = ord(move_str.strip().lower()) - ord('a')
102
+ if 0 <= col <= 6:
103
+ return col
104
+ return -1
105
+ except:
106
+ return -1
107
 
108
  def create_interface():
109
  game = ConnectFour()
 
170
 
171
  with gr.Blocks(css=css) as interface:
172
  gr.Markdown("# 🎮 Connect Four vs AI")
173
+ gr.Markdown("### Play against an AI trained to be an expert Connect Four player!")
174
 
175
  with gr.Row():
176
  with gr.Column(scale=2):
 
178
  status = gr.Markdown("Your turn! Click a button to drop your piece!", elem_id="ai-status")
179
 
180
  # Column buttons
181
+ with gr.Group(elem_id="column-buttons"):
182
  col_buttons = []
183
  for i in range(7):
184
+ btn = gr.Button(f"⬇️ {chr(ord('A') + i)}", scale=1)
185
  col_buttons.append(btn)
186
 
187
  # Game board
188
  board_display = gr.HTML(render_board(), elem_id="board-display")
189
  reset_btn = gr.Button("🔄 New Game", variant="primary")
190
 
191
+ with gr.Column(scale=1):
192
+ # AI reasoning display
193
+ gr.Markdown("### 🤖 AI's Thoughts")
194
+ reasoning_display = gr.HTML(
195
+ value='<div id="ai-reasoning">Waiting for your move...</div>',
196
+ elem_id="ai-reasoning-container"
197
  )
198
 
199
  def handle_move(col):
 
226
  # AI move
227
  game.current_player = 2
228
  board_state = game.board_to_string()
229
+
230
+ prompt = f"Current board state (you are O, opponent is X):\n{board_state}\n\nMake your move."
 
231
 
232
  # Get AI response
233
  response = model.create_chat_completion(
 
247
  move_str = ai_response.split("<move>")[1].split("</move>")[0].strip()
248
  ai_col = game.parse_ai_move(move_str)
249
 
250
+ if ai_col == -1:
251
+ raise ValueError("Invalid move format from AI")
252
+
253
  # Format reasoning for display
254
  reasoning_html = f'''
255
  <div id="ai-reasoning">
256
  <div class="reasoning-box">
257
  <p><strong>🤔 Reasoning:</strong></p>
258
  <p>{reasoning}</p>
259
+ <p><strong>📍 Move chosen:</strong> Column {move_str.upper()}</p>
260
  </div>
261
  </div>
262
  '''
 
337
  html += "</div>"
338
  return html
339
 
340
+ interface = create_interface()
341
+ interface.launch()