Beispiel #1
0
    def test_tower_copy(self):
        tower1 = Tower_State()
        tower1_copy = copy(tower1)
        self.assertEqual(tower1, tower1_copy)
        self.assertTrue(tower1 is not tower1_copy)

        tower2 : Tower_State = Tower_State()
        for new_block in [Block(block_mesh, 'flat_wide', (0, 0, i)) for i in range(1, 50)]:
            if tower2.can_add(new_block):
                tower2.add(new_block)

        tower2_copy : Tower_State = copy(tower2)
        self.assertEqual(tower2, tower2_copy)
        self.assertTrue(tower2 is not tower2_copy)

        new_block = Block(block_mesh, 'flat_wide', (0, 0, 50))
        if tower2.can_add(new_block):
            tower2.add(new_block)
            print("Added new block to tower 2, {}".format(new_block.__str__()))

        self.assertNotEqual(tower2, tower2_copy)
        self.assertTrue(tower2 is not tower2_copy)

        self.assertNotEqual(tower2._connectivity, tower2_copy._connectivity)
        self.assertNotEqual(list(tower2._orientation_counter), list(tower2_copy._orientation_counter))
    def get_successors(self, tower_state: Tower_State):

        print("Building succesors for state of height:{}".format(tower_state._max_level))
        pp(tower_state)
        all_possible_son_desc = []
        for father_block in tower_state.gen_blocks(no_floor=False, filter_saturated_block=False):
            if father_block.is_saturated(tower_state):
                self._num_of_blocks_saturated += 1
                continue
            all_possible_son_desc.extend(filter(
                lambda desc: not tower_state.is_bad_block(Block.gen_str(desc)),
                father_block.gen_possible_block_descriptors(
                      limit_orientation=lambda o: father_block.is_perpendicular(o),
                      limit_len=self._limit_sons,
                      random_order=self._gen_randomly
                )
            )
            )
        if self._gen_randomly:
            shuffle(all_possible_son_desc)
        else:
            all_possible_son_desc.sort(key=lambda desc: desc[1][Z], reverse=True)
        for _ in range(self._limit_branching):
            new_tower = copy(tower_state)
            actions = []
            while len(actions) < self._num_of_blocks_in_action:
                if all_possible_son_desc:
                    desc = all_possible_son_desc.pop()
                else:
                    break
                if tower_state.is_bad_block(Block.gen_str(desc)):
                    self._num_of_descriptors_disqualified += 1
                    continue
                son_block = Block(BLOCK_MESH, *desc)
                if new_tower.can_add(son_block):
                    new_tower.add(son_block)
                    actions.append(son_block)
                else:
                    self._num_of_blocks_disqualified += 1
            if actions:
                yield (new_tower, actions, len(actions))
            else:
                print(
                    "\tNum bad from hash:\t{}\n\tNum of blocks disqualified:\t{}\n\tNum of blocks saturated:\t{}".format(
                        tower_state._bad_block_calls,
                        self._num_of_blocks_disqualified,
                        self._num_of_blocks_saturated
                    ))
                return
                #successors.append((new_tower, actions, len(actions)))
        print("\tNum of desc disqualified:\t{}\n\tNum of blocks disqualified:\t{}\n\tNum of blocks saturated:\t{}".format(
            self._num_of_descriptors_disqualified,
            self._num_of_blocks_disqualified,
            self._num_of_blocks_saturated
        ))
Beispiel #3
0
    def test_perp_tower(self):
        STAGE = 10
        tower: Tower_State = Tower_State(size=30, ring_floor=True)
        for i in range(100):
            added = []
            for father_block in tower.gen_blocks(no_floor=False):
                if not father_block.is_saturated(tower):
                    for son_desc in father_block.gen_possible_block_descriptors(
                            limit_orientation=lambda o: father_block.is_perpendicular(o), limit_len=STAGE / 2, random_order=True):
                        son_block = Block(floor_mesh, *son_desc)
                        if tower.can_add(son_block):
                            tower.add(son_block)
                            added.append(son_block)
                            if len(added) > STAGE:
                                break
                    if len(added) > STAGE:
                        break
            print(i)
            DISPLAY = False
            TO_FILE = True

            if DISPLAY or TO_FILE:
                old_meshes = [b.render() for b in filter(lambda b: b not in added, tower.gen_blocks())]
                new_meshes = [b.render() for b in added]
                display_colored(old_meshes + new_meshes,
                                ['gray'] * len(old_meshes) + ['cyan'] * len(new_meshes),
                                scale=60,
                                to_file=TO_FILE and not DISPLAY,
                                file_name="plots/ring_floor4/{0:03}.png".format(i)
                                )
