示例#1
0
 def to_fumen(self):
     """Output setup + continuations in one fumen."""
     if len(self.continuations) > 0:
         frames = [fumen.decode(self.solution.fumen)]
         for cont in self.continuations:
             field, _ = fumen.decode(cont.solution.fumen)
             comment = "%.2f%%" % cont.PC_rate if cont.PC_rate > 0 else ""
             frames.append((field, comment))
         #print(frames)
         return fumen.encode(frames)
     else:
         return self.solution.fumen
示例#2
0
def fields():
    """Return a list of fields to be tested by unit tests."""
    test_fumens = [
        "v115@AhBtDewhQ4ywBti0whR4wwRpilg0whAeQ4AeRpglCe?whJeAgl",  #albatross
        "v115@hghlQ4BeAtEeglR4BtAewhh0AeglA8Q4AtRpwhg0Be?D8Rpwhg0CeE8whB8AeI8AeG8JeAgH",  #DT-cannon bag2
        "v115@AhBtDewhQ4CeBti0whR4AeRpilg0whAeQ4AeRpglCe?whJeAgl",  #albatross without T
    ]
    return [fumen.decode(test_fumen)[0] for test_fumen in test_fumens]
示例#3
0
def get_solutions(fm):
    """Attempt to retrieve solutions from cache."""
    fname = get_cache_file(fm)
    cache_file = Path(working_dir / fname)
    if cache_file.exists():
        with cache_file.open() as f:
            sols = f.read().splitlines()
        # move to backup of old caches
        cache_file.rename(backup_dir / fname)
        solutions = []
        for sol in sols:
            field, seq = fumen.decode(sol)
            solutions.append(TetSolution(TetField(from_list=field), sol, seq))
        return solutions
    else:
        return None
示例#4
0
def fumen_to_image(fumen_data, height, blocks):
    """Convert fumen encoded field to base64 encoded PNG image (for embedding in output.html).

    height can be used to expand the field to a certain height with blank rows, should not be less than field height.
    blocks is a numpy array of block images in PNG format.
    """
    field, _ = fumen.decode(fumen_data)
    field_height = len(field)
    if (height > field_height):
        field.extend([[0] * 10 for _ in range(height - field_height)])
    # fumen.decode returns blocks in reverse order
    # could potentially speed things up even more by going straight from fumen to the proper format for this
    # and have a separate function to turn fumen output to a TetField
    field.reverse()
    img_data = numpy.vstack(
        tuple(numpy.hstack(tuple(blocks[i] for i in row)) for row in field))
    # for some reason optimize is giving me larger filesizes
    # imageio.imwrite("test.png", img_data, format="PNG", optimize=True
    png_data = imageio.imwrite(imageio.RETURN_BYTES, img_data, format="PNG")
    data_url = "data:image/png;base64," + base64.b64encode(png_data).decode()
    return data_url
示例#5
0
def main():
    #albatross without T piece
    test_field, _ = fumen.decode(
        "v115@AhBtDewhQ4CeBti0whR4AeRpilg0whAeQ4AeRpglCe?whJeAgl")
    print(is_bag_possible(test_field, "SOLIZJ"))
示例#6
0
def test_is_harddrop_possible():
    """ Unit tests for is_harddrop_possible.
    successes:
        for each placement, dropping onto blank ground in every position possible for that piece
        dropping onto ground raised a certain amount
        ground where only one point of piece makes contact:
            v115@CgywHewwA8ZeQ4BeQ4FeR4AeR4AezhA8Q4BeQ4DeA8?DeA8ieAgl
        dropping inbetween narrow gap:
        v115@1gB8CeA8AeA8BeB8CeA8whA8Q4AeB8CeA8whA8R4B8?AewwAeA8whA8AeQ4B8ywA8whA8JeAgl
    fails:
        piece out of bounds
        part of piece occupied
        floating pieces (test if bottom block in column makes contact for each column)
         (note: this wouldnt work with more complex shapes, but should work with every mino?)
        gap too narrow, or overhang above (for later: argument for height harddropped from)
    """
    # attempt to place every piece/rotation in every possible spot on a blank field
    # should succeed for all in-bounds pieces, should fail for out-of-bounds
    blank_field = [[0] * 10 for __ in range(20)]
    for piece in "ILOZTJS":
        for rot in range(4):
            for y in range(-2, 0):
                for x in range(-2, 10):
                    result = setupfinder.analysis.is_harddrop_possible(
                        piece, (x, y, rot), blank_field)
                    if x in list(
                            setupfinder.analysis.VALID_X_PLACEMENTS[piece]
                        [rot]) and y == setupfinder.analysis.MIN_Y_PLACEMENT[
                            piece][rot]:
                        assert result == True
                    else:
                        assert result == False

    # test piece hanging off a single point, also hanging from the middle row of the piece
    # one floating dot at 5,2
    test_field, __ = fumen.decode("v115@MhA8heAgH")
    for __ in range(20 - len(test_field)):
        test_field.append([0] * 10)
    supported_placements = [("I", (2, 2, 0)), ("I", (3, 3, 1)),
                            ("L", (3, 2, 0))]
    floating_placements = [("I", (1, 2, 0)), ("I", (2, 3, 1)),
                           ("L", (3, 3, 0))]
    for piece, placement in supported_placements:
        assert setupfinder.analysis.is_harddrop_possible(
            piece, placement, test_field) == True
    for piece, placement in floating_placements:
        assert setupfinder.analysis.is_harddrop_possible(
            piece, placement, test_field) == False

    # test harddropping into narrow gap
    # x = 0 is 3-wide, x = 4 is 2-wide, x = 7 is 1-wide
    test_field, __ = fumen.decode(
        "v115@AhA8BeA8AeB8CeA8BeA8AeB8CeA8BeA8AeB8CeA8Be?A8AeB8JeAgH")
    for __ in range(20 - len(test_field)):
        test_field.append([0] * 10)
    # test every piece/rotation in each spot
    # OCCUPIED_COLS is set up the same way as PIECES, for each rotation it's a list of which cols contain a block
    for piece, rot_cols in setupfinder.analysis.OCCUPIED_COLS.items():
        for rotation, cols in enumerate(rot_cols):
            rotation_width = len(cols)
            # first column with a block in it (to align piece)
            rotation_x_offset = cols[0]
            # bottom of the piece so we don't try placing out of bounds
            rotation_y = setupfinder.analysis.MIN_Y_PLACEMENT[piece][rotation]
            fits_in_3_wide_gap = setupfinder.analysis.is_harddrop_possible(
                piece, (0 - rotation_x_offset, rotation_y, rotation),
                test_field)
            fits_in_2_wide_gap = setupfinder.analysis.is_harddrop_possible(
                piece, (4 - rotation_x_offset, rotation_y, rotation),
                test_field)
            fits_in_1_wide_gap = setupfinder.analysis.is_harddrop_possible(
                piece, (7 - rotation_x_offset, rotation_y, rotation),
                test_field)
            assert fits_in_3_wide_gap == (rotation_width <= 3)
            assert fits_in_2_wide_gap == (rotation_width <= 2)
            assert fits_in_1_wide_gap == (rotation_width <= 1)

    # test places where piece fits but spot covered
    # same field as before but entire thing is covered
    test_field, __ = fumen.decode(
        "v115@zgJ8CeA8BeA8AeB8CeA8BeA8AeB8CeA8BeA8AeB8Ce?A8BeA8AeB8JeAgH")
    for __ in range(20 - len(test_field)):
        test_field.append([0] * 10)
    for piece, rot_cols in setupfinder.analysis.OCCUPIED_COLS.items():
        for rotation, cols in enumerate(rot_cols):
            # first column with a block in it (to align piece)
            rotation_x_offset = cols[0]
            # bottom of the piece so we don't try placing out of bounds
            rotation_y = setupfinder.analysis.MIN_Y_PLACEMENT[piece][rotation]
            covered_3_wide_gap = setupfinder.analysis.is_harddrop_possible(
                piece, (0 - rotation_x_offset, rotation_y, rotation),
                test_field)
            assert covered_3_wide_gap == False

    # make sure flat i piece can't be placed with blocks covering row 1
    # (this tests covering blocks inside the piece's bounding box)
    test_field, __ = fumen.decode("v115@RhJ8DeF8JeAgl")
    for __ in range(20 - len(test_field)):
        test_field.append([0] * 10)
    covered_i_piece = setupfinder.analysis.is_harddrop_possible(
        "I", (0, -1, 0), test_field)
    assert covered_i_piece == False