import gradio as gr import random # === Game Configuration === BOARD_WIDTH = 10 BOARD_HEIGHT = 10 NUM_MINES = 15 # === Global Game State === game_state = { "board": [], "game_over": False, "win": False } # === Board Initialization === def initialize_board(width, height, num_mines): board = [[{'mine': False, 'revealed': False, 'flagged': False, 'adjacent': 0} for _ in range(width)] for _ in range(height)] # Random mine placement mines = set() while len(mines) < num_mines: r = random.randint(0, height - 1) c = random.randint(0, width - 1) if not board[r][c]['mine']: board[r][c]['mine'] = True mines.add((r, c)) # Increment adjacent mine counts for i in range(max(0, r - 1), min(height, r + 2)): for j in range(max(0, c - 1), min(width, c + 2)): if (i, j) != (r, c): board[i][j]['adjacent'] += 1 return board # === Flood Fill Reveal Logic === def reveal_tile(board, row, col): if board[row][col]['revealed'] or board[row][col]['flagged']: return board[row][col]['revealed'] = True # Reveal neighboring tiles recursively if no adjacent mines if board[row][col]['adjacent'] == 0 and not board[row][col]['mine']: for i in range(max(0, row - 1), min(len(board), row + 2)): for j in range(max(0, col - 1), min(len(board[0]), col + 2)): if not board[i][j]['revealed']: reveal_tile(board, i, j) # === Flagging === def toggle_flag(board, row, col): if not board[row][col]['revealed']: board[row][col]['flagged'] = not board[row][col]['flagged'] # === Win Condition === def check_win(board): for row in board: for tile in row: if not tile['mine'] and not tile['revealed']: return False return True # === Display Conversion === def cell_display(cell): if cell['flagged']: return "๐Ÿšฉ" if not cell['revealed']: return "" if cell['mine']: return "๐Ÿ’ฃ" return str(cell['adjacent']) if cell['adjacent'] > 0 else "" def update_display(): return [[cell_display(cell) for cell in row] for row in game_state["board"]] # === User Action Handler === def handle_click(x, y, action): if game_state["game_over"]: return update_display(), "Game over! Please reset." if not (0 <= x < BOARD_WIDTH and 0 <= y < BOARD_HEIGHT): return update_display(), "Invalid coordinates." board = game_state["board"] if action == "Reveal": if board[y][x]['mine']: board[y][x]['revealed'] = True game_state["game_over"] = True return update_display(), "๐Ÿ’ฅ You hit a mine! Game over." else: reveal_tile(board, y, x) elif action == "Flag": toggle_flag(board, y, x) if check_win(board): game_state["game_over"] = True game_state["win"] = True return update_display(), "๐ŸŽ‰ Congratulations! You won!" return update_display(), "Continue playing..." # === Game Reset === def reset_game(): game_state["board"] = initialize_board(BOARD_WIDTH, BOARD_HEIGHT, NUM_MINES) game_state["game_over"] = False game_state["win"] = False return update_display(), "Game reset!" # === Gradio UI === with gr.Blocks() as demo: gr.Markdown("## ๐Ÿงจ Minesweeper") gr.Markdown("Reveal tiles and flag the mines. Good luck!") status = gr.Textbox(label="Game Status", value="Game initialized!", interactive=False) board_display = gr.Dataframe(value=update_display(), interactive=False, headers=None) with gr.Row(): x_input = gr.Number(label="X (Column)", value=0, precision=0) y_input = gr.Number(label="Y (Row)", value=0, precision=0) action = gr.Radio(["Reveal", "Flag"], value="Reveal", label="Action") with gr.Row(): move_btn = gr.Button("Make Move") reset_btn = gr.Button("Reset Game") move_btn.click(fn=handle_click, inputs=[x_input, y_input, action], outputs=[board_display, status]) reset_btn.click(fn=reset_game, outputs=[board_display, status]) # Initialize game on startup reset_game() demo.launch()