def test_simple_movement_execution(self): board = Board() piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.south) board.get_tile(1, 2).place_piece(piece_two) assert board.execute_board_movements(PLAYER_1_ID) == 1 assert board.get_tile(1, 1).piece == piece_two
def execute_piece_movement(self, piece: Piece) -> int: target_x, target_y = piece.get_target_coordinates() target_tile = self.get_tile(target_x, target_y) if target_tile.piece is None: self.commit_piece_movement(piece, piece.tile, target_tile) return 1 elif piece.is_pusher(): push_movements = self.get_chained_push_movements(piece.tile, target_tile) for push_source_tile, push_target_tile in reversed(push_movements): if push_target_tile is None: push_source_tile.piece.remove_from_play() push_source_tile.remove_piece() else: self.commit_piece_movement(push_source_tile.piece, push_source_tile, push_target_tile) return len(push_movements) elif target_tile.piece.is_pushable() and not piece.is_pushable(): dx, dy = piece.get_movement_offsets() push_target_tile = self.get_tile(x=target_tile.x + dx, y=target_tile.y + dy) if push_target_tile is None or push_target_tile.piece is None: self.commit_piece_movement(target_tile.piece, target_tile, push_target_tile) self.commit_piece_movement(piece, piece.tile, target_tile) return 2 else: self.remove_piece_stuck_in_perimeter(piece.tile, piece) else: self.remove_piece_stuck_in_perimeter(piece.tile, piece) return 0
def test_board_serialization(self): board = Board() assert board.to_string_notation() == EMPTY_BOARD_SERIALIZATION piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.east) board.get_tile(1, 1).place_piece(piece_two) assert board.get_tile(1, 1).to_string_notation() == "2|1|east" assert board.to_string_notation() == ",,,,2|1|east,,,,,,,,,,,,,,,,"
def __init__(self, row, column): super().__init__() self.__row = row self.__column = column self.__board = [[ Piece(Cell.VALUE, y * column + x + 1) for x in range(column) ] for y in range(row)] self.__board[-1][-1] = Piece(Cell.BLANK, 0) self.__pos_blank = (row - 1, column - 1)
def test_get_chained_push_movements_edge(self): board = Board() board.get_tile(3, 3).place_piece(Piece(PLAYER_1_ID, PieceType.four)) board.get_tile(3, 4).place_piece(Piece(PLAYER_1_ID, PieceType.one)) movements = board.get_chained_push_movements(board.get_tile(3, 3), board.get_tile(3, 4)) assert movements == [ (Tile(3, 3), Tile(3, 4)), (Tile(3, 4), None), ]
def test_board_pieces(self): board = Board() assert board.get_board_pieces() == [] board.get_tile(0, 1).place_piece(Piece(PLAYER_1_ID, PieceType.four)) board.get_tile(2, 2).place_piece(Piece(PLAYER_1_ID, PieceType.two)) board.get_tile(3, 3).place_piece(Piece(PLAYER_1_ID, PieceType.one)) assert len(board.get_board_pieces()) == 3 assert len(board.get_board_pieces(exclude_perimeter=True)) == 2
def test_move_to_perimeter(self): board = Board() piece_four = Piece(PLAYER_1_ID, PieceType.four) piece_four.set_movement_direction(Direction.south) board.get_tile(2, 1).place_piece(piece_four) assert board.execute_board_movements(PLAYER_1_ID) == 1 assert piece_four.tile is None assert board.get_tile(2, 1).piece is None assert board.get_tile(2, 0).piece is None
def test_central_row_win_condition(self): board = Board() board.get_tile(2, 1).place_piece(Piece(PLAYER_1_ID, PieceType.two)) board.get_tile(2, 2).place_piece(Piece(PLAYER_1_ID, PieceType.one)) board.get_tile(2, 3).place_piece(Piece(PLAYER_1_ID, PieceType.five)) # Random pieces board.get_tile(3, 3).place_piece(Piece(PLAYER_2_ID, PieceType.four)) board.get_tile(1, 1).place_piece(Piece(PLAYER_2_ID, PieceType.five)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is GameResult.win
def test_get_chained_push_movements(self): board = Board() board.get_tile(0, 3).place_piece(Piece(PLAYER_1_ID, PieceType.four)) board.get_tile(1, 3).place_piece(Piece(PLAYER_1_ID, PieceType.two)) board.get_tile(2, 3).place_piece(Piece(PLAYER_2_ID, PieceType.three)) board.get_tile(4, 3).place_piece(Piece(PLAYER_2_ID, PieceType.one)) movements = board.get_chained_push_movements(board.get_tile(0, 3), board.get_tile(1, 3)) assert len(movements) == 3 assert movements == [ (Tile(0, 3), Tile(1, 3)), (Tile(1, 3), Tile(2, 3)), (Tile(2, 3), Tile(3, 3)), ]
def __init__(self, userDisc): Player.__player += 1 self.__userDisc = userDisc self.__name = userDisc.name if Player.__player > 2: Player.__player = 1 self.__piece = Piece(self.__player)
def place_piece(self, piece: Piece): if self.piece is not None: raise ValueError( f"Tried placing {piece!r} on {self!r}, with an existing piece on it ({self.piece!r})" ) self.piece = piece piece.tile = self
def test_get_chained_push_movements_empty(self): board = Board() board.get_tile(1, 3).place_piece(Piece(PLAYER_1_ID, PieceType.four)) movements = board.get_chained_push_movements(board.get_tile(1, 3), board.get_tile(1, 2)) assert movements == [ (Tile(1, 3), Tile(1, 2)), ]
def draw_piece(self, piece: Piece, x, y): pygame.draw.circle(self.screen, PLAYER_COLOR[piece.owner_id], (x + DX / 2, y + DY / 2), DX * 0.3) dir_x, dir_y = piece.get_movement_offsets() pygame.draw.polygon(self.screen, PLAYER_COLOR[piece.owner_id], points=self.get_poli_points( x, y, DX, DY, dir_x, dir_y)) self.screen.blit(self.piece_type_image[piece.type], (x + DX / 2.5, y + DY / 3))
def test_perimeter_exclusion_from_win_conditions(self): board = Board() board.get_tile(0, 1).place_piece(Piece(PLAYER_1_ID, PieceType.four)) board.get_tile(0, 2).place_piece(Piece(PLAYER_1_ID, PieceType.two)) board.get_tile(0, 3).place_piece(Piece(PLAYER_1_ID, PieceType.one)) board.get_tile(2, 1).place_piece(Piece(PLAYER_1_ID, PieceType.four)) board.get_tile(3, 1).place_piece(Piece(PLAYER_1_ID, PieceType.two)) board.get_tile(4, 1).place_piece(Piece(PLAYER_1_ID, PieceType.one)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None
def test_draw_by_multiple_wins(self): board = Board() board.get_tile(1, 2).place_piece(Piece(PLAYER_1_ID, PieceType.one)) board.get_tile(2, 2).place_piece(Piece(PLAYER_1_ID, PieceType.two)) board.get_tile(3, 2).place_piece(Piece(PLAYER_1_ID, PieceType.three)) board.get_tile(1, 1).place_piece(Piece(PLAYER_2_ID, PieceType.one)) board.get_tile(2, 1).place_piece(Piece(PLAYER_2_ID, PieceType.two)) board.get_tile(3, 1).place_piece(Piece(PLAYER_2_ID, PieceType.three)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None
def test_win_conditions(self): board = Board() board.get_tile(1, 1).place_piece(Piece(PLAYER_1_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(1, 2).place_piece(Piece(PLAYER_1_ID, PieceType.four)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(2, 2).place_piece(Piece(PLAYER_1_ID, PieceType.five)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(1, 3).place_piece(Piece(PLAYER_1_ID, PieceType.three)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is GameResult.win assert board.get_game_result(PLAYER_2_ID, PLAYER_1_ID) is GameResult.loss board.get_tile(3, 1).place_piece(Piece(PLAYER_2_ID, PieceType.three)) board.get_tile(3, 2).place_piece(Piece(PLAYER_2_ID, PieceType.three)) board.get_tile(3, 3).place_piece(Piece(PLAYER_2_ID, PieceType.three)) assert board.get_game_result(PLAYER_2_ID, PLAYER_1_ID) is None
def test_diagonal_win_conditions(self): board = Board() board.get_tile(1, 1).place_piece(Piece(PLAYER_1_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(2, 2).place_piece(Piece(PLAYER_1_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(3, 3).place_piece(Piece(PLAYER_1_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is GameResult.win board.get_tile(2, 2).remove_piece() board.get_tile(1, 3).place_piece(Piece(PLAYER_2_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(2, 2).place_piece(Piece(PLAYER_2_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is None board.get_tile(3, 1).place_piece(Piece(PLAYER_2_ID, PieceType.two)) assert board.get_game_result(PLAYER_1_ID, PLAYER_2_ID) is GameResult.loss
def piece_at(self, square: Square) -> Optional[Piece]: """Optionally returns the piece occupying the given square.""" mask = BB_SQUARES[square] if not self.occupied & mask: return None for colour in [WHITE, BLACK]: if self.pawns[colour] & mask: return Piece(PAWN, colour) elif self.rooks[colour] & mask: return Piece(ROOK, colour) elif self.knights[colour] & mask: return Piece(KNIGHT, colour) elif self.bishops[colour] & mask: return Piece(BISHOP, colour) elif self.queens[colour] & mask: return Piece(QUEEN, colour) elif self.kings[colour] & mask: return Piece(KING, colour)
def test_win_condition_board_evaluation(self): board = Board() piece_one = Piece(PLAYER_1_ID, PieceType.one) piece_one.set_movement_direction(Direction.north) board.get_tile(1, 1).place_piece(piece_one) piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.north) board.get_tile(2, 2).place_piece(piece_two) piece_three = Piece(PLAYER_1_ID, PieceType.three) piece_three.set_movement_direction(Direction.south) board.get_tile(3, 3).place_piece(piece_three) assert evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) == WIN_CONDITION_SCORE assert evaluate_board(board, PLAYER_2_ID, PLAYER_1_ID) == -WIN_CONDITION_SCORE
def test_positions(self): p1 = Piece(0, 0) p2 = Piece(2, 2) self.assertEqual(p1.get_position(), (0, 0)) self.assertEqual(p2.get_position(), (2, 2))
def test_state(self): p1 = Piece(0, 0) p1.set_black() self.assertEqual(p1.get_state(), BLACK) p2 = Piece(1, 1) p2.set_white() self.assertEqual(p2.get_state(), WHITE) p3 = Piece(3, 3) p3.set_move() self.assertEqual(p3.get_state(), MOVE) p1.flip() self.assertEqual(p1.get_state(), WHITE) self.assertEqual(p1.is_flipped(), True) p4 = Piece(4,4) p4.set_board() self.assertEqual(p4.get_state(), BOARD)
def test_one_not_pushable_if_piece_behind(self): board = Board() five = Piece(PLAYER_1_ID, PieceType.five) five.set_movement_direction(Direction.south) board.get_tile(2, 2).place_piece(five) one = Piece(PLAYER_1_ID, PieceType.one) one.set_movement_direction(Direction.north) board.get_tile(1, 1).place_piece(one) enemy_two = Piece(PLAYER_2_ID, PieceType.two) enemy_two.set_movement_direction(Direction.east) board.get_tile(0, 2).place_piece(enemy_two) board.execute_board_movements(PLAYER_2_ID) assert board.get_tile(2, 1).piece == five assert board.get_tile(1, 2).piece == one assert board.get_tile(0, 2).piece is None
def test_piece_board_evaluation(self): board = Board() piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.west) board.get_tile(2, 2).place_piece(piece_two) piece_two_score = PLACED_PIECE_SCORE[ PieceType.two] * TILE_SCORE_MULTIPLIER[2][2][Direction.west] assert evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) == piece_two_score piece_two_enemy = Piece(PLAYER_2_ID, PieceType.two) piece_two_enemy.set_movement_direction(Direction.east) board.get_tile(2, 1).place_piece(piece_two_enemy) enemy_two_score = PLACED_PIECE_SCORE[ PieceType.two] * TILE_SCORE_MULTIPLIER[2][1][Direction.east] assert evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) == piece_two_score - enemy_two_score piece_three = Piece(PLAYER_2_ID, PieceType.three) piece_three.set_movement_direction(Direction.south) board.get_tile(1, 1).place_piece(piece_three) enemy_three_score = PLACED_PIECE_SCORE[ PieceType.three] * TILE_SCORE_MULTIPLIER[1][1][Direction.south] assert evaluate_board( board, PLAYER_1_ID, PLAYER_2_ID ) == piece_two_score - enemy_two_score - enemy_three_score
def test_piece_equality(self): assert Piece(PLAYER_1_ID, PieceType.two) == Piece(PLAYER_1_ID, PieceType.two) assert Piece(PLAYER_1_ID, PieceType.two) != Piece(PLAYER_2_ID, PieceType.two) assert Piece(PLAYER_1_ID, PieceType.two) != Piece(PLAYER_1_ID, PieceType.four)
def test_piece_about_to_exit(self): board = Board() center_piece = Piece(PLAYER_1_ID, PieceType.two) center_piece.set_movement_direction(Direction.east) board.get_tile(2, 2).place_piece(center_piece) assert center_piece.is_exiting_board() is False top_piece = Piece(PLAYER_1_ID, PieceType.two) top_piece.set_movement_direction(Direction.north) board.get_tile(2, 3).place_piece(top_piece) assert top_piece.is_exiting_board() is True top_piece.set_movement_direction(Direction.west) assert top_piece.is_exiting_board() is False east_piece = Piece(PLAYER_1_ID, PieceType.two) east_piece.set_movement_direction(Direction.east) board.get_tile(3, 1).place_piece(east_piece) assert east_piece.is_exiting_board() is True east_piece.set_movement_direction(Direction.west) assert east_piece.is_exiting_board() is False
def test_piece_value_relationships(self): # We want to test that pieces in squares where they are more valuable # are valued better than if placed somewhere else # board = Board() piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.north) board.get_tile(1, 1).place_piece(piece_two) just_entered_score = evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) board.get_tile(1, 1).remove_piece() piece_two.set_movement_direction(Direction.south) board.get_tile(3, 3).place_piece(piece_two) assert evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) == just_entered_score board.get_tile(3, 3).remove_piece() board.get_tile(2, 2).place_piece(piece_two) center_square_score = evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) board.get_tile(2, 2).remove_piece() piece_two.set_movement_direction(Direction.east) board.get_tile(3, 3).place_piece(piece_two) about_to_exit_score = evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) board.get_tile(3, 3).remove_piece() piece_two.set_movement_direction(Direction.west) board.get_tile(2, 3).place_piece(piece_two) neutral_score = evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) board.get_tile(2, 3).remove_piece() piece_two.set_movement_direction(Direction.south) board.get_tile(3, 2).place_piece(piece_two) assert evaluate_board(board, PLAYER_1_ID, PLAYER_2_ID) == neutral_score assert center_square_score > neutral_score assert just_entered_score > neutral_score assert neutral_score > about_to_exit_score
def test_state(self): p1 = Piece(0, 0) p1.set_black() self.assertEqual(p1.get_state(), BLACK) p2 = Piece(1, 1) p2.set_white() self.assertEqual(p2.get_state(), WHITE) p3 = Piece(3, 3) p3.set_move() self.assertEqual(p3.get_state(), MOVE) p1.flip() self.assertEqual(p1.get_state(), WHITE) self.assertEqual(p1.is_flipped(), True) p4 = Piece(4, 4) p4.set_board() self.assertEqual(p4.get_state(), BOARD)
def __init__(self, colour): self.width = WIDTH self.height = HEIGHT self.pieces = list((Piece(x, y, colour) for y in range(0, self.height) for x in range(0, self.width)))
def test_push_movements_execution(self): board = Board() piece_four = Piece(PLAYER_1_ID, PieceType.four) piece_four.set_movement_direction(Direction.north) board.get_tile(2, 1).place_piece(piece_four) piece_three = Piece(PLAYER_1_ID, PieceType.three) piece_three.set_movement_direction(Direction.east) board.get_tile(1, 2).place_piece(piece_three) piece_three_2 = Piece(PLAYER_2_ID, PieceType.three) piece_three_2.set_movement_direction(Direction.west) board.get_tile(2, 2).place_piece(piece_three_2) piece_five = Piece(PLAYER_2_ID, PieceType.five) piece_five.set_movement_direction(Direction.east) board.get_tile(2, 3).place_piece(piece_five) piece_two = Piece(PLAYER_1_ID, PieceType.two) piece_two.set_movement_direction(Direction.south) board.get_tile(3, 3).place_piece(piece_two) piece_one = Piece(PLAYER_2_ID, PieceType.one) piece_one.set_movement_direction(Direction.west) board.get_tile(3, 2).place_piece(piece_one) assert board.execute_board_movements(PLAYER_1_ID) == 5 assert board.get_tile(1, 1).piece is None assert board.get_tile(2, 1).piece is None assert board.get_tile(3, 1).piece == piece_one assert board.get_tile(1, 2).piece == piece_three assert board.get_tile(2, 2).piece == piece_four assert board.get_tile(3, 2).piece == piece_two assert board.get_tile(1, 3).piece is None assert board.get_tile(2, 3).piece == piece_three_2 assert board.get_tile(3, 3).piece is None assert piece_five.tile is None
def test_pieces_movement_order(self): board = Board() board.get_tile(1, 1).place_piece(Piece(PLAYER_1_ID, PieceType.two)) assert board.get_movement_ordered_pieces(PLAYER_1_ID) == [ Piece(PLAYER_1_ID, PieceType.two) ] board.get_tile(1, 2).place_piece(Piece(PLAYER_2_ID, PieceType.one)) board.get_tile(1, 3).place_piece(Piece(PLAYER_2_ID, PieceType.two)) board.get_tile(2, 1).place_piece(Piece(PLAYER_1_ID, PieceType.four)) assert board.get_movement_ordered_pieces(PLAYER_1_ID) == [ Piece(PLAYER_2_ID, PieceType.one), Piece(PLAYER_1_ID, PieceType.two), Piece(PLAYER_2_ID, PieceType.two), Piece(PLAYER_1_ID, PieceType.four) ] assert board.get_movement_ordered_pieces(PLAYER_2_ID) == [ Piece(PLAYER_2_ID, PieceType.one), Piece(PLAYER_2_ID, PieceType.two), Piece(PLAYER_1_ID, PieceType.two), Piece(PLAYER_1_ID, PieceType.four) ]
def __swap_cell(self, left, right): temp = Piece(self.get_cell(left).id, self.get_cell(left).value) self.__set_cell(left, self.get_cell(right)) self.__set_cell(right, temp)