def test_kakuro_not_solution(self): game = GameField(3, 3) cell_column = Cell(CellType.RULES, column_rule=3, length_column=2) cell_row = Cell(CellType.RULES, row_rule=17, length_row=2) game.init_cell(0, 1, cell_column) game.init_cell(1, 0, cell_row) solver = Solver(game) with self.assertRaises(exc.KakuroNotSolution): self.assertRaises(solver.solve())
def get_solve(input_file, output_file): parser = Parser() try: pairs = parser.parse(input_file) except exc.IncorrectFileArgument as e: print('Incorrect file{0}'.format(input_file)) return except Exception as fe: print('Unrecognized error in file') return dimension = pairs[0] game = GameField(dimension, dimension) for cells in pairs[1:]: for key in cells.keys(): game.init_cell(key[0], key[1], cells[key]) solver = Solver(game) painter = Painter(64) try: solution = solver.solve() except exc.KakuroNotSolution as e: print('Not solution') return painter.paint(solution, output_file, dimension)
def test_init_put_rule_cell_column(self): game = GameField(10, 10) cell = Cell(CellType.RULES, column_rule=10, length_column=2) game.init_cell(5, 5, cell) self.assertEqual(CellType.PLAY, game.field[6][5].get_type()) self.assertEqual(CellType.PLAY, game.field[7][5].get_type())
def test_init_put_rule_cell_row(self): game = GameField(10, 10) cell = Cell(CellType.RULES, row_rule=10, length_row=2) game.init_cell(5, 5, cell) self.assertEqual(CellType.PLAY, game.field[5][6].get_type()) self.assertEqual(CellType.PLAY, game.field[5][7].get_type())
def test_init_put_play_cell(self): game = GameField(10, 10) cell = Cell(CellType.PLAY, value=10) game.init_cell(5, 5, cell) self.assertEqual(cell, game.field[5][5])
class SolverTest(unittest.TestCase): def setUp(self): self.game = GameField(4, 4) self.game.init_cell( 0, 1, Cell(CellType.RULES, column_rule=16, length_column=2)) self.game.init_cell( 0, 2, Cell(CellType.RULES, column_rule=15, length_column=3)) self.game.init_cell(1, 0, Cell(CellType.RULES, row_rule=17, length_row=2)) self.game.init_cell(2, 0, Cell(CellType.RULES, row_rule=15, length_row=3)) self.game.init_cell(3, 1, Cell(CellType.RULES, row_rule=3, length_row=2)) self.game.init_cell( 1, 3, Cell(CellType.RULES, column_rule=4, length_column=2)) def test_get_list(self): solver = Solver(self.game) expected = [ self.game.field[1][1], self.game.field[1][2], self.game.field[2][1], self.game.field[2][2], self.game.field[2][3], self.game.field[3][2], self.game.field[3][3] ] solver.get_list() self.assertEqual(expected, solver.all_cells) def test_correct_solve(self): solver = Solver(self.game) self.game.field[1][1].set_value(9) self.game.field[1][2].set_value(8) self.game.field[2][1].set_value(7) self.game.field[2][2].set_value(5) self.game.field[2][3].set_value(3) self.game.field[3][2].set_value(2) self.game.field[3][3].set_value(1) self.assertTrue(solver.is_correct_solve()) def test_kakuro_not_solution(self): game = GameField(3, 3) cell_column = Cell(CellType.RULES, column_rule=3, length_column=2) cell_row = Cell(CellType.RULES, row_rule=17, length_row=2) game.init_cell(0, 1, cell_column) game.init_cell(1, 0, cell_row) solver = Solver(game) with self.assertRaises(exc.KakuroNotSolution): self.assertRaises(solver.solve())
class GUI: def __init__(self, root, dimension): self.root = root self.dimension = dimension self.img_for_button = PhotoImage( file=os.path.join(os.getcwd(), 'img', 'cell.gif')) self.list_button = [] self.size_button = 64 self.all_img = [] self.draw_menu() self.root.mainloop() def draw_field(self): for x in range(0, self.dimension): line_button = [] for y in range(0, self.dimension): line_button.append(Button(self.root)) line_button[y]['command'] = partial(self.open_setting_window, x, y) line_button[y]['image'] = self.img_for_button line_button[y].grid(row=x, column=y) self.list_button.append(line_button) def open_setting_window(self, x, y): setting_root = Tk() self.setting_new_root(setting_root, x, y) def setting_new_root(self, setting_root, x, y): width = 10 height = 2 row_label = Label(setting_root, width=width, height=height, text="Row") column_label = Label(setting_root, width=width, height=height, text="Column") sum_label = Label(setting_root, width=width, height=height, text="Sum") length_label = Label(setting_root, width=width, height=height, text="Length") sum_row = Entry(setting_root, width=width) sum_column = Entry(setting_root, width=width) length_row = Entry(setting_root, width=width) length_column = Entry(setting_root, width=width) apply = Button(setting_root, width=width, height=height, text='Apply') apply['command'] = partial(self.put_cell, sum_row, length_row, sum_column, length_column, x, y, setting_root) cancel = Button(setting_root, width=width, height=height, text='Cancel') cancel['command'] = partial(self.close_window, setting_root) row_label.grid(row=1, column=0) column_label.grid(row=2, column=0) sum_label.grid(row=0, column=1) length_label.grid(row=0, column=2) sum_row.grid(row=1, column=1) sum_column.grid(row=2, column=1) length_row.grid(row=1, column=2) length_column.grid(row=2, column=2) apply.grid(row=3, column=0) cancel.grid(row=3, column=2) setting_root.mainloop() def close_window(self, side_root): side_root.destroy() side_root.quit() def put_cell(self, sum_row, length_row, sum_column, length_column, x, y, root): try: row_rule = int(sum_row.get()) column_rule = int(sum_column.get()) row = int(length_row.get()) column = int(length_column.get()) except Exception as e: self.throw_exception('Argument error', 'One or more argument are NaN', root) return if not self.check_arguments(row_rule, column_rule, row, column, x, y, root): return self.close_window(root) cell = Cell(CellType.RULES, row_rule=row_rule, column_rule=column_rule, length_row=row, length_column=column) self.game_field.init_cell(x, y, cell) self.redraw() def check_arguments(self, row_rule, column_rule, row, column, x, y, setting_root): if column_rule > 45 or row_rule > 45: self.throw_exception('Argument error', 'The amount can not exceed 45', setting_root) return False if row_rule < 0 or column_rule < 0 or row < 0 or column < 0: self.throw_exception('Argument error', 'One or more argument less zero', setting_root) return False if x + column >= self.dimension: self.throw_exception('Argument error', 'Row length too large', setting_root) return False if y + row >= self.dimension: self.throw_exception('Argument error', 'Column length too large', setting_root) return False return True def redraw(self): for x in range(0, self.dimension): for y in range(0, self.dimension): if self.game_field.field[x][y].is_rules(): row = self.game_field.field[x][y].get_rules()[0] column = self.game_field.field[x][y].get_rules()[1] img = self.get_image_for_button(row, column) self.list_button[x][y]['image'] = img if self.game_field.field[x][y].get_type() == CellType.PLAY: value = self.game_field.field[x][y].get_value() self.list_button[x][y][ 'image'] = self.get_image_value_cell(value) self.root.update() def get_image_for_button(self, row, column): img = Image.new('RGB', (self.size_button, self.size_button), 'white') drawer = ImageDraw.Draw(img) if row > 0: to_str = str(int(row)) numbers = self.count_number(row) drawer.text([self.size_button // 2, 0], text=to_str[0:numbers], fill='black', align='center') if column > 0: to_str = str(int(column))[0:3] numbers = self.count_number(column) drawer.text([0, self.size_button // 2], text=to_str[0:numbers], fill='black') drawer.line([0, 0, self.size_button, self.size_button], 'black') p_img = ImageTk.PhotoImage(img) self.all_img.append(p_img) return p_img def count_number(self, n): i = 0 while n > 0: n = n // 10 i += 1 return i def get_image_value_cell(self, value): img = Image.new('RGB', (self.size_button, self.size_button), 'white') drawer = ImageDraw.Draw(img) drawer.text([self.size_button // 2, self.size_button // 2], text=str(value), fill='black', align='center') p_img = ImageTk.PhotoImage(img) self.all_img.append(p_img) return p_img def draw_menu(self): menu_bar = Menu(self.root) file_menu = Menu(menu_bar) file_menu.add_command(label='Create new kakuro', command=self.start_setting) file_menu.add_command(label='Open from file', command=self.open_from_file) file_menu.add_command(label="Save kakuro to image file", command=self.save) menu_bar.add_cascade(label='File', menu=file_menu) solve_menu = Menu(menu_bar, tearoff=0) solve_menu.add_command(label='Solve', command=self.solve) menu_bar.add_cascade(label="Solution", menu=solve_menu) self.root.config(menu=menu_bar) def solve(self): solver = Solver(self.game_field) solution = solver.solve() if solution is None: return self.game_field.field = solution self.redraw() def start_setting(self): start_setting_root = Tk() start_setting_root.title('Create new kakuro') width = 15 height = 2 label_d = Label(start_setting_root, text='Select the dimension', width=width, height=height) entry_d = Entry(start_setting_root, width=width) create_button = Button(start_setting_root, width=width, height=height, text='Create') cancel = Button(start_setting_root, width=width, height=height, text='Cancel') cancel['command'] = partial(self.close_window, start_setting_root) create_button['command'] = partial(self.start_new_kakuro, entry_d, start_setting_root) label_d.grid(row=0, column=0, padx=10) entry_d.grid(row=0, column=2) create_button.grid(row=1, column=0) cancel.grid(row=1, column=2) start_setting_root.mainloop() def start_new_kakuro(self, entry_dimension, start_root, dimension=0): try: if dimension == 0: dimension = int(entry_dimension.get()) except Exception as e: self.throw_exception('Incorrect dimension', 'Dimension is NaN', start_root) return if dimension < 1: self.throw_exception('Incorrect dimension', 'Dimension is less zero', start_root) return if dimension > 10: self.throw_exception('Incorrect dimension', 'Dimension too large', start_root) return self.init_new_kakuro(dimension) self.close_window(start_root) def init_new_kakuro(self, dimension): self.game_field = GameField(dimension, dimension) self.dimension = dimension self.all_img.clear() self.list_button.clear() self.draw_field() self.root.geometry("{0}x{1}".format(dimension * 70, dimension * 70)) self.root.update() def throw_exception(self, title, msg, start_root): messagebox.showerror(title, msg) self.close_window(start_root) def open_from_file(self): open_file_path = filedialog.askopenfilename( title="Select file", defaultextension=".kk", filetypes=(('kk files', '*.kk'), ("all files", "*.*"))) parser = Parser() if len(open_file_path) != 0: try: pairs = parser.parse(open_file_path) except exc.IncorrectFileArgument as e: messagebox.showerror('Incorrect file', e.msg) return except Exception as fe: messagebox.showerror('Incorrect file', 'Unrecognized error in file') return dimension = pairs[0] self.init_new_kakuro(int(dimension)) for cells in pairs[1:]: for key in cells.keys(): self.game_field.init_cell(key[0], key[1], cells[key]) self.redraw() def save(self): path = filedialog.asksaveasfile(mode='w', defaultextension='.png', filetypes=(('png files', '*.png'), ("all files", "*.*"))) if path is not None: painter = Painter(self.size_button) painter.paint(self.game_field.field, path.name, self.dimension)
class CommandLineMode: def __init__(self, dimension): self.game = GameField(dimension, dimension) self.dimansion = dimension self.all_line = [] def add_cell(self, line): frame = line.split('|') if len(frame) != 6: print('Incorrect line') return try: pos_x = self.get_frame(frame[0]) pos_y = self.get_frame(frame[1]) row_sum = self.get_frame(frame[2]) row_length = self.get_frame(frame[3]) column_sum = self.get_frame(frame[4]) column_length = self.get_frame(frame[5]) except Exception as e: print('incorrect line') return cell = Cell(CellType.RULES, row_rule=row_sum, column_rule=column_sum, length_row=row_length, length_column=column_length) self.game.init_cell(pos_x, pos_y, cell) self.all_line.append(line) def get_frame(self, frame): return int(frame.rstrip().lstrip()) def interpret(self, line): if ':' in line: command = line.split(':')[0].lstrip().rstrip() date = line.split(':')[1].lstrip().rstrip() if command == 'add': self.add_cell(date) return if command == 'save_png': self.save_png(date) return if command == 'save_kk': self.save_kk(date) return if line == 'solve': self.solve() print('Incorrect command') def save_png(self, path): if not path.endswith('.png'): path += '.png' pa = Painter(64) pa.paint(self.game.field, path, self.dimansion) def save_kk(self, date): if not date.endswith('kk'): date += '.kk' with open(date, 'w') as f: f.write(self.dimansion + '\n') for line in self.all_line: f.write(line + '\n') def solve(self): solver = Solver(self.game) try: solver.solve() print('Accepted') except Exception as e: print("Can not find solution")
def print_field(field): for x in range(0, len(field)): line = "" for y in range(0, len(field)): if field[x][y].get_type() == CellType.NO_ACTIVE: line += ' # \t' if field[x][y].get_type() == CellType.PLAY: line += ' ' + str(field[x][y].get_value()) + ' \t' if field[x][y].get_type() == CellType.RULES: line += ' ' + str(field[x][y].get_rules()[1]) + '\\' + str( field[x][y].get_rules()[0]) + '\t' print(line) if __name__ == '__main__': game = GameField(4, 4) #print_field(game.field) #print('===================================') game.init_cell(0, 1, Cell(CellType.RULES, column_rule=16, length_column=2)) game.init_cell(0, 2, Cell(CellType.RULES, column_rule=15, length_column=3)) game.init_cell(1, 0, Cell(CellType.RULES, row_rule=17, length_row=2)) game.init_cell(2, 0, Cell(CellType.RULES, row_rule=15, length_row=3)) game.init_cell(3, 1, Cell(CellType.RULES, row_rule=3, length_row=2)) game.init_cell(1, 3, Cell(CellType.RULES, column_rule=4, length_column=2)) print_field(game.field) #solver = Solver(game) #new_field = solver.solve() #print_field(new_field) print(tuple([1, 2, 3]))