alperugurcan commited on
Commit
0060ecb
·
verified ·
1 Parent(s): 8b07749

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -73
app.py CHANGED
@@ -2,72 +2,84 @@ import gradio as gr
2
  import numpy as np
3
  from game_logic import my_agent, Configuration, Observation
4
 
 
 
 
 
 
 
 
 
5
  def initialize_game():
6
- return np.zeros((6, 7), dtype=int)
7
 
8
  def make_move(board, column, player):
9
- """Make a move on the board"""
10
- for row in range(5, -1, -1):
11
- if board[row][column] == 0:
12
- board[row][column] = player
13
- return board
14
  return board
15
 
16
- def format_board(board):
17
- """Convert board to player-friendly visualization"""
18
- symbols = {0: "⚪", 1: "🔴", 2: "🟡"}
19
- return [[symbols[cell] for cell in row] for row in board]
20
-
21
  def check_winner(board):
22
- """Check if there's a winner"""
23
- board = np.array(board)
24
-
25
- def check_line(line):
26
- return (len(line) >= 4 and
27
- (any(np.all(line[i:i+4] == 1) for i in range(len(line)-3)) or
28
- any(np.all(line[i:i+4] == 2) for i in range(len(line)-3))))
29
-
30
  # Horizontal
31
- for row in board:
32
- if check_line(row):
33
- return True
 
 
34
 
35
  # Vertical
36
- for col in board.T:
37
- if check_line(col):
38
- return True
 
 
39
 
40
  # Diagonals
41
- for offset in range(-2, 4):
42
- diag = np.diagonal(board, offset)
43
- if check_line(diag):
44
- return True
45
- diag = np.diagonal(np.fliplr(board), offset)
46
- if check_line(diag):
47
- return True
48
-
 
 
 
49
  return False
50
 
 
 
 
 
51
  def play_game(board, col, state):
52
  if state["game_over"]:
53
  return board, "Game is over! Click 'New Game' to play again."
54
 
55
- # Convert Dataframe to numpy array for game logic
56
- board_array = np.array([[0 if cell == "⚪" else 1 if cell == "🔴" else 2 for cell in row]
57
- for row in board.values.tolist()])
 
58
 
59
  # Player move
60
- board_array = make_move(board_array, col, 1)
 
 
 
 
61
  if check_winner(board_array):
62
  state["game_over"] = True
63
  return format_board(board_array), "You win! 🎉"
64
 
65
  # AI move
66
- config = Configuration({"rows": 6, "columns": 7, "inarow": 4})
67
- obs = Observation({"board": board_array.flatten().tolist(), "mark": 2})
68
 
69
  ai_col = my_agent(obs, config)
70
- board_array = make_move(board_array, ai_col, 2)
71
 
72
  if check_winner(board_array):
73
  state["game_over"] = True
@@ -75,15 +87,43 @@ def play_game(board, col, state):
75
 
76
  return format_board(board_array), "Your turn!"
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  def create_ui():
79
  with gr.Blocks(css=css) as demo:
80
  gr.Markdown("# Play Connect Four Against AI")
81
- gr.Markdown("You are Red (🔴), AI is Yellow (🟡)")
82
 
83
  state = gr.State({"game_over": False})
84
 
85
  with gr.Row(elem_classes="button-row"):
86
- buttons = [gr.Button(str(i), size="sm") for i in range(7)]
87
 
88
  board = gr.Dataframe(
89
  value=format_board(initialize_game()),
@@ -92,8 +132,8 @@ def create_ui():
92
  headers=False,
93
  wrap=True,
94
  elem_id="board",
95
- row_count=6,
96
- col_count=7
97
  )
98
 
99
  message = gr.Textbox(value="Your turn!", label="Status")
@@ -117,34 +157,5 @@ def create_ui():
117
 
118
  return demo
119
 
120
- # CSS definition
121
- css = """
122
- #board {
123
- max-width: 400px;
124
- margin: 20px auto;
125
- }
126
- #board table {
127
- width: 100%;
128
- table-layout: fixed;
129
- }
130
- #board td {
131
- text-align: center;
132
- font-size: 32px;
133
- padding: 12px;
134
- width: 14.28%; /* 100% / 7 columns */
135
- }
136
- .button-row {
137
- max-width: 400px;
138
- margin: 0 auto;
139
- display: flex;
140
- justify-content: space-between;
141
- gap: 10px;
142
- }
143
- .button-row button {
144
- flex: 1;
145
- min-width: 40px;
146
- }
147
- """
148
-
149
  demo = create_ui()
150
  demo.launch()
 
2
  import numpy as np
3
  from game_logic import my_agent, Configuration, Observation
4
 
5
+ # Constants
6
+ EMPTY = 0
7
+ PLAYER = 1
8
+ AI = 2
9
+ SYMBOLS = {EMPTY: "⚪", PLAYER: "🔴", AI: "🟡"}
10
+ BOARD_SIZE = (6, 7)
11
+ WIN_LENGTH = 4
12
+
13
  def initialize_game():
