def test_fit_top_bottom(self, piece4: Piece, piece9: Piece) -> None: """A piece with one possible matching side fits 8 ways.""" assert str(piece4) == "Red-♦♣♧♢" assert str(piece9) == "Red-♥♠♤♧" expected_orientations = [ (piece9, False, Turn.TURN_270, piece4, False, Turn.TURN_270), (piece9, False, Turn.TURN_270, piece4, True, Turn.TURN_90), (piece4, False, Turn.TURN_90, piece9, False, Turn.TURN_90), (piece4, False, Turn.TURN_90, piece9, True, Turn.TURN_270), (piece9, True, Turn.TURN_90, piece4, False, Turn.TURN_270), (piece9, True, Turn.TURN_90, piece4, True, Turn.TURN_90), (piece4, True, Turn.TURN_270, piece9, False, Turn.TURN_90), (piece4, True, Turn.TURN_270, piece9, True, Turn.TURN_270), ] expected = [ Puzzle(1, 2, (OrientedPiece(p1, f1, t1), OrientedPiece(p2, f2, t2))) for p1, f1, t1, p2, f2, t2 in expected_orientations ] assert sorted(expected) == expected puzzles = solve_puzzle(1, 2, (piece4, piece9)) assert puzzles == set(expected) assert (str(expected[0]) == """\ ┌♠┐ ♥R♤ ├♣┤ ♦R♧ └♢┘\ """)
def test_init_fails_too_many_pieces(self, piece1: Piece, piece2: Piece) -> None: with pytest.raises(ValueError) as err: Puzzle(1, 1, (OrientedPiece(piece1), OrientedPiece(piece2))) assert (str( err.value ) == "2 pieces will not fit in a puzzle of size 1 (width 1, height 1)")
def test_fit_left_right(self, piece4: Piece, piece9: Piece) -> None: """A piece with one possible matching side fits 8 ways.""" assert str(piece4) == "Red-♦♣♧♢" assert str(piece9) == "Red-♥♠♤♧" expected_orientations = [ (piece4, False, Turn.NO_TURN, piece9, False, Turn.NO_TURN), (piece4, False, Turn.NO_TURN, piece9, True, Turn.TURN_180), (piece9, False, Turn.TURN_180, piece4, False, Turn.TURN_180), (piece9, False, Turn.TURN_180, piece4, True, Turn.NO_TURN), (piece9, True, Turn.NO_TURN, piece4, False, Turn.TURN_180), (piece9, True, Turn.NO_TURN, piece4, True, Turn.NO_TURN), (piece4, True, Turn.TURN_180, piece9, False, Turn.NO_TURN), (piece4, True, Turn.TURN_180, piece9, True, Turn.TURN_180), ] expected = [ Puzzle(2, 1, (OrientedPiece(p1, f1, t1), OrientedPiece(p2, f2, t2))) for p1, f1, t1, p2, f2, t2 in expected_orientations ] assert sorted(expected) == expected puzzles = solve_puzzle(2, 1, (piece4, piece9)) assert puzzles == set(expected) assert (str(expected[0]) == """\ ┌♦┬♥┐ ♢R♣R♠ └♧┴♤┘\ """)
def test_init_fails_pieces_do_not_fit(self, piece1: Piece, piece2: Piece) -> None: with pytest.raises(ValueError) as err: Puzzle(2, 1, (OrientedPiece(piece1), OrientedPiece(piece2))) assert str(err.value) == ( "Piece Red-♠♦♡♢ does not fit at col 0, row 0: Edge.EAST is Red-♣♥♤♡" )
def test_init_row_pair(self, piece1: Piece, piece3: Piece) -> None: op1 = OrientedPiece(piece1) op3 = OrientedPiece(piece3) assert str(op1) == "Red-♠♦♡♢" assert str(op3) == "Red-♥♦♢♡" puzzle = Puzzle(2, 1, (op3, op1)) assert (str(puzzle) == """\ ┌♥┬♠┐ ♡R♦R♦ └♢┴♡┘\ """) assert puzzle.is_standard assert puzzle.is_red
def test_fits_left( self, piece1: Piece, piece3: Piece, flip: bool, turn: Turn, str_out: str, fits: bool, ) -> None: """fits_left() returns True when oriented to fit.""" op1 = OrientedPiece(piece1, flip, turn) assert str(op1) == str_out op3 = OrientedPiece(piece3) assert str(op3) == "Red-♥♦♢♡" assert op1.fits_left(op3) is fits
def test_fits_below( self, piece9: Piece, piece1: Piece, flip: bool, turn: Turn, str_out: str, fits: bool, ) -> None: """fits_below() returns True when oriented to fit.""" op9 = OrientedPiece(piece9, flip, turn) assert str(op9) == str_out op1 = OrientedPiece(piece1) assert str(op1) == "Red-♠♦♡♢" assert op9.fits_below(op1) is fits
def test_fits_right( self, piece1: Piece, piece4: Piece, flip: bool, turn: Turn, str_out: str, fits: bool, ) -> None: """fits_right() returns True when oriented to fit.""" op1 = OrientedPiece(piece1, flip, turn) assert str(op1) == str_out op4 = OrientedPiece(piece4) assert str(op4) == "Red-♦♣♧♢" assert op1.fits_right(op4) is fits
def test_default_init(self, piece1: Piece) -> None: """Default is the standard orientation.""" op = OrientedPiece(piece1) assert str(op) == "Red-♠♦♡♢" assert repr(op) == ( "OrientedPiece(Piece(" "Shape.SPADE, Shape.DIAMOND, Shape.HEART, Shape.DIAMOND))") assert op.is_empty is False assert op.is_red is True assert op.is_standard is True assert op.side == Side.RED assert op.north == (Shape.SPADE, End.TAB) assert op.east == (Shape.DIAMOND, End.TAB) assert op.south == (Shape.HEART, End.BLANK) assert op.west == (Shape.DIAMOND, End.BLANK) assert op.north_shape == Shape.SPADE assert op.east_shape == Shape.DIAMOND assert op.south_shape == Shape.HEART assert op.west_shape == Shape.DIAMOND assert op.north_end == End.TAB assert op.east_end == End.TAB assert op.south_end == End.BLANK assert op.west_end == End.BLANK
def test_fits_neighbors(self, piece2: Piece, piece3: Piece, piece4: Piece) -> None: op1 = EmptySpot() neighbors = { Edge.NORTH: OrientedPiece(piece2), Edge.SOUTH: OrientedPiece(piece3), Edge.EAST: OrientedPiece(piece4), Edge.WEST: EmptySpot(), } fits = op1.fits_neighbors(neighbors) assert fits == { Edge.NORTH: True, Edge.SOUTH: True, Edge.EAST: True, Edge.WEST: True, } assert op1.fits_all_neighbors(neighbors)
def test_full_init(self, piece1: Piece) -> None: """A piece can be flipped and turned at init.""" op = OrientedPiece(piece1, flip=True, turn=Turn.TURN_90) assert str(op) == "Black-♦♠♢♡" assert repr(op) == ( "OrientedPiece(" "Piece(Shape.SPADE, Shape.DIAMOND, Shape.HEART, Shape.DIAMOND)," " flip=True, turn=Turn.TURN_90)") assert op.is_empty is False assert op.is_red is False assert op.is_standard is False
def test_turned_init(self, piece1: Piece) -> None: """A piece can be turned at init.""" op = OrientedPiece(piece1, turn=Turn.TURN_90) assert str(op) == "Red-♢♠♦♡" assert repr(op) == ( "OrientedPiece(" "Piece(Shape.SPADE, Shape.DIAMOND, Shape.HEART, Shape.DIAMOND)," " turn=Turn.TURN_90)") assert op.is_empty is False assert op.is_red is True assert op.is_standard is False
def test_init_missing_piece(self, piece3: Piece, piece1: Piece, piece4: Piece) -> None: op3 = OrientedPiece(piece3) op1 = OrientedPiece(piece1) op4 = OrientedPiece(piece4) puzzle = Puzzle(2, 2, (op3, op1, op4)) assert puzzle.width == 2 assert puzzle.height == 2 assert len(puzzle.pieces) == 4 assert puzzle.pieces[:3] == (op3, op1, op4) assert puzzle.pieces[3].is_empty expected = """\ ┌♥┬♠┐ ♡R♦R♦ ├♦┼♡┘ ♢R♣ \n\ └♧┘ """ assert str(puzzle) == expected assert puzzle.is_standard assert puzzle.is_red
def test_get_neighbors(self, piece3: Piece, piece1: Piece, piece4: Piece) -> None: op3 = OrientedPiece(piece3) op1 = OrientedPiece(piece1) op4 = OrientedPiece(piece4) puzzle = Puzzle(2, 2, (op3, op1, op4)) piece = puzzle.get(0, 0) assert piece == op3 neighbors = puzzle.get_neighbors(0, 0) assert neighbors[Edge.NORTH].is_empty assert neighbors[Edge.SOUTH] == op4 assert neighbors[Edge.WEST].is_empty assert neighbors[Edge.EAST] == op1 piece = puzzle.get(1, 1) assert piece.is_empty neighbors = puzzle.get_neighbors(1, 1) assert neighbors[Edge.NORTH] == op1 assert neighbors[Edge.SOUTH].is_empty assert neighbors[Edge.WEST] == op4 assert neighbors[Edge.EAST].is_empty
def test_init_piece(self, piece3: Piece) -> None: op3 = OrientedPiece(piece3) puzzle = Puzzle(1, 1, (op3, )) assert puzzle.width == 1 assert puzzle.height == 1 assert puzzle.pieces == (op3, ) assert (str(puzzle) == """\ ┌♥┐ ♡R♦ └♢┘""") assert repr(puzzle) == f"Puzzle(1, 1, (OrientedPiece({piece3!r}),))" assert puzzle.is_standard assert puzzle.is_red
def test_equality(self, piece1: Piece, piece4: Piece) -> None: """An OrientedPiece is equal when the same piece and orientation.""" clone1 = Piece(piece1.north_shape, piece1.east_shape, piece1.south_shape, piece1.west_shape) assert str(piece1) == "Red-♠♦♡♢" assert str(clone1) == "Red-♠♦♡♢" assert str(piece4) == "Red-♦♣♧♢" assert piece1 != clone1 assert str(piece1) == str(clone1) assert piece1 != piece4 assert OrientedPiece(piece1) == OrientedPiece(piece1) assert OrientedPiece(piece1) != OrientedPiece(clone1) assert OrientedPiece(piece1) != OrientedPiece(piece4) assert OrientedPiece(piece1) != OrientedPiece(piece1, flip=True) assert OrientedPiece(piece1) != OrientedPiece(piece1, turn=Turn.TURN_90) assert OrientedPiece(piece1) != OrientedPiece( piece1, flip=True, turn=Turn.TURN_180) assert OrientedPiece(piece1, flip=True) == OrientedPiece(piece1, flip=True) assert OrientedPiece(piece1, turn=Turn.TURN_90) == OrientedPiece( piece1, turn=Turn.TURN_90) assert OrientedPiece(piece1, flip=True, turn=Turn.TURN_180) == OrientedPiece( piece1, flip=True, turn=Turn.TURN_180)