Beispiel #4
0
    def test_state_copy_time(self):
        results = dict()
        l = 6
        copies = dict()
        for t in range(10, 100, 20):
            tower : Tower_State = Tower_State()
            for new_block in [Block(block_mesh, 'flat_wide', (0, 0, i)) for i in range(1, t)]:
                if tower.can_add(new_block):
                    tower.add(new_block)

            s = time.time()
            copies[t] = [copy(tower) for _ in range(l)]
            e = time.time() - s
            results[t] = e / l
            print(results[t])
        pp(results)
        for height, tower_copy_list in copies.items():
            for i, tower in enumerate(tower_copy_list):
                new_block  = Block(block_mesh, 'flat_wide', (0, i, height))
                if tower.can_add(new_block):
                    tower.add(new_block)
        towers = []
        for copy_list in copies.values():
            towers += copy_list
        for i, tower1 in enumerate(towers):
            for j, tower2 in enumerate(towers[i+1:]):
                self.assertNotEqual(tower1, tower2)
                self.assertNotEqual(tower1._connectivity, tower2._connectivity)
Beispiel #5
0
    def test_iteration(self):
        tower: Tower_State = Tower_State()
        for new_block in [Block(block_mesh, 'flat_wide', (0, 0, i)) for i in range(1, 10)]:
            if tower.can_add(new_block):
                tower.add(new_block)

        for b in tower.gen_blocks():
            print(b.get_top_level())
 def get_start_state(self) -> Tower_State:
     tower: Tower_State = Tower_State(self._floor_size, # size
                                      True, # ring floor
                                      None, # father state
                                      self._ring_width, # args
                                      self._number_of_rings,
                                      self._distance_between_rings)
     return tower
Beispiel #7
0
def cover_heuristic(state: Tower_State, block_search: Block_Search):
    starting_point = state._starting_cover_size
    end_goal = state._starting_cover_size / block_search._height_goal
    proportional_height = state._max_level / block_search._height_goal
    desired_cover = state._starting_cover_size / proportional_height
    actual_cover = state.get_cover_at_level(state._max_level - 1)
    if actual_cover > desired_cover:
        # encourage building tall
        return (block_search._height_goal - state._max_level)
    else:
        #encourage bulding wide
        return (block_search._height_goal - state._max_level) / 15
Beispiel #8
0
    def test_covers(self):
        tower: Tower_State = Tower_State()
        for new_block in [Block(block_mesh, 'flat_wide', (0, 0, i)) for i in range(1, 10)]:
            if tower.can_add(new_block):
                tower.add(new_block)
        cover = tower.get_cover_at_level(0)
        for i in range(10):
            self.assertEqual(cover, tower.get_cover_at_level(i), str(tower.get_cover_at_level(i))+str(i))

        tower: Tower_State = Tower_State()
        for i in range(10):
            for j in range(i, 10 - i):
                new_block = Block(block_mesh, 'flat_thin', (0, j*3, i))
                if tower.can_add(new_block):
                    tower.add(new_block)
        if DISPLAY:
            display([b.render() for b in tower.gen_blocks()])
        prev = 10000
        for level in range(10):
            size = tower.get_cover_at_level(level).__len__()
            self.assertLessEqual(size, prev)
            prev = size
