DHEIVER commited on
Commit
c8b2153
·
verified ·
1 Parent(s): 9f39510

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -185
app.py CHANGED
@@ -1,227 +1,149 @@
1
  import gradio as gr
2
  import numpy as np
3
- import json
4
 
5
  class Minesweeper:
6
- def __init__(self, width=8, height=8, num_mines=10):
7
- self.width = width
8
- self.height = height
9
  self.num_mines = num_mines
 
 
 
10
  self.game_over = False
11
- self.won = False
12
  self.first_move = True
13
- self.initialize_board()
14
-
15
- def initialize_board(self):
16
- self.board = np.zeros((self.height, self.width), dtype=int)
17
- self.visible_board = np.full((self.height, self.width), -2, dtype=int)
18
-
19
  def place_mines(self, first_x, first_y):
20
- positions = [(x, y) for x in range(self.height) for y in range(self.width)]
21
  positions.remove((first_x, first_y))
22
  mine_positions = random.sample(positions, self.num_mines)
23
 
24
  for x, y in mine_positions:
25
  self.board[x, y] = -1
26
-
27
- for x in range(self.height):
28
- for y in range(self.width):
29
  if self.board[x, y] != -1:
30
  self.board[x, y] = self.count_adjacent_mines(x, y)
31
 
32
  def count_adjacent_mines(self, x, y):
33
  count = 0
34
- for dx in [-1, 0, 1]:
35
- for dy in [-1, 0, 1]:
36
- if dx == 0 and dy == 0:
37
- continue
38
- new_x, new_y = x + dx, y + dy
39
- if (0 <= new_x < self.height and
40
- 0 <= new_y < self.width and
41
- self.board[new_x, new_y] == -1):
42
  count += 1
43
  return count
44
 
45
  def reveal(self, x, y):
46
- if self.game_over or self.won:
47
- return
48
-
49
  if self.first_move:
50
  self.place_mines(x, y)
51
  self.first_move = False
52
-
53
  if self.board[x, y] == -1:
54
  self.game_over = True
55
- return
56
-
57
- self.flood_fill(x, y)
58
-
59
- if np.count_nonzero(self.visible_board == -2) == self.num_mines:
60
- self.won = True
61
-
62
- def flood_fill(self, x, y):
63
- if (not (0 <= x < self.height and 0 <= y < self.width) or
64
- self.visible_board[x, y] != -2):
65
- return
66
-
67
- self.visible_board[x, y] = self.board[x, y]
68
 
69
  if self.board[x, y] == 0:
70
- for dx in [-1, 0, 1]:
71
- for dy in [-1, 0, 1]:
72
- self.flood_fill(x + dx, y + dy)
73
-
74
- def toggle_flag(self, x, y):
75
- if self.game_over or self.won:
76
- return
77
 
78
- if self.visible_board[x, y] == -2:
79
- self.visible_board[x, y] = -1
80
- elif self.visible_board[x, y] == -1:
81
- self.visible_board[x, y] = -2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
- def create_game_html(game):
84
- # Cores para diferentes estados das células
85
- cell_styles = {
86
- -2: "background-color: #ccc;", # Coberto
87
- -1: "background-color: #f00;", # Bandeira
88
- 0: "background-color: #fff;", # Vazio
89
- 1: "background-color: #fff; color: blue;",
90
- 2: "background-color: #fff; color: green;",
91
- 3: "background-color: #fff; color: red;",
92
- 4: "background-color: #fff; color: darkblue;",
93
- 5: "background-color: #fff; color: darkred;",
94
- 6: "background-color: #fff; color: teal;",
95
- 7: "background-color: #fff; color: black;",
96
- 8: "background-color: #fff; color: gray;"
97
- }
98
-
99
- html = """
100
- <style>
101
- .minesweeper-board {
102
- display: inline-block;
103
- border: 2px solid #999;
104
- background-color: #eee;
105
- padding: 10px;
106
- }
107
- .board-row {
108
- display: flex;
109
- }
110
- .cell {
111
- width: 40px;
112
- height: 40px;
113
- border: 1px solid #999;
114
- display: flex;
115
- align-items: center;
116
- justify-content: center;
117
- font-weight: bold;
118
- font-size: 20px;
119
- cursor: pointer;
120
- user-select: none;
121
- }
122
- .game-over .cell {
123
- cursor: not-allowed;
124
- }
125
- </style>
126
-
127
- <div class="minesweeper-board">
128
- """
129
 
