-
Notifications
You must be signed in to change notification settings - Fork 0
/
Board.py
208 lines (174 loc) · 6.41 KB
/
Board.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
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import random
from random import shuffle
from Cell import Cell
class Board:
def __init__(self, solution=[], user_board=[]):
self.solution = solution
if solution == []:
# set board with 0's
for i in range(9): # row
row = []
for j in range(9): # col
row.append(0)
self.solution.append(row)
self.user_board = user_board
if user_board == []:
for i in range(9):
row = []
for j in range(9):
row.append(0)
self.user_board.append(row)
self.starting_board = []
for i in range(9):
row = []
for j in range(9):
row.append(0)
self.starting_board.append(row)
self.num_solutions = 0
self.current_cell = (0, 0) # (x, y)
self.initialize()
self.remove_nums()
self.copy_solution()
self.notes_mode = False
self.most_recent = ()
# initializes a solution board for the game
def initialize(self):
options = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for x in range(81):
r = x // 9
c = x % 9
if self.solution[r][c] == 0:
shuffle(options)
for num in options:
if self.can_add_cell(r, c, num):
self.solution[r][c] = num
if self.is_grid_full():
return True
else:
if self.initialize():
return True
self.solution[r][c] = 0
break
# self.starting_board = self.solution
return False
# determines if solution board has been filled with numbers
def is_grid_full(self):
for r in self.solution:
for c in r:
if c == 0: return False
return True
# prints board to console (testing purposes)
def print_board(self):
for r in range(9):
for c in range(9):
print("{} ".format(self.solution[r][c]), end='')
print("\n")
# sets the slot at the given row and column to the given number
# def set_cell(self, num):
# self.user_board[self.current_cell[1]][self.current_cell[0]].set_user_value(num)
# checks if a number can be put in that row and column
def can_add_cell(self, row, column, number_to_add):
# check row
for cell in self.solution[row]:
if cell == number_to_add:
return False
# check column
for i in self.solution:
if i[column] == number_to_add:
return False
# check 3x3 box
# find coordinates of 3x3 box
x = column // 3
y = row // 3
x *= 3
y *= 3
for r in range(y, y + 3):
for c in range(x, x + 3):
if self.solution[r][c] == number_to_add:
return False
# if all tests pass
return True
# removes numbers that won't be visible on the board
def remove_nums(self):
for i in range(9):
for j in range(9):
self.starting_board[i][j] = self.solution[i][j]
nums = random.randint(70, 75)
for x in range(nums): # CHANGE BACK
cell, row, col = 0, 0, 0
while cell == 0:
# pick random row and column
row = random.randint(0, 8)
col = random.randint(0, 8)
cell = self.solution[row][col]
self.starting_board[row][col] = 0
# transfers solution to the board the user will see
def copy_solution(self):
for r in range(9):
for c in range(9):
self.user_board[r][c] = Cell(c, r, self.solution[r][c], 0, self.starting_board[r][c] != 0)
# sets the current highlighted cell to the given coordinates
def set_current_cell(self, row, col):
self.current_cell = (col, row)
def change_cell_notes(self, num):
self.user_board[self.current_cell[1]][self.current_cell[0]].switch_note(num)
def reset_notes(self):
for x in range(1, 10):
self.user_board[self.current_cell[1]][self.current_cell[0]].notes[x] = False
# sets the current cell to the given number if it wasn't already given
def set_entry(self, num):
if self.user_board[self.current_cell[1]][self.current_cell[0]].given:
print("You can't enter a number here, it was already given to you!")
else:
self.user_board[self.current_cell[1]][self.current_cell[0]].set_user_value(num)
# determines if game has been won yet
def game_over(self):
for i in range(9):
for j in range(9):
if not self.user_board[i][j].given:
if not self.cell_is_allowed(i, j):
return False
return True
# for the game over function, checks if the cell in a rowxcolumn can be there
def cell_is_allowed(self, row, col):
num = self.user_board[row][col].user_value
# check row
for i in range(8):
if self.user_board[row][i].user_value == num and i != col:
return False
# check column
for i in range(8):
if self.user_board[i][col].user_value == num and i != row:
return False
# check 3x3 box
# find coordinates of 3x3 box
x = col // 3
y = row // 3
x *= 3
y *= 3
for i in range(y, y + 3):
for j in range(x, x + 3):
if self.user_board[i][j] == num and i != row and j != col:
return False
return True
def set_most_recent(self, row, col):
self.most_recent = (col, row)
def update_surrounding_notes(self):
# most recent user-entered value
row = self.most_recent[1]
col = self.most_recent[0]
val = self.user_board[row][col].user_value
# modify row
for cell in self.user_board[row]:
cell.notes[val] = False
# modify col
for r in self.user_board:
r[col].notes[val] = False
# modify 3x3 box
x = col // 3
y = row // 3
x *= 3
y *= 3
for r in range(y, y + 3):
for c in range(x, x + 3):
self.user_board[r][c].notes[val] = False