Beispiel #9
0
    def test_spread(self):
        tower_state = Tower_State()

        #same orientation
        orientation = 'tall_wide'
        block1 = Block(block_mesh, orientation, (0, 0, 0))
        block2 = Block(block_mesh, orientation, (2, 1, 0))

        spread = tower_state.get_spread(block1, block2)
        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)

        orientation = 'short_wide'
        block1 = Block(block_mesh, orientation, (0, 0, 0))
        block2 = Block(block_mesh, orientation, (5, 5, 0))

        spread = tower_state.get_spread(block1, block2)
        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)

        orientation = 'flat_thin'
        block1 = Block(block_mesh, orientation, ( 0,  0, 0))
        block2 = Block(block_mesh, orientation, (10, 10, 0))

        spread = tower_state.get_spread(block1, block2)
        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)

        # differing orientations - must have same top level
        block1 = Block(block_mesh, 'flat_wide', ( 0,  0, 0))
        block2 = Block(block_mesh, 'tall_thin', ( 5, 3, -7))

        spread = tower_state.get_spread(block1, block2)
        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)

        block1 = Block(block_mesh, 'flat_wide', ( 0,  0, 1))
        block2 = Block(block_mesh, 'short_thin', ( -10, 3, 0))

        spread = tower_state.get_spread(block1, block2)
        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)


        # test commutative quality of spread: ie. my spread with you is the same as yours spread with me.
        block1 = Block(block_mesh, 'flat_wide', ( 0,  0, 1))
        block2 = Block(block_mesh, 'short_thin', ( -15, 5, 0))

        spread1 = tower_state.get_spread(block1, block2)
        spread2 = tower_state.get_spread(block2, block1)

        self.assertEqual(spread1, spread2)

        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread1, spread2], scale=20)

        block1 = Block(block_mesh, (0, 0, 0), (0, 5, 1))
        block2 = Block(block_mesh, (0, 0, 0), (-2, -11, 1))
        block3 = Block(block_mesh, 'flat_wide', (-1, -6, 3))
        tower_state.set_blocks_above(block1, {block3})
        tower_state.set_blocks_above(block2, {block3})
        spread = tower_state.get_spread(block2, block1)

        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)

        block1 = Block(block_mesh, (0, 0, 0), (0, 9, 1))
        block2 = Block(block_mesh, (0, 0, 0), (-2, -13, 1))
        block3 = Block(block_mesh, 'flat_wide', (-1, -6, 3))
        tower_state.set_blocks_above(block1, {block3})
        tower_state.set_blocks_above(block2, {block3})
        spread = tower_state.get_spread(block2, block1)

        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)

        block1 = Block(block_mesh, 'short_thin', (-8, -1, 1))
        block2 = Block(block_mesh, 'short_thin', (7, 1, 1))
        block3 = Block(block_mesh, 'flat_wide', (0, 0, 3))
        tower_state.set_blocks_above(block1, {block3})
        tower_state.set_blocks_above(block2, {block3})
        spread = tower_state.get_spread(block2, block1)

        if DISPLAY:
            display([block1.render(), block2.render()])
            display_multiple_cells([block1.get_cells(), block2.get_cells()], scale=20)
            display_multiple_grids([block1.get_cover_cells(), block2.get_cover_cells(), spread], scale=20)
    def get_successors(self, state: Tower_State):
        new_states = [copy(state) for _ in range(self._limit_branching)]
        successors = []
        pp(state)
        for new_state in new_states:
            num_of_blocks_added = 0
            actions = []
            for father_block in state.gen_blocks(no_floor=False):
                if father_block.is_saturated(new_state):
                    self._num_of_blocks_saturated += 1
                    continue
                if len(actions) > self._num_of_blocks_in_action:
                    break
                son_descriptors = list(father_block.gen_possible_block_descriptors(
                    limit_len=self._limit_sons,
                    limit_orientation=self._son_orientation_filter,
                    random_order=self._gen_randomly
                ))
                if self._gen_randomly:
                    shuffle(son_descriptors)
                for desc in son_descriptors:
                    if len(actions) > self._num_of_blocks_in_action:
                        break
                    if state.is_bad_block(Block.gen_str(desc)):
                        self._num_of_descriptors_disqualified += 1
                    else:  # good block description, lets try it out
                        blocks = [Block(BLOCK_MESH, *desc)]
                        if self._use_symmetry:
                            sub_descriptors = Block_Search.propagate(*desc, dist=self._symmetrical_base_distance)
                            # qualified_symmetrical_brothers = len(sub_descriptors)
                            for sym_desc in sub_descriptors:
                                if state.is_bad_block(Block.gen_str(desc)):
                                    self._num_of_descriptors_disqualified += 1
                                    # qualified_symmetrical_brothers -= 1
                                else:
                                    blocks.append(Block(BLOCK_MESH, *sym_desc))
                        to_add = []
                        for candidate_block in blocks:
                            if new_state.can_add(candidate_block):
                                to_add.append(candidate_block)
                            else:
                                self._num_of_blocks_disqualified += 1
                            # else:
                            #     if self._use_symmetry:
                            #         qualified_symmetrical_brothers -= 1
                        if self._use_symmetry:
                            if len(to_add) >= self._sym_son_threshold:
                                for good_block in to_add:
                                    new_state.add(good_block)
                                    actions.append(good_block)
                                    num_of_blocks_added += 1

                            else:
                                for good_block in to_add:
                                    self._num_of_blocks_disqualified += 1
                                    new_state.disconnect_block_from_neighbors(good_block)
                        else:
                            for good_block in to_add:
                                new_state.add(good_block)
                                actions.append(good_block)
                                num_of_blocks_added += 1
            successors.append((new_state, actions, len(actions)))
            # if DISPLAY:
            #     display_colored([b.render() for b in state.gen_blocks()])
            # return True
        # print("\tNum of desc disqualified:{}\tNum of blocks disqualified:{}\tNum of staturated:{}".format(
        #     self._num_of_descriptors_disqualified,
        #     self._num_of_blocks_disqualified,
        #     self._num_of_blocks_saturated
        # ))
        return successors
 def get_start_state(self):
     return Tower_State(self._floor_size)
 def is_goal_state(self, state: Tower_State):
     if state._max_level >= self._height_goal:
         if DISPLAY:
             display([b.render() for b in state.gen_blocks()], scale=self._height_goal * 0.7)
         return True
     return False