-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathminesweeper.py
More file actions
156 lines (129 loc) · 3.9 KB
/
Copy pathminesweeper.py
File metadata and controls
156 lines (129 loc) · 3.9 KB
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# Console Minesweeper with board size and bomb rate adjustment support
import random
import sys
### VARIABLES
ROWS = 10
COLS = 10
BOMB_DENSITY = 0.1
bombs = int(ROWS * COLS * BOMB_DENSITY)
# bombs = int(math.sqrt(ROWS*COLS))
################
field = [["-" for x in range(COLS)] for y in range(ROWS)]
bombmap = [["-" for x in range(COLS)] for y in range(ROWS)]
def fill_bombs():
while sum(row.count("*") for row in bombmap) < bombs:
bombmap[random.randint(0, ROWS - 1)][random.randint(0, COLS - 1)] = "*"
fill_bombs()
def get_spaces(max, text):
text = str(text)
spaces_amount = max - len(text)
spaces = ""
for i in range(spaces_amount):
spaces += " "
return spaces
def print_field(show_bombs=False):
if show_bombs:
# Deep copy of field
field_display = [row[:] for row in field]
for row in range(ROWS):
for col in range(COLS):
if bombmap[row][col] == "*":
field_display[row][col] = "*"
else:
field_display = field
max_digits_row = 0
for row in range(ROWS):
length = len(str(row))
max_digits_row = max(max_digits_row, length)
max_digits_col = 0
for col in range(COLS):
length = len(str(col))
max_digits_col = max(max_digits_col, length)
top_legend = get_spaces(max_digits_row + 2, "")
for col in range(COLS): # add numbers top legend
top_legend += str(col + 1) + get_spaces(max_digits_col + 1, col + 1)
print(top_legend)
for row in range(ROWS):
indent = get_spaces(max_digits_row + 2, row + 1)
# print(indentAmount)
readable_row = str(row + 1) + indent
for col in range(COLS):
readable_row += field_display[row][col] + get_spaces(max_digits_col, "")
print(readable_row)
def get_surrounding(row, col):
surrounding = []
for row_offset in (-1, 0, 1):
for col_offset in (-1, 0, 1):
if row_offset == col_offset == 0:
continue # don't count itself
new_row = row + row_offset
new_col = col + col_offset
if 0 <= new_row < ROWS and 0 <= new_col < COLS:
surrounding.append((new_row, new_col))
return surrounding
def count_surrounding_bombs(row, col):
count = sum(1 for r, c in get_surrounding(row, col) if bombmap[r][c] == "*")
return str(count) if count else " "
def flag(row, col):
if field[row][col] == "-":
field[row][col] = "F"
elif field[row][col] == "F":
field[row][col] = "-"
def uncover(row, col):
# Iterative flood fill to avoid recursion limit
stack = [(row, col)]
while stack:
r, c = stack.pop()
if field[r][c] != "-":
continue
if bombmap[r][c] == "*":
return True # BOMB UNCOVERED
surrounding_bombs = count_surrounding_bombs(r, c)
field[r][c] = surrounding_bombs
if surrounding_bombs == " ":
for nr, nc in get_surrounding(r, c):
if field[nr][nc] == "-":
stack.append((nr, nc))
return False
def check_win():
for row in range(ROWS):
for col in range(COLS):
# breakpoint()
if str(bombmap[row][col]) == "-" and str(field[row][col]) != " ":
return False
return True
print_field(False)
while True:
while True:
try:
chosen_col = int(input("Choose a column:")) - 1
chosen_row = int(input("Choose a row:")) - 1
if field[chosen_row][chosen_col] in ["-", "F"]:
break
else:
raise
except ValueError:
print("Choose a different position!")
continue
while True:
action = input("Choose an action -> Hit: 'x', Flag: 'f'").lower()
if action in ["x", "f"]:
break
else:
continue
if action == "f":
flag(chosen_row, chosen_col)
print_field(False)
if action == "x":
if uncover(chosen_row, chosen_col):
print_field(True)
print("BOOM. You died!")
sys.exit()
else:
print_field(False)
print("Phew. No bomb.")
if check_win():
print(
f"You win! Configuration: {ROWS} x {COLS} with a bomb density of {BOMB_DENSITY} ({bombs} bombs)."
)
sys.exit()