130
- # Adicionar status do jogo
131
  if game.game_over:
132
- html += '<div style="text-align: center; margin-bottom: 10px; color: red; font-weight: bold;">Game Over!</div>'
133
- elif game.won:
134
- html += '<div style="text-align: center; margin-bottom: 10px; color: green; font-weight: bold;">Você Venceu!</div>'
135
 
136
- # Criar tabuleiro
137
- for i in range(game.height):
138
- html += '<div class="board-row">'
139
- for j in range(game.width):
140
- cell_value = game.visible_board[i, j]
141
- style = cell_styles[cell_value]
142
-
143
- # Se o jogo acabou, mostrar as minas
144
- if game.game_over and game.board[i, j] == -1:
145
- cell_content = "💣"
146
- style = "background-color: #f00;"
147
- # Se é uma bandeira
148
- elif cell_value == -1:
149
- cell_content = "🚩"
150
- # Se está coberto
151
- elif cell_value == -2:
152
- cell_content = ""
153
- # Se é um número
154
- else:
155
- cell_content = str(cell_value) if cell_value > 0 else ""
156
-
157
- html += f'<div class="cell" style="{style}" data-x="{i}" data-y="{j}">{cell_content}</div>'
158
- html += '</div>'
159
- html += '</div>'
160
-
161
- # Adicionar JavaScript para handling de cliques
162
- html += """
163
- <script>
164
- function handleCellClick(event) {
165
- const cell = event.target;
166
- if (!cell.classList.contains('cell')) return;
167
-
168
- const x = cell.getAttribute('data-x');
169
- const y = cell.getAttribute('data-y');
170
-
171
- if (event.button === 2 || event.ctrlKey) { // Clique direito ou Ctrl+Clique
172
- handleAction(x, y, 'flag');
173
- } else { // Clique esquerdo
174
- handleAction(x, y, 'reveal');
175
- }
176
- }
177
-
178
- document.querySelector('.minesweeper-board').addEventListener('click', handleCellClick);
179
- document.querySelector('.minesweeper-board').addEventListener('contextmenu', (e) => {
180
- e.preventDefault();
181
- handleCellClick(e);
182
- });
183
- </script>
184
- """
185
-
186
- return html
187
-
188
- def handle_action(x, y, action, game_state):
189
- if not game_state:
190
- game = Minesweeper()
191
- else:
192
- game = Minesweeper()
193
- game.__dict__ = game_state
194
-
195
- if action == "reveal":
196
- game.reveal(int(x), int(y))
197
  else:
198
- game.toggle_flag(int(x), int(y))
199
-
200
- return create_game_html(game), game.__dict__
201
-
202
- def new_game():
203
- game = Minesweeper()
204
- return create_game_html(game), game.__dict__
205
-
206
- with gr.Blocks(title="Campo Minado") as demo:
207
- gr.Markdown("""
208
- # Campo Minado
209
 
210
- Instruções:
211
- - Clique esquerdo para revelar uma célula
212
- - Clique direito (ou Ctrl+Clique) para colocar/remover bandeira
213
- - Evite as minas!
214
- """)
215
 
216
- game_state = gr.State()
217
- board = gr.HTML()
218
 
219
- with gr.Row():
220
- new_game_btn = gr.Button("Novo Jogo")
 
221
 
222
- board.change(handle_action, [board], [board, game_state]) # Para atualização após cliques
223
- new_game_btn.click(new_game, outputs=[board, game_state])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
- demo.load(new_game, outputs=[board, game_state])
226
 
 
227
  demo.launch()
 
1
  import gradio as gr
2
  import numpy as np
3
+ import random
4
 
5
  class Minesweeper:
6
+ def __init__(self, size=8, num_mines=10):
7
+ self.size = size
 
8
  self.num_mines = num_mines
9
+ self.board = np.zeros((size, size), dtype=int)
10
+ self.revealed = np.zeros((size, size), dtype=bool)
11
+ self.flags = np.zeros((size, size), dtype=bool)
12
  self.game_over = False
 
13
  self.first_move = True
14
+
 
 
 
 
 
15
  def place_mines(self, first_x, first_y):
16
+ positions = [(i, j) for i in range(self.size) for j in range(self.size)]
17
  positions.remove((first_x, first_y))
18
  mine_positions = random.sample(positions, self.num_mines)
19
 
20
  for x, y in mine_positions:
