-
Notifications
You must be signed in to change notification settings - Fork 0
/
solver.py
114 lines (75 loc) · 2.6 KB
/
solver.py
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
__author__ = 'alex'
from board import Board
from random import randint
class Solver(object):
def __init__(self):
self.board = Board(13, 13)
def random_pt(self):
return randint(0,13), randint(0,13)
class Cases(object):
def __init__(self):
pass
def _get_clicked_sqs(self, board: Board) -> set:
return board.unclicked_squares - board.blank
def _get_visible_nums(self, board: Board) -> set:
return board.unclicked_squares - set(board.numbers)
def _get_zero_sqs(self, board: Board) -> set:
return self._get_visible_nums(board) - self._get_clicked_sqs(board)
def _get_mapped_neighbors(self, board: Board, pt: tuple) -> set:
neighbors = board.gen_neighbors(pt)
mapped_neighbors = {neighbor: pt for neighbor in neighbors}
pass
def _get_edges(self, board, pt, neighbors=None):
if not neighbors:
neighbors = board.gen_neighbors(pt)
x, y = pt
xinterval, yinterval = (x-1, x, x+1), (y-1, y, y+1)
edges = left, right, top, bottom = \
{(x-1, yi) for yi in yinterval}, \
{(x+1, yi) for yi in yinterval}, \
{(xi, y+1) for xi in xinterval}, \
{(xi, y-1) for xi in xinterval}
return edges
def _is_on_soft_edge(self, board: Board, pt: tuple, neighbors=None, edges=None) -> bool:
if not neighbors:
neighbors = board.gen_neighbors(pt)
if not edges:
edges = self._get_edges(board, pt, neighbors)
#intersection of visible zeros and neighbors
zero_sqs = self._get_zero_sqs(board)
zero_neighbors = zero_sqs & neighbors
# check if 3-consec pts are subsets of zero_neighbors, bools
return any(edge < zero_neighbors for edge in edges)
def _is_on_edge(self, board: Board, pt: tuple, neighbors=None, edges=None) -> bool:
if not neighbors:
neighbors = board.gen_neighbors(pt)
if len(neighbors) <= 5:
return True
if not edges:
edges = self._get_edges(board, pt, neighbors)
return self._is_on_soft_edge(board, pt, neighbors, edges)
def basic_patterns(self, board: Board, pt) -> None:
if pt in board.numbers:
bombs = board.numbers[pt]
neighbors = board.gen_neighbors(pt)
open_neighbors = neighbors & board.unclicked_squares
if len(open_neighbors) == bombs:
for neighbor in neighbors:
board.select_sq(neighbor)
self.basic_patterns(neighbor)
def edge_one_one(self, board: Board, pt, neighbors=None) -> None:
if not neighbors:
neighbors = board.gen_neighbors(pt)
has_edge = self._is_on_edge(board, pt, neighbors)
if not has_edge:
return False
def main():
s = Solver()
pt = s.random_pt()
s.basic_patterns(pt)
pt = s.random_pt()
s.basic_patterns(pt)
pt = s.random_pt()
s.basic_patterns(pt)
if __name__ == "__main__":
main()