File size: 4,259 Bytes
2308956
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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()