21
  self.board[x, y] = -1
22
+
23
+ for x in range(self.size):
24
+ for y in range(self.size):
25
  if self.board[x, y] != -1:
26
  self.board[x, y] = self.count_adjacent_mines(x, y)
27
 
28
  def count_adjacent_mines(self, x, y):
29
  count = 0
30
+ for i in range(max(0, x-1), min(self.size, x+2)):
31
+ for j in range(max(0, y-1), min(self.size, y+2)):
32
+ if self.board[i, j] == -1:
 
 
 
 
 
33
  count += 1
34
  return count
35
 
36
  def reveal(self, x, y):
 
 
 
37
  if self.first_move:
38
  self.place_mines(x, y)
39
  self.first_move = False
40
+
41
  if self.board[x, y] == -1:
42
  self.game_over = True
43
+ return "💥 Game Over!"
44
+
45
+ self.revealed[x, y] = True
 
 
 
 
 
 
 
 
 
 
46
 
47
  if self.board[x, y] == 0:
48
+ for i in range(max(0, x-1), min(self.size, x+2)):
49
+ for j in range(max(0, y-1), min(self.size, y+2)):
50
+ if not self.revealed[i, j]:
51
+ self.reveal(i, j)
 
 
 
52
 
53
+ if self.check_win():
54
+ return "🎉 Você venceu!"
55
+ return None
56
+
57
+ def check_win(self):
58
+ return np.all(self.revealed | (self.board == -1))
59
+
60
+ def get_display(self):
61
+ display = []
62
+ for i in range(self.size):
63
+ row = []
64
+ for j in range(self.size):
65
+ if not self.revealed[i, j]:
66
+ if self.flags[i, j]:
67
+ row.append("🚩")
68
+ else:
69
+ row.append("⬜")
70
+ else:
71
+ if self.board[i, j] == -1:
72
+ row.append("💣")
73
+ elif self.board[i, j] == 0:
74
+ row.append("⬛")
75
+ else:
76
+ row.append(str(self.board[i, j]))
77
+ display.append(row)
78
+ return display
79
 
80
+ def create_game():
81
+ return Minesweeper()
82
+
83
+ def make_move(x, y, is_flag, game):
84
+ if game is None:
85
+ game = create_game()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
 
87
  if game.game_over:
88
+ return "Game Over! Clique em 'Novo Jogo'", game
 
 
89
 
90
+ if is_flag:
91
+ game.flags[x, y] = not game.flags[x, y]
92
+ message = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  else:
94
+ if game.flags[x, y]:
95
+ return "Remova a bandeira primeiro!", game
96
+ message = game.reveal(x, y)
 
 
 
 
 
 
 
 
97
 
98
+ if game.game_over:
99
+ game.revealed = np.ones((game.size, game.size), dtype=bool)
 
 
 
100
 
101
+ grid = game.get_display()
102
+ buttons = []
103
 
104
+ for i in range(game.size):
105
+ for j in range(game.size):
106
+ buttons.append(gr.Button(value=grid[i][j], scale=1))
107
 
108
+ return message if message else "Jogo em andamento", game
109
+
110
+ def create_interface():
111
+ with gr.Blocks() as demo:
112
+ gr.Markdown("""
113
+ # 💣 Campo Minado
114
+
115
+ - Clique nos quadrados para revelar
116
+ - Use 'Bandeira' para marcar possíveis minas
117
+ - Evite todas as minas!
118
+ """)
119
+
120
+ game_state = gr.State()
121
+ status = gr.Textbox(label="Status", value="Clique para começar!")
122
+
123
+ with gr.Column():
124
+ use_flag = gr.Checkbox(label="Bandeira")
125
+ new_game = gr.Button("Novo Jogo")
126
+
127
+ with gr.Row():
128
+ for i in range(8):
129
+ with gr.Column(scale=1):
130
+ for j in range(8):
131
+ btn = gr.Button("⬜", scale=1)
132
+ btn.click(
133
+ make_move,
134
+ inputs=[gr.Number(value=i, visible=False),
135
+ gr.Number(value=j, visible=False),
136
+ use_flag,
137
+ game_state],
138
+ outputs=[status, game_state]
139
+ )
140
+
141
+ new_game.click(
142
+ lambda: (None, create_game()),
143
+ outputs=[status, game_state]
144
+ )
145
 
146
+ return demo
147
 
148
+ demo = create_interface()
149
  demo.launch()