def _generate_all_turns(board: Board): turns = [] possible_turns = dict() for key in board.cells: if board.cells[key] is not None and board.cells[ key].side == board.turn: board.else_possible_turns(possible_turns, key) for key in board.cells: board_checker = board.cells[key] if board_checker is not None and board_checker.side == board.turn: for i in range(-1, 2, 2): for j in range(-1, 2, 2): direction = BoardCell(i, j) dir_multiplier = 1 current_cell = key.plus( direction.times(dir_multiplier)) while 0 <= current_cell.vertical < board.width and 0 <= current_cell.horizontal < board.height: if board.is_possible_turn(key, current_cell) and\ (not possible_turns or (key in possible_turns and current_cell in possible_turns[key])): turns.append((key, current_cell)) if not board_checker.is_king and dir_multiplier == 2: break dir_multiplier += 1 current_cell = key.plus( direction.times(dir_multiplier)) return turns
class TestBoardCell(unittest.TestCase): first_board_cell = BoardCell(1, 3) second_board_cell = BoardCell(2, 1) first_board_cell_copy = BoardCell(1, 3) def testGetVertical(self): self.assertEqual(1, TestBoardCell.first_board_cell.vertical) def testGetHorizontal(self): self.assertEqual(3, TestBoardCell.first_board_cell.horizontal) def testSetHorizontal(self): test = BoardCell(1, 1) test.horizontal = 2 self.assertEqual(2, test.horizontal) test.__horizontal = "" self.assertEqual(2, test.horizontal) def testPlus(self): self.assertEqual(BoardCell(3, 4), TestBoardCell.first_board_cell.plus(TestBoardCell.second_board_cell)) def testMinus(self): self.assertEqual(BoardCell(-1, 2), TestBoardCell.first_board_cell.minus(TestBoardCell.second_board_cell)) def testTimes(self): self.assertEqual(BoardCell(2, 6), TestBoardCell.first_board_cell.times(2)) def testEqual(self): self.assertFalse(TestBoardCell.first_board_cell.__eq__(TestBoardCell.second_board_cell)) self.assertTrue(TestBoardCell.first_board_cell.__eq__(TestBoardCell.first_board_cell_copy))
def _get_full_cell_between(self, old_cell: BoardCell, turn_cell: BoardCell): if self.cells[old_cell] is not None: dist_min_vertical = min(old_cell.vertical, turn_cell.vertical) dist_min_horizontal = min(old_cell.horizontal, turn_cell.horizontal) dist_max_vertical = max(old_cell.vertical, turn_cell.vertical) dist_max_horizontal = max(old_cell.horizontal, turn_cell.horizontal) dif = turn_cell.minus(old_cell) direction = BoardCell(0, 0) if dif.vertical < 0: direction.vertical = -1 else: direction.vertical = 1 if dif.horizontal < 0: direction.horizontal = -1 else: direction.horizontal = 1 for multiplier in range(1, max(self.height, self.width)): current_cell = old_cell.plus(direction.times(multiplier)) if current_cell.vertical not in range(dist_min_vertical, dist_max_vertical) or \ current_cell.horizontal not in range(dist_min_horizontal, dist_max_horizontal): break if self.cells[current_cell] is not None: return current_cell return None
def is_possible_turn(self, old_cell: BoardCell, turn_cell: BoardCell): if self.cells[turn_cell] is None: difference = turn_cell.minus(old_cell) cell_between = self._get_full_cell_between(old_cell, turn_cell) if self.cells[old_cell].is_king and abs( difference.vertical) == abs(difference.horizontal): if cell_between is None: return True if self.cells[cell_between].side != self.turn: second_cell_between = self._get_full_cell_between( cell_between, turn_cell) if self.cells[ turn_cell] is None and second_cell_between is None: return True else: if abs(difference.vertical) == 2 and abs( difference.horizontal) == 2: if cell_between is not None and self.cells[ cell_between].side == self.turn.opposite(): return True if abs(difference.vertical) == 1: if difference.horizontal == -1 and self.turn == Side.WHITE: return True if difference.horizontal == 1 and self.turn == Side.BLACK: return True return False
def make_turn(self, old_cell: BoardCell, vertical: int, horizontal: int): turn_cell = BoardCell(vertical, horizontal) possible_turns = dict() for key in self.cells: if self.cells[key] is not None and self.cells[ key].side == self.turn: self.else_possible_turns(possible_turns, key) if possible_turns and self.turn_phase == 0: self.turn_phase = 1 if 0 <= vertical < self.width and 0 <= horizontal < self.height and self.cells[old_cell] is not None and \ self.cells[old_cell].side == self.turn: if self.is_possible_turn(old_cell, turn_cell) and \ (self.turn_phase == 0 or (self.turn_phase == 1 and old_cell in possible_turns and turn_cell in possible_turns[old_cell]) or (self.turn_phase == 2 and old_cell == self.last_beat_cell)): self.attr_story.append( (self.turn, self.turn_phase, self.last_beaten_checker, self.last_beat_cell, self.white_checkers, self.white_kings, self.black_checkers, self.black_kings, Checker(self.cells[old_cell].side, self.cells[old_cell].is_king))) cell_between = self._get_full_cell_between(old_cell, turn_cell) self.cells[turn_cell] = self.cells[old_cell] self.cells[old_cell] = None if self.turn == Side.WHITE and horizontal == 0: self.cells[turn_cell].is_king = True self.white_checkers -= 1 self.white_kings += 1 if self.turn == Side.BLACK and horizontal == self.height - 1: self.cells[turn_cell].is_king = True self.black_checkers -= 1 self.black_kings += 1 if cell_between is not None and self.cells[ cell_between] is not None: if self.turn == Side.WHITE: if self.cells[cell_between].is_king: self.black_kings -= 1 else: self.black_checkers -= 1 else: if self.cells[cell_between].is_king: self.white_kings -= 1 else: self.white_checkers -= 1 self.last_beaten_checker = self.cells[cell_between] self.cells[cell_between] = None possible_turns = dict() self.else_possible_turns(possible_turns, turn_cell) if possible_turns: self.turn_phase = 2 self.last_beat_cell = turn_cell return turn_cell, cell_between else: self.turn_phase = 0 self.turn = self.turn.opposite() return turn_cell, cell_between return None
def fill_board(self): self.cells.clear() self.attr_story.clear() self.white_checkers = 0 self.black_checkers = 0 self.turn = Side.WHITE self.turn_phase = 0 self.last_beat_cell = None for vertical in range(self.width): for horizontal in range(self.height): if (vertical + horizontal) % 2 != 0: if horizontal < 3: self.cells[BoardCell(vertical, horizontal)] = Checker( Side.BLACK, False) self.black_checkers += 1 elif horizontal > 4: self.cells[BoardCell(vertical, horizontal)] = Checker( Side.WHITE, False) self.white_checkers += 1 if BoardCell(vertical, horizontal) not in self.cells: self.cells[BoardCell(vertical, horizontal)] = None
def else_possible_turns(self, possible_turns: dict, cell: BoardCell): for i in range(-1, 2, 2): for j in range(-1, 2, 2): direction = BoardCell(i, j) dir_multiplier = 2 current_cell = cell.plus(direction.times(dir_multiplier)) while 0 <= current_cell.vertical < self.width and 0 <= current_cell.horizontal < self.height: if self.is_possible_turn(cell, current_cell) and \ self._get_full_cell_between(cell, current_cell) is not None: if cell not in possible_turns: possible_turns[cell] = list() possible_turns[cell].append(current_cell) if not self.cells[cell].is_king: break dir_multiplier += 1 current_cell = cell.plus(direction.times(dir_multiplier))
def testMakeTurn(self): TestBoard.test_board.fill_board() self.assertEqual(None, TestBoard.test_board.make_turn(BoardCell(0, 5), 0, 3)) self.assertEqual((BoardCell(1, 4), None), TestBoard.test_board.make_turn(BoardCell(0, 5), 1, 4)) self.assertEqual((BoardCell(2, 3), None), TestBoard.test_board.make_turn(BoardCell(3, 2), 2, 3)) self.assertEqual((BoardCell(3, 2), BoardCell(2, 3)), TestBoard.test_board.make_turn(BoardCell(1, 4), 3, 2)) self.assertEqual((BoardCell(2, 3), BoardCell(3, 2)), TestBoard.test_board.make_turn(BoardCell(4, 1), 2, 3)) self.assertEqual((BoardCell(1, 4), None), TestBoard.test_board.make_turn(BoardCell(2, 5), 1, 4)) self.assertEqual(None, TestBoard.test_board.make_turn(BoardCell(5, 0), 4, 1)) self.assertEqual((BoardCell(0, 5), BoardCell(1, 4)), TestBoard.test_board.make_turn(BoardCell(2, 3), 0, 5)) self.assertEqual((BoardCell(5, 4), None), TestBoard.test_board.make_turn(BoardCell(6, 5), 5, 4)) self.assertEqual((BoardCell(4, 1), None), TestBoard.test_board.make_turn(BoardCell(5, 0), 4, 1)) self.assertEqual((BoardCell(6, 5), None), TestBoard.test_board.make_turn(BoardCell(7, 6), 6, 5)) self.assertEqual((BoardCell(4, 3), None), TestBoard.test_board.make_turn(BoardCell(5, 2), 4, 3)) self.assertEqual((BoardCell(3, 2), BoardCell(4, 3)), TestBoard.test_board.make_turn(BoardCell(5, 4), 3, 2)) self.assertEqual((BoardCell(5, 0), BoardCell(4, 1)), TestBoard.test_board.make_turn(BoardCell(3, 2), 5, 0)) self.assertEqual(True, TestBoard.test_board.cells[BoardCell(5, 0)].is_king) self.assertEqual((BoardCell(3, 2), None), TestBoard.test_board.make_turn(BoardCell(2, 1), 3, 2)) self.assertEqual(None, TestBoard.test_board.make_turn(BoardCell(2, 1), 3, 2)) self.assertEqual((BoardCell(1, 4), BoardCell(3, 2)), TestBoard.test_board.make_turn(BoardCell(5, 0), 1, 4)) self.assertEqual((BoardCell(2, 3), BoardCell(1, 4)), TestBoard.test_board.make_turn(BoardCell(0, 5), 2, 3)) self.assertEqual((BoardCell(5, 4), None), TestBoard.test_board.make_turn(BoardCell(6, 5), 5, 4)) self.assertEqual((BoardCell(5, 2), None), TestBoard.test_board.make_turn(BoardCell(6, 1), 5, 2)) self.assertEqual((BoardCell(2, 5), None), TestBoard.test_board.make_turn(BoardCell(3, 6), 2, 5)) self.assertEqual((BoardCell(2, 1), None), TestBoard.test_board.make_turn(BoardCell(3, 0), 2, 1)) self.assertEqual((BoardCell(3, 6), None), TestBoard.test_board.make_turn(BoardCell(4, 7), 3, 6)) self.assertEqual((BoardCell(3, 2), None), TestBoard.test_board.make_turn(BoardCell(2, 1), 3, 2)) self.assertEqual((BoardCell(7, 6), None), TestBoard.test_board.make_turn(BoardCell(6, 7), 7, 6)) self.assertEqual((BoardCell(4, 3), None), TestBoard.test_board.make_turn(BoardCell(5, 2), 4, 3)) self.assertEqual((BoardCell(0, 5), None), TestBoard.test_board.make_turn(BoardCell(1, 6), 0, 5)) self.assertEqual((BoardCell(6, 5), BoardCell(5, 4)), TestBoard.test_board.make_turn(BoardCell(4, 3), 6, 5)) self.assertEqual((BoardCell(4, 7), BoardCell(5, 6)), TestBoard.test_board.make_turn(BoardCell(6, 5), 4, 7)) self.assertEqual(True, TestBoard.test_board.turn_phase == 0)
def testTimes(self): self.assertEqual(BoardCell(2, 6), TestBoardCell.first_board_cell.times(2))
def testMinus(self): self.assertEqual(BoardCell(-1, 2), TestBoardCell.first_board_cell.minus(TestBoardCell.second_board_cell))
def testPlus(self): self.assertEqual(BoardCell(3, 4), TestBoardCell.first_board_cell.plus(TestBoardCell.second_board_cell))
def testSetHorizontal(self): test = BoardCell(1, 1) test.horizontal = 2 self.assertEqual(2, test.horizontal) test.__horizontal = "" self.assertEqual(2, test.horizontal)
def setup_ui(self, MainWindow): global in_progress global choose_cell_phase MainWindow.setObjectName("Draughts") MainWindow.resize(800, 600) MainWindow.setMinimumSize(QtCore.QSize(800, 600)) MainWindow.setMaximumSize(QtCore.QSize(800, 600)) MainWindow.setStyleSheet("") self.centralwidget = QtWidgets.QWidget(MainWindow) self.frame = QtWidgets.QFrame(self.centralwidget) self.frame.setGeometry(QtCore.QRect(0, 0, 181, 601)) self.frame.setStyleSheet("QFrame {\n" "border-color:black;\n" "border-style:solid;\n" "border-width:5px;\n" "background-color:#FFFACD;\n" "}\n" "\n" "QPushButton {\n" "border-color:black;\n" "border-style:solid;\n" "background-color: #dcb35c;\n" "border-radius: 40px;\n" "border-width:3px;\n" "}\n" "\n" "QPushButton:hover {\n" "background-color: #ECE7BC;\n" "}\n" "\n" "QLabel{\n" "border-color:black;\n" "border-style:solid;\n" "border-width:5 5 5 5;\n" "}") self.label = QtWidgets.QLabel(self.frame) self.label.setGeometry(QtCore.QRect(0, 0, 181, 111)) font = QtGui.QFont() font.setFamily("Verdana") font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label.setFont(font) self.label.setTextFormat(QtCore.Qt.PlainText) self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setWordWrap(True) self.restart = QtWidgets.QPushButton(self.frame) self.restart.setGeometry(QtCore.QRect(20, 160, 141, 81)) font = QtGui.QFont() font.setFamily("Verdana") font.setPointSize(12) font.setBold(True) font.setWeight(75) self.restart.setFont(font) self.restart.setObjectName("restart") self.restart.pressed.connect(lambda: self.restart_pressed()) self.widget = QtWidgets.QWidget(self.centralwidget) self.widget.setGeometry(QtCore.QRect(180, 0, 621, 601)) self.gridLayout = QtWidgets.QGridLayout(self.widget) self.gridLayout.setContentsMargins(0, 0, 0, 0) self.gridLayout.setSpacing(0) for vertical, horizontal in itertools.product(range(board.width), range(board.height)): board_cell = BoardCell(vertical, horizontal) groupBox = QGroupBoxClickable(self.widget) image_label = QtWidgets.QLabel(groupBox) image_label.setGeometry(QtCore.QRect(0, 0, 80, 80)) if (vertical + horizontal) % 2 == 0: image_label.setStyleSheet("background-color:#fdeda8;") else: image_label.setStyleSheet("background-color:#ba7b55;") event = functools.partial(self.group_clicked, board_cell) groupBox.clicked.connect(event) buttons[board_cell] = groupBox self.gridLayout.addWidget(groupBox, horizontal, vertical, 1, 1) self.dialog = UnclosableDialog(self.centralwidget) self.dialog.resize(400, 257) self.dialog.setMinimumSize(QtCore.QSize(400, 257)) self.dialog.setMaximumSize(QtCore.QSize(400, 257)) self.dialog.setModal(True) self.dialog.setWindowFlag(Qt.FramelessWindowHint) self.dialog.setStyleSheet("QPushButton {\n" "border-color:black;\n" "border-style:solid;\n" "background-color: #dcb35c;\n" "border-radius: 25px;\n" "border-width:3px;\n" "}\n" "QPushButton:hover {\n" "background-color: #ECE7BC;\n" "}\n" "QDialog {\n" "border-color:black;\n" "border-style:solid;\n" "border-width:5px;\n" "background-color:#FFFACD;\n" "}\n" "QFrame {\n" "border-color:black;\n" "border-style:solid;\n" "border-width:3px;\n" "}\n" "") self.frame = QtWidgets.QFrame(self.dialog) self.frame.setGeometry(QtCore.QRect(60, 80, 120, 80)) self.frame.setStyleSheet("background-color: #dcb35c;\n" "border-width:3px;") self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame.setFrameShadow(QtWidgets.QFrame.Raised) self.first_player_human = QtWidgets.QRadioButton(self.frame) self.first_player_human.setGeometry(QtCore.QRect(20, 20, 82, 17)) self.first_player_human.setStyleSheet("border-width:0px;") self.first_player_human.setChecked(True) self.first_player_computer = QtWidgets.QRadioButton(self.frame) self.first_player_computer.setGeometry(QtCore.QRect(20, 50, 82, 17)) self.first_player_computer.setStyleSheet("border-width:0px;") self.frame_2 = QtWidgets.QFrame(self.dialog) self.frame_2.setGeometry(QtCore.QRect(220, 80, 120, 80)) self.frame_2.setStyleSheet("background-color: #dcb35c;\n" "border-width:3px;") self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) self.second_player_human = QtWidgets.QRadioButton(self.frame_2) self.second_player_human.setGeometry(QtCore.QRect(20, 20, 82, 17)) self.second_player_human.setStyleSheet("border-width:0px;") self.second_player_human.setChecked(True) self.second_player_computer = QtWidgets.QRadioButton(self.frame_2) self.second_player_computer.setGeometry(QtCore.QRect(20, 50, 82, 17)) self.second_player_computer.setStyleSheet("border-width:0px;") self.push_button = QtWidgets.QPushButton(self.dialog) self.push_button.setGeometry(QtCore.QRect(140, 180, 121, 51)) self.push_button.pressed.connect(lambda: self.dialog_pressed()) self.dialog_first = QtWidgets.QLabel(self.dialog) self.dialog_first.setGeometry(QtCore.QRect(70, 50, 101, 21)) self.dialog_first.setStyleSheet("font: 75 12pt \"Verdana\";\n" "border-width:0px;") self.dialog_second = QtWidgets.QLabel(self.dialog) self.dialog_second.setGeometry(QtCore.QRect(220, 50, 121, 21)) self.dialog_second.setStyleSheet("font: 75 12pt \"Verdana\";\n" "border-width:0px;") self.dialog.show() self.timer = QTimer() in_progress = True MainWindow.setCentralWidget(self.centralwidget) self.retranslate_ui(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow)