예제 #1
0
def test_valid_moves_tsu(width):
    field = TallField(1, tsu_rules=True)
    for top in range(1 << 16):
        field.data[3] = top & 255
        field.data[4] = top >> 8
        assert (_reference_valid_moves(field.data,
                                       width) == field._valid_moves(width))
예제 #2
0
def test_action_mask_tsu():
    state = State(13, 6, 2, 1, tsu_rules=True)
    stack = [_, _, _, _, _, _, _, _] * state.field.offset
    stack += [
        R,
        _,
        R,
        G,
        _,
        G,
        _,
        _,
    ]
    state.field = TallField.from_list(stack,
                                      num_layers=state.num_layers,
                                      tsu_rules=state.tsu_rules)
    state.render()
    mask = state.get_action_mask()
    print(mask)
    assert (len(mask) == 5 + 5 + 6 + 6)
    for i, (x, orientation) in enumerate(state.actions):
        if x in (1, 4):
            assert (mask[i])
        elif orientation in (0, 2) and x in (0, 3):
            assert (mask[i])
        else:
            assert (not mask[i])
예제 #3
0
    def __init__(self,
                 height,
                 width,
                 num_layers,
                 num_deals=None,
                 tsu_rules=False,
                 has_garbage=False,
                 deals=None,
                 seed=None):
        if height not in ALLOWED_HEIGHTS:
            raise NotImplementedError(
                "Only heights {} supported".format(ALLOWED_HEIGHTS))
        if width > BottomField.WIDTH:
            raise NotImplementedError("Maximum width is {}".format(
                BottomField.WIDTH))
        if height == 13 and not tsu_rules:
            raise NotImplementedError(
                "Height 13 only available with tsu ruleset")
        if tsu_rules and not height == 13:
            raise NotImplementedError(
                "Tsu ruleset available only for height 13")
        if num_deals and deals:
            raise ValueError("Cannot use a partial number of fixed deals")

        if height == BottomField.HEIGHT:
            self.field = BottomField(num_layers, has_garbage=has_garbage)
        else:
            self.field = TallField(num_layers,
                                   tsu_rules=tsu_rules,
                                   has_garbage=has_garbage)
        self.width = width
        self.height = height
        self.num_deals = num_deals
        self.garbage_x = 0 if has_garbage else None
        self.make_actions()
        self.seed(seed)
        if deals is None:
            self.make_deals()
        else:
            self.deals = list(deals)
예제 #4
0
def test_render_in_place():
    field = TallField(1)
    for i in range(16):
        field.data[i] = ((i + 4234)**3) % 256

    for i in range(20):
        print(i)
    util.print_up(16)
    print("Let's shift this a bit!", end="")
    field.render(in_place=True)
    print("hello")
    field.render(width=6, height=13)
예제 #5
0
def test_complex_resolve():
    stack = [
        R,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        R,
        G,
        B,
        Y,
        _,
        _,
        _,
        _,
        R,
        R,
        G,
        B,
        _,
        _,
        _,
        _,
        G,
        G,
        B,
        B,
        _,
        _,
        _,
        _,
    ]
    field = TallField.from_list(stack)
    field.render()
    print()
    score, chain = field.resolve()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ])
    assert (chain == 3)
    expected = 4 * 10 * (1)  # Reds
    expected += 5 * 10 * (8 + 2)  # Greens
    # Blues, yellows and reds
    num_cleared = 26
    chain_power = 16
    group_bonuses = 0 + 0 + 3 + 3 + 3
    color_bonus = 6
    expected += num_cleared * 10 * (chain_power + group_bonuses + color_bonus)
    assert (score == expected)
예제 #6
0
def test_resolve_plain(tsu_rules):
    stack = [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        B,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        G,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        G,
        G,
        _,
        _,
        _,
        _,
    ]
    field = TallField.from_list(stack, tsu_rules=tsu_rules)
    field.render()
    print()
    score, chain = field.resolve()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        B,
        _,
        _,
        _,
        _,
        _,
    ])
    assert (chain == 2)
    assert (score == 940)
예제 #7
0
def test_clear_groups(tsu_rules):
    O = Y + 1  # noqa
    stack = [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        G,
        O,
        O,
        _,
        Y,
        _,
        R,
        _,
        G,
        O,
        O,
        _,
        Y,
        Y,
    ]
    field = TallField.from_list(stack, tsu_rules=tsu_rules, has_garbage=True)
    field.render()
    score = field.clear_groups(5)
    print(score)
    field.render()
    stack = field.to_list()
    expected = [_] * 8 * 3
    if tsu_rules:
        expected += [O, _, _, _, _, _, _, _]
    else:
        expected += [_] * 8
    assert (score == 10 * (4 + 12) * (3 + 10 + 96))
    assert (stack == expected + [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        O,
        _,
        Y,
        Y,
    ])
예제 #8
0
def test_mirror():
    stack = [
        R,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
    ]
    field = TallField.from_list(stack)
    field.render()
    field.mirror()
    print()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ])
예제 #9
0
def test_has_moves_tsu():
    state = State(13, 2, 4, 1, tsu_rules=True)
    stack = [_, _, _, _, _, _, _, _] * state.field.offset
    stack += [
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
    ]
    state.field = TallField.from_list(stack,
                                      num_layers=state.num_layers,
                                      tsu_rules=state.tsu_rules)
    state.render()
    assert (state.get_children())
예제 #10
0
def test_overlapping_overlay():
    field = TallField(4)
    field.overlay([
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        R,
        G,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ])
    field.render()
    print()
    field.overlay([
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ])
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        _,
        _,
        R,
        R,
        _,
        R,
        _,
        _,
        R,
        G,
        _,
        _,
        R,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        R,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        R,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        R,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ])
예제 #11
0
def test_gravity():
    stack = [
        R,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
    ]
    field = TallField.from_list(stack)
    field.render()
    field.handle_gravity()
    print()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        R,
        G,
    ])
예제 #12
0
def test_overlay():
    field = TallField(3)
    field.overlay([_, G, R, _, _, _, _, _])
    field.handle_gravity()
    field.render()
    print()
    field.overlay([
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
    ])
    field.handle_gravity()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        _,
    ])
예제 #13
0
def test_resolve_garbage():
    O = G + 1  # noqa
    stack = [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        O,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        O,
        O,
        R,
        _,
        _,
        _,
        _,
        _,
        O,
        O,
        G,
        O,
        _,
        _,
        _,
        _,
        O,
        O,
        G,
        O,
        O,
    ]
    field = TallField.from_list(stack, tsu_rules=True, has_garbage=True)
    field.render()
    print()
    score, chain = field.resolve()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        O,
        _,
        O,
        _,
        _,
        _,
        _,
        _,
        O,
        O,
        G,
        O,
        _,
        _,
        _,
        _,
        O,
        O,
        G,
        O,
        O,
    ])
    assert (chain == 1)
    assert (score == 700)
예제 #14
0
def test_resolve_ghost():
    stack = [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        P,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        P,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        P,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        P,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
    ]
    field = TallField.from_list(stack, tsu_rules=True)
    field.render()
    print()
    score, chain = field.resolve()
    field.render()
    stack = field.to_list()
    assert (stack == [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
    ])
    assert (chain == 2)
    assert (score == 360)
예제 #15
0
def test_garbage_tsu():
    state = State(13, 6, 5, 1, tsu_rules=True, has_garbage=True)
    stack = [_, _, _, _, _, _, _, _] * state.field.offset
    stack += [
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        B,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        B,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        Y,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
    ]
    state.field = TallField.from_list(stack,
                                      num_layers=state.num_layers,
                                      tsu_rules=state.tsu_rules,
                                      has_garbage=state.has_garbage)
    state.render()
    state.add_garbage(39)
    state.render()
    state.field.resolve()
    assert (state.field.popcount == 51)
예제 #16
0
class State(object):
    TESTING = False

    def __init__(self,
                 height,
                 width,
                 num_layers,
                 num_deals=None,
                 tsu_rules=False,
                 has_garbage=False,
                 deals=None,
                 seed=None):
        if height not in ALLOWED_HEIGHTS:
            raise NotImplementedError(
                "Only heights {} supported".format(ALLOWED_HEIGHTS))
        if width > BottomField.WIDTH:
            raise NotImplementedError("Maximum width is {}".format(
                BottomField.WIDTH))
        if height == 13 and not tsu_rules:
            raise NotImplementedError(
                "Height 13 only available with tsu ruleset")
        if tsu_rules and not height == 13:
            raise NotImplementedError(
                "Tsu ruleset available only for height 13")
        if num_deals and deals:
            raise ValueError("Cannot use a partial number of fixed deals")

        if height == BottomField.HEIGHT:
            self.field = BottomField(num_layers, has_garbage=has_garbage)
        else:
            self.field = TallField(num_layers,
                                   tsu_rules=tsu_rules,
                                   has_garbage=has_garbage)
        self.width = width
        self.height = height
        self.num_deals = num_deals
        self.garbage_x = 0 if has_garbage else None
        self.make_actions()
        self.seed(seed)
        if deals is None:
            self.make_deals()
        else:
            self.deals = list(deals)

    @property
    def num_colors(self):
        return self.field.num_colors

    @property
    def num_layers(self):
        return self.field.num_layers

    @property
    def has_garbage(self):
        return self.field.has_garbage

    @property
    def tsu_rules(self):
        return getattr(self.field, "tsu_rules", False)

    @property
    def max_chain(self):
        return (self.width * self.height) // self.field.CLEAR_THRESHOLD

    @property
    def max_score(self):
        if isinstance(self.field, BottomField):
            return self.max_chain**2
        else:
            return 10 * self.width * self.height * 999 * self.max_chain  # FIXME: This overshoots a lot

    def seed(self, seed=None):
        # TODO: find why 2 states are initialized
        seed = 5
        self.np_random, seed = seeding.np_random(seed)
        return seed

    def reset(self):
        self.field.reset()
        self.make_deals()

    def render(self, outfile=sys.stdout, in_place=False):
        if not in_place:
            for _ in range(self.height):
                outfile.write("\n")
            util.print_up(self.height, outfile=outfile)
        self.field.render(outfile,
                          width=self.width,
                          height=self.height,
                          in_place=True)
        util.print_up(self.height, outfile=outfile)
        util.print_forward(2 * self.width + 2, outfile=outfile)
        remaining = self.height
        for deal in self.deals[:self.height // 2]:
            for puyo in deal:
                util.print_puyo(puyo, outfile=outfile)
            util.print_back(4, outfile=outfile)
            util.print_down(2, outfile=outfile)
            remaining -= 2
        util.print_reset(outfile=outfile)
        util.print_down(remaining, outfile=outfile)
        util.print_back(2 * self.width + 2, outfile=outfile)
        outfile.flush()

    def make_actions(self):
        self.actions = []
        for x in range(self.width):
            self.actions.append((x, 1))
            self.actions.append((x, 3))
        for x in range(self.width - 1):
            self.actions.append((x, 0))
            self.actions.append((x, 2))

        self._validation_actions = []
        for x in range(self.field.WIDTH - 1):
            self._validation_actions.append((x, 0))
        for x in range(self.field.WIDTH):
            self._validation_actions.append((x, 1))
        for x in range(self.field.WIDTH - 1):
            self._validation_actions.append((x, 2))
        for x in range(self.field.WIDTH):
            self._validation_actions.append((x, 3))

    def make_deals(self):
        self.deals = []
        for _ in range(self.num_deals):
            self.make_deal()

    def make_deal(self):
        self.deals.append((
            self.np_random.randint(0, self.num_colors),
            self.np_random.randint(0, self.num_colors),
        ))

    def add_garbage(self, amount):
        if not amount:
            return
        if not self.has_garbage:
            raise ValueError("This state doesn't support garbage")
        if amount < 0:
            raise ValueError("Cannot add negative amount of garbage")
        garbage = self.field.num_colors
        stack = []
        while amount:
            line = [None] * self.field.WIDTH
            while self.garbage_x < self.width and amount:
                line[self.garbage_x] = garbage
                self.garbage_x += 1
                amount -= 1
            if self.garbage_x >= self.width:
                self.garbage_x = 0
            stack = line + stack
        if len(stack) > self.field.WIDTH * self.field.HEIGHT:
            stack = [garbage] * (self.field.WIDTH * self.field.HEIGHT)
        self.field.overlay(stack)
        self.field.handle_gravity()

    def encode_deals(self):
        np_deals = np.zeros((self.num_colors, self.num_deals, 2))
        for i, deal in enumerate(self.deals):
            np_deals[deal[0]][i][0] = 1
            np_deals[deal[1]][i][1] = 1
        return np_deals

    def encode_deals_box(self):
        """
        Encode deals so that they can be stacked on top of the encoded field.
        """
        box = np.zeros((self.num_layers, self.num_deals, self.width),
                       dtype=np.int8)
        for i, deal in enumerate(self.deals):
            box[deal[0]][self.num_deals - 1 - i][0] = 1
            box[deal[1]][self.num_deals - 1 - i][1] = 1
        return box

    def encode_field(self):
        np_state = self.field.encode()
        return np_state[:self.num_layers,
                        (self.field.HEIGHT - self.height):, :self.width]

    def encode(self):
        return (self.encode_deals(), self.encode_field())

    def mirror(self):
        self.field.mirror()
        self.field.shift(self.width - self.field.WIDTH)

    def get_deal_stack(self, x, orientation):
        puyo_a, puyo_b = self.deals[0]
        stack = [None] * (2 * self.field.WIDTH)
        if orientation == 0:
            stack[x] = puyo_a
            stack[x + 1] = puyo_b
        elif orientation == 1:
            stack[x] = puyo_a
            stack[x + self.field.WIDTH] = puyo_b
        elif orientation == 2:
            stack[x] = puyo_b
            stack[x + 1] = puyo_a
        elif orientation == 3:
            stack[x] = puyo_b
            stack[x + self.field.WIDTH] = puyo_a
        else:
            raise ValueError("Unknown orientation")
        return stack

    def play_deal(self, x, orientation):
        if self.num_deals is not None:
            self.make_deal()
        puyo_a, puyo_b = self.deals.pop(0)
        index = self._validation_actions.index((x, orientation))
        self.field._make_move(index, puyo_a, puyo_b)

    def get_action_mask(self):
        result = np.zeros(len(self.actions))
        bitset = self.field._valid_moves(self.width)
        for i, (x, orientation) in enumerate(self.actions):
            index = self._validation_actions.index((x, orientation % 2))
            if bitset & (1 << index):
                result[i] = 1
        return result

    def validate_action(self, x, orientation):
        orientation %= 2
        if x + 1 - orientation >= self.width:
            return False
        bitset = self.field._valid_moves(self.width)
        index = self._validation_actions.index((x, orientation))
        return bool(bitset & (1 << index))

    def step(self, x, orientation):
        if not self.deals:
            return -1
        if not self.validate_action(x, orientation):
            return -1
        self.play_deal(x, orientation)
        reward = self.field.resolve()[0]
        if isinstance(self.field, TallField) and not any(self.field.data):
            reward += 8500
        if self.TESTING:
            assert (self.field.sane)
        return reward

    def clone(self):
        deals = self.deals[:]
        if self.num_deals is None:
            clone_deals = deals
        else:
            clone_deals = None
        clone = State(
            self.height,
            self.width,
            self.num_layers,
            self.num_deals,
            tsu_rules=self.tsu_rules,
            has_garbage=self.has_garbage,
            deals=clone_deals,
        )
        clone.field.data[:] = self.field.data
        clone.deals = deals
        return clone

    def get_children(self, complete=False):
        result = []
        for action in self.actions:
            child = self.clone()
            score = child.step(*action)
            if score >= 0:
                result.append((child, score))
            elif complete:
                result.append((None, score))
        return result

    def field_to_int(self):
        result = 0
        for y in range(self.field.HEIGHT - self.height, self.field.HEIGHT):
            for x in range(self.width):
                result *= self.num_layers + 1
                puyo = self.field.puyo_at(x, y)
                if puyo is not None:
                    result += puyo + 1
        return result

    def field_from_int(self, n):
        self.field.reset()
        for y in reversed(
                range(self.field.HEIGHT - self.height, self.field.HEIGHT)):
            for x in reversed(range(self.width)):
                n, puyo = divmod(n, self.num_layers + 1)
                if puyo > 0:
                    self.field._unsafe_set_puyo_at(x, y, puyo - 1)

    def to_list(self, offset=False):
        result = []
        for i, puyo in enumerate(self.field.to_list()):
            y, x = divmod(i, self.field.WIDTH)
            if x >= self.width:
                continue
            if offset and y < self.field.offset:
                continue
            result.append(puyo)
        return result
예제 #17
0
def test_encode():
    stack = [
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        R,
    ]
    field = TallField.from_list(stack)
    field.render()
    encoded = field.encode()
    expected = [
        [
            [0, 1, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 1],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 1, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 1],
        ],
        [
            [0, 0, 0, 0, 0, 0, 0, 0],
            [1, 0, 1, 0, 0, 0, 0, 0],
            [0, 0, 0, 1, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 1, 0, 0, 0, 0, 0],
            [1, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 1],
            [0, 0, 0, 0, 0, 0, 0, 0],
        ],
    ]
    assert (encoded == expected).all()
예제 #18
0
def test_resolve_large():
    state = State(16, 7, 2, 1)
    state.deals[0] = (0, 0)
    stack = [
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        _,
        G,
        G,
        G,
        _,
        _,
        _,
        _,
        _,
        R,
        R,
        R,
        G,
        G,
        G,
        _,
    ]
    state.field = TallField.from_list(stack, num_layers=state.num_layers)
    state.render()
    reward = state.step(0, 1)
    assert (reward == 8500 + 760)