14
+ return np.zeros(BOARD_SIZE, dtype=int)
15
 
16
  def make_move(board, column, player):
17
+ """Make a move on the board - returns None if invalid move"""
18
+ row = np.where(board[:, column] == EMPTY)[0]
19
+ if len(row) == 0:
20
+ return None
21
+ board[row[-1], column] = player
22
  return board
23
 
 
 
 
 
 
24
  def check_winner(board):
25
+ """Optimized winner check using numpy operations"""
 
 
 
 
 
 
 
26
  # Horizontal
27
+ for row in range(BOARD_SIZE[0]):
28
+ for col in range(BOARD_SIZE[1] - WIN_LENGTH + 1):
29
+ window = board[row, col:col + WIN_LENGTH]
30
+ if np.all(window == PLAYER) or np.all(window == AI):
31
+ return True
32
 
33
  # Vertical
34
+ for row in range(BOARD_SIZE[0] - WIN_LENGTH + 1):
35
+ for col in range(BOARD_SIZE[1]):
36
+ window = board[row:row + WIN_LENGTH, col]
37
+ if np.all(window == PLAYER) or np.all(window == AI):
38
+ return True
39
 
40
  # Diagonals
41
+ for row in range(BOARD_SIZE[0] - WIN_LENGTH + 1):
42
+ for col in range(BOARD_SIZE[1] - WIN_LENGTH + 1):
43
+ # Positive diagonal
44
+ window = board[range(row, row + WIN_LENGTH), range(col, col + WIN_LENGTH)]
45
+ if np.all(window == PLAYER) or np.all(window == AI):
46
+ return True
47
+ # Negative diagonal
48
+ window = board[range(row, row + WIN_LENGTH), range(col + WIN_LENGTH - 1, col - 1, -1)]
49
+ if np.all(window == PLAYER) or np.all(window == AI):
50
+ return True
51
+
52
  return False
53
 
54
+ def format_board(board):
55
+ """Convert board to emoji representation"""
56
+ return [[SYMBOLS[cell] for cell in row] for row in board]
57
+
58
  def play_game(board, col, state):
59
  if state["game_over"]:
60
  return board, "Game is over! Click 'New Game' to play again."
61
 
62
+ # Convert display format to game logic format
63
+ board_array = np.array([[0 if cell == SYMBOLS[EMPTY] else
64
+ 1 if cell == SYMBOLS[PLAYER] else 2
65
+ for cell in row] for row in board.values.tolist()])
66
 
67
  # Player move
68
+ new_board = make_move(board_array.copy(), col, PLAYER)
69
+ if new_board is None:
70
+ return format_board(board_array), "Invalid move! Try again."
71
+ board_array = new_board
72
+
73
  if check_winner(board_array):
74
  state["game_over"] = True
75
  return format_board(board_array), "You win! 🎉"
76
 
77
  # AI move
78
+ config = Configuration({"rows": BOARD_SIZE[0], "columns": BOARD_SIZE[1], "inarow": WIN_LENGTH})
79
+ obs = Observation({"board": board_array.flatten().tolist(), "mark": AI})
80
 
81
  ai_col = my_agent(obs, config)
82
+ board_array = make_move(board_array, ai_col, AI)
83
 
84
  if check_winner(board_array):
85
  state["game_over"] = True
 
87
 
88
  return format_board(board_array), "Your turn!"
89
 
90
+ css = """
91
+ #board {
92
+ max-width: 400px;
93
+ margin: 20px auto;
94
+ }
95
+ #board table {
96
+ width: 100%;
97
+ table-layout: fixed;
98
+ }
99
+ #board td {
100
+ text-align: center;
101
+ font-size: 32px;
102
+ padding: 12px;
103
+ width: 14.28%;
104
+ }
105
+ .button-row {
106
+ max-width: 400px;
107
+ margin: 0 auto;
108
+ display: flex;
109
+ justify-content: space-between;
110
+ gap: 10px;
111
+ }
112
+ .button-row button {
113
+ flex: 1;
114
+ min-width: 40px;
115
+ }
116
+ """
117
+
118
  def create_ui():
119
  with gr.Blocks(css=css) as demo:
120
  gr.Markdown("# Play Connect Four Against AI")
121
+ gr.Markdown(f"You are {SYMBOLS[PLAYER]}, AI is {SYMBOLS[AI]}")
122
 
123
  state = gr.State({"game_over": False})
124
 
125
  with gr.Row(elem_classes="button-row"):
126
+ buttons = [gr.Button(str(i), size="sm") for i in range(BOARD_SIZE[1])]
127
 
128
  board = gr.Dataframe(
129
  value=format_board(initialize_game()),
 
132
  headers=False,
133
  wrap=True,
134
  elem_id="board",
135
+ row_count=BOARD_SIZE[0],
136
+ col_count=BOARD_SIZE[1]
137
  )
138
 
139
  message = gr.Textbox(value="Your turn!", label="Status")
 
157
 
158
  return demo
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  demo = create_ui()
161
  demo.launch()