Minesweeper / app.py
DHEIVER's picture
Update app.py
94ea014 verified
raw
history blame
6.67 kB
import gradio as gr
import numpy as np
import matplotlib.pyplot as plt
import random
class Minesweeper:
def __init__(self, width=8, height=8, num_mines=10):
self.width = width
self.height = height
self.num_mines = num_mines
self.game_over = False
self.won = False
self.first_move = True
self.initialize_board()
def initialize_board(self):
self.board = np.zeros((self.height, self.width), dtype=int)
self.visible_board = np.full((self.height, self.width), -2, dtype=int)
def place_mines(self, first_x, first_y):
positions = [(x, y) for x in range(self.height) for y in range(self.width)]
positions.remove((first_x, first_y))
mine_positions = random.sample(positions, self.num_mines)
for x, y in mine_positions:
self.board[x, y] = -1
for x in range(self.height):
for y in range(self.width):
if self.board[x, y] != -1:
self.board[x, y] = self.count_adjacent_mines(x, y)
def count_adjacent_mines(self, x, y):
count = 0
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
if dx == 0 and dy == 0:
continue
new_x, new_y = x + dx, y + dy
if (0 <= new_x < self.height and
0 <= new_y < self.width and
self.board[new_x, new_y] == -1):
count += 1
return count
def reveal(self, x, y):
if self.game_over or self.won:
return
if self.first_move:
self.place_mines(x, y)
self.first_move = False
if self.board[x, y] == -1:
self.game_over = True
return
self.flood_fill(x, y)
if np.count_nonzero(self.visible_board == -2) == self.num_mines:
self.won = True
def flood_fill(self, x, y):
if (not (0 <= x < self.height and 0 <= y < self.width) or
self.visible_board[x, y] != -2):
return
self.visible_board[x, y] = self.board[x, y]
if self.board[x, y] == 0:
for dx in [-1, 0, 1]:
for dy in [-1, 0, 1]:
self.flood_fill(x + dx, y + dy)
def toggle_flag(self, x, y):
if self.game_over or self.won:
return
if self.visible_board[x, y] == -2:
self.visible_board[x, y] = -1
elif self.visible_board[x, y] == -1:
self.visible_board[x, y] = -2
def create_board_image(game):
fig, ax = plt.subplots(figsize=(8, 8))
colors = {
-2: '#CCCCCC', # Coberto
-1: '#FF0000', # Bandeira/Mina
0: '#FFFFFF', # Vazio
1: '#0000FF', # Azul
2: '#008000', # Verde
3: '#FF0000', # Vermelho
4: '#000080', # Azul escuro
5: '#800000', # Vermelho escuro
6: '#008080', # Ciano
7: '#000000', # Preto
8: '#808080' # Cinza
}
for i in range(game.height):
for j in range(game.width):
color = colors[game.visible_board[i, j]]
ax.add_patch(plt.Rectangle((j, game.height-1-i), 1, 1, facecolor=color, edgecolor='black'))
if game.visible_board[i, j] > 0:
plt.text(j+0.5, game.height-1-i+0.5, str(game.visible_board[i, j]),
horizontalalignment='center',
verticalalignment='center',
color='black')
elif game.visible_board[i, j] == -1:
plt.text(j+0.5, game.height-1-i+0.5, 'F',
horizontalalignment='center',
verticalalignment='center',
color='black')
if game.game_over:
for i in range(game.height):
for j in range(game.width):
if game.board[i, j] == -1:
ax.add_patch(plt.Rectangle((j, game.height-1-i), 1, 1, facecolor='red', edgecolor='black'))
plt.text(j+0.5, game.height-1-i+0.5, 'M',
horizontalalignment='center',
verticalalignment='center',
color='black')
ax.set_xlim(0, game.width)
ax.set_ylim(0, game.height)
ax.set_xticks(range(game.width))
ax.set_yticks(range(game.height))
ax.grid(True)
status = "Jogando"
if game.game_over:
status = "Game Over!"
elif game.won:
status = "Você Venceu!"
plt.title(f'Campo Minado - {status}')
return fig
def make_move(x, y, action, game_state):
if not game_state:
game = Minesweeper(8, 8, 10)
else:
game = Minesweeper(8, 8, 10)
game.__dict__ = game_state
if action == "reveal":
game.reveal(x, y)
else:
game.toggle_flag(x, y)
fig = create_board_image(game)
status = "Jogando"
if game.game_over:
status = "Game Over!"
elif game.won:
status = "Você Venceu!"
return fig, game.__dict__, status
def new_game():
game = Minesweeper(8, 8, 10)
fig = create_board_image(game)
return fig, game.__dict__, "Novo jogo iniciado!"
with gr.Blocks(title="Campo Minado") as demo:
gr.Markdown("""
# Campo Minado
Instruções:
1. Digite as coordenadas (0-7) para linha e coluna
2. Escolha "Revelar" para abrir uma célula ou "Bandeira" para marcar uma mina
3. Evite as minas e revele todas as células seguras!
""")
game_state = gr.State()
board = gr.Plot(label="Tabuleiro")
status = gr.Textbox(label="Status do Jogo", interactive=False)
with gr.Row():
x_coord = gr.Number(label="Linha (0-7)", minimum=0, maximum=7, step=1)
y_coord = gr.Number(label="Coluna (0-7)", minimum=0, maximum=7, step=1)
with gr.Row():
reveal_btn = gr.Button("Revelar")
flag_btn = gr.Button("Bandeira")
new_game_btn = gr.Button("Novo Jogo")
reveal_btn.click(
make_move,
inputs=[x_coord, y_coord, gr.Textbox(value="reveal", visible=False), game_state],
outputs=[board, game_state, status]
)
flag_btn.click(
make_move,
inputs=[x_coord, y_coord, gr.Textbox(value="flag", visible=False), game_state],
outputs=[board, game_state, status]
)
new_game_btn.click(new_game, outputs=[board, game_state, status])
demo.load(new_game, outputs=[board, game_state, status])
demo.launch()