120 lines
4.1 KiB
Python
120 lines
4.1 KiB
Python
"""This module contains the Board class.
|
|
|
|
It is used to represent different elements for the whole board.
|
|
"""
|
|
|
|
from square import Square
|
|
|
|
|
|
class Board:
|
|
"""The Board class contains different elements of the board."""
|
|
|
|
def __init__(self, string):
|
|
self.lines = [""] * 9
|
|
|
|
i = 0
|
|
line = 0
|
|
while line < 9:
|
|
if string[i] == '\n':
|
|
line += 1
|
|
else:
|
|
self.lines[line] += string[i]
|
|
i += 1
|
|
|
|
self.columns = [""] * 9
|
|
|
|
for col in range(9):
|
|
for line in self.lines:
|
|
self.columns[col] += line[col]
|
|
|
|
self.__assert_lines_and_columns_have_same_values()
|
|
|
|
def __str__(self):
|
|
return "\n".join(self.lines)
|
|
|
|
def __assert_lines_and_columns_have_same_values(self):
|
|
differences = [
|
|
'X' for col, column in enumerate(self.columns)
|
|
for lin, line, in enumerate(self.lines)
|
|
if self.lines[lin][col] != self.columns[col][lin]
|
|
]
|
|
|
|
assert len(differences) == 0
|
|
|
|
def __compute_possible_values_from_lines(self):
|
|
"""Compute possible values for each number in a line.
|
|
|
|
Go through each line and add possible values to each square that hasn't
|
|
been found yet. The values are computed based on the fact that they
|
|
aren't already present in that same line.
|
|
"""
|
|
|
|
for line_index, line in enumerate(self.lines):
|
|
self.lines[line_index] = list(line)
|
|
for column in range(9):
|
|
if line[column] == '.':
|
|
self.lines[line_index][column] = {
|
|
number for number in range(1, 10)
|
|
if str(number) not in line
|
|
}
|
|
else:
|
|
self.lines[line_index][column] = {line[column]}
|
|
|
|
def __compute_possible_values_from_columns(self):
|
|
"""Compute possible values for each number in a column.
|
|
|
|
Go through each column and add possible values to each square that
|
|
hasn't been found yet. The values are computed based on the fact that
|
|
they aren't already present in that same column.
|
|
"""
|
|
|
|
for column_index, column in enumerate(self.columns):
|
|
self.columns[column_index] = list(column)
|
|
for line in range(9):
|
|
if column[line] == '.':
|
|
self.columns[column_index][line] = {
|
|
number for number in range(1, 10)
|
|
if str(number) not in column
|
|
}
|
|
else:
|
|
self.columns[column_index][line] = {column[line]}
|
|
|
|
def compute_possible_values(self):
|
|
"""Compute possible values for each square in the board."""
|
|
|
|
self.__compute_possible_values_from_lines()
|
|
self.__compute_possible_values_from_columns()
|
|
|
|
def intersect_possible_values(self):
|
|
"""Remove impossible values from possibilities in lines and columns.
|
|
|
|
Go through each line and for each square intersect the set with the set
|
|
in the same square in self.columns.
|
|
Go through each column and for each square intersect the set with the
|
|
set in the same square in self.lines.
|
|
|
|
Note: you need to run compute_possible_values first.
|
|
"""
|
|
|
|
for lin, line in enumerate(self.lines):
|
|
for col, column in enumerate(self.columns):
|
|
self.lines[lin][col] = line[col].intersection(column[lin])
|
|
self.columns[col][lin] = column[lin].intersection(line[col])
|
|
|
|
self.__assert_lines_and_columns_have_same_values()
|
|
|
|
def create_squares(self):
|
|
"""Make each square of the board a Square object."""
|
|
|
|
for lin, line in enumerate(self.lines):
|
|
for col, column in enumerate(self.columns):
|
|
self.lines[lin][col] = Square(lin, col, line[col])
|
|
self.columns[col][lin] = Square(lin, col, column[lin])
|
|
|
|
differences = [
|
|
'X' for col, column in enumerate(self.columns)
|
|
for lin, line, in enumerate(self.lines)
|
|
if self.lines[lin][col].content != self.columns[col][lin].content
|
|
]
|
|
|
|
assert len(differences) == 0
|