Exemple #1
0
 def clear_prev_path_data(self):
     # these work like traditional arrays
     self.path.clear()
     self.pq_arr.clear()
     # added call number to each cell in the lookup table so that when contain key is called
     # it checks the call number of the cell, even if contains_key prop is true, if the call number
     # is not the same as the current call number it knows its from a different call. set sets
     # the call number. Because of this memset is not needed.
     self.g_arr.size = array_capacity(self.g_arr)
     self.came_from.size = array_capacity(self.came_from)
Exemple #2
0
 def check_lookup_table_size(self, game: Game):
     # check to see if the pathfinder capacity on the lookup tables is large
     #  enough for the max map. path and pq_arr are not lookup tables, just regular arrays.
     map_row_ratio = game.max_map_size.x * game.move_grid_ratio
     map_col_ratio = game.max_map_size.y * game.move_grid_ratio
     map_max_capacity = map_row_ratio * map_col_ratio
     g_arr_capacity = array_capacity(self.g_arr)
     came_from_capacity = array_capacity(self.came_from)
     if g_arr_capacity < map_max_capacity or came_from_capacity < map_max_capacity:
         print(
             "PathFinder.check_lookup_table_size - path_finder g_arr capacity or came_from capacity is not large enough for the max size map.\nMax map size:", map_max_capacity, "\ng_arr capacity:", g_arr_capacity, "\ncame_from capacity:", came_from_capacity)
         exit(1)
Exemple #3
0
def push_value(arr, value):
    capacity = array_capacity(arr)
    if arr.size > capacity - 1:
        print("push_value - array size is > than capacity - 1.", "size:",
              arr.size, "capacity:", capacity)
        exit(1)
    arr[arr.size] = value
    arr.size += 1
Exemple #4
0
def push(arr, value_ptr):
    capacity = array_capacity(arr)
    if arr.size > capacity - 1:
        print("push - array size is > than capacity - 1.", "size:", arr.size,
              "capacity:", capacity)
        exit(1)
    arr[arr.size] = deref(value_ptr)
    arr.size += 1
Exemple #5
0
def next_handle(arr):
    capacity = array_capacity(arr)
    if arr.size > capacity - 1:
        print("next_handle - array size is > than capacity - 1.", "size:",
              arr.size, "capacity:", capacity)
        exit(1)
    handle = arr.size
    arr.size += 1
    return handle
Exemple #6
0
def next(arr):
    capacity = array_capacity(arr)
    if arr.size > capacity - 1:
        print("next - array size is > than capacity - 1.", "size:", arr.size,
              "capacity:", capacity)
        exit(1)
    value = addr(arr[arr.size])
    arr.size += 1
    return value
Exemple #7
0
 def init(self, game: Game):
     self.units.size = array_capacity(self.units)
     last_enum_idx = last_enum_int(UnitName)
     if last_enum_idx > self.units.size - 1:
         print("UnitDB.init - UnitName's last enum idx is > units capacity.")
         exit(1)
     # skip NA by starting at 1
     for i in range(1, last_enum_idx):
         unit_name = cast(i, "UnitName")
         game.temp_unit.init(game, 0)
         game.temp_unit.set_to(game, unit_name, Faction.Ally)
         self.units[i] = game.temp_unit
 def init(self, game: Game):
     self.items.size = array_capacity(self.items)
     last_enum_idx = last_enum_int(ItemName)
     if last_enum_idx > self.items.size - 1:
         print(
             "ItemDB.init - ItemName's last enum idx is > items capacity.")
         exit(1)
     # skip NA by starting at 1
     for i in range(1, last_enum_idx):
         item_name = cast(i, "ItemName")
         game.temp_item.set_to(game, item_name)
         self.items[i] = game.temp_item
 def init(self, game: Game):
     self.abilities.size = array_capacity(self.abilities)
     last_enum_idx = last_enum_int(AbilityName)
     if last_enum_idx > self.abilities.size - 1:
         print(
             "AbilityDB.init - AbilityName's last enum idx is > abilities capacity."
         )
         exit(1)
     # skip NA by starting at 1
     for i in range(1, last_enum_idx):
         ability_name = cast(i, "AbilityName")
         game.temp_ability.set_to(game, ability_name)
         self.abilities[i] = game.temp_ability
Exemple #10
0
def string_set(arr1, arr2):
    # arr1 and arr2 are both of type Array of char
    capacity = array_capacity(arr1)
    buffer1 = array_get_buffer(arr1)
    buffer2 = array_get_buffer(arr2)

    if arr2.size > capacity - 1:
        print("string_set - arr2.size > then the capacity of arr1",
              "\narr2.size:", arr2.size, "\narr1 capacity:", capacity,
              "\narr1 str:", buffer1, "\narr2 str:", buffer2)
        exit(1)
    strcpy(buffer1, buffer2)
    arr1.size = arr2.size
Exemple #11
0
def string_set_literal(arr, string_literal):
    # arr is of type Array of char, string literal is of type char*
    capacity = array_capacity(arr)
    length = strlen(string_literal)
    buffer = array_get_buffer(arr)

    if length > capacity - 1:
        print(
            "string_set_literal - string literal length is > then the capacity of arr.",
            "\nstring literal length:", length, "\narr capacity:", capacity,
            "\narr str:", buffer, "\nstring_literal:", string_literal)
        exit(1)
    strcpy(buffer, string_literal)
    arr.size = length
Exemple #12
0
def pool_get_handle(arr, last_in_use_handle_ptr: int,
                    debug_pool_name_char_ptr) -> int:
    last_in_use_handle = deref(last_in_use_handle_ptr)
    for i, item in enumerate(arr):
        if not (item.in_use_in_pool):
            item.in_use_in_pool = True
            # update last_in_use_handle_ptr if the handle returned
            # is greater than the last_in_use_handle_ptr value
            if i > last_in_use_handle:
                set(deref(last_in_use_handle_ptr), i)
            return i
    capacity = array_capacity(arr)
    print("pool_get_handle - all elements are in use.")
    print("pool name:", debug_pool_name_char_ptr, "\npool size: ", arr.size,
          "\npool capacity:", capacity)
    exit(1)
Exemple #13
0
def string_cat_literal(arr, string_literal):
    # arr is of type Array of char, string literal is of type char*
    capacity = array_capacity(arr)
    length = strlen(string_literal)
    buffer = array_get_buffer(arr)

    # nothing to cat
    if length == 0:
        return
    # if arr1 size is 0 make sure it has a null terminator by doing a strcpy of an empty string.
    # a size of 0 might mean its unitialized.
    if arr.size == 0:
        string_set_literal(arr, "")
    if arr.size + length > capacity - 1:
        print(
            "string_cat_literal - arr.size + string literal length is > then the capacity of arr.",
            "\narr size:", arr.size, "\nstring literal length:", length,
            "\narr capacity:", capacity, "\narr str:", buffer,
            "\nstring_literal:", string_literal)
        exit(1)
    strcat(buffer, string_literal)
    arr.size += length
Exemple #14
0
def string_cat(arr1, arr2):
    # arr1 and arr2 are both of type Array of char
    capacity = array_capacity(arr1)
    buffer1 = array_get_buffer(arr1)
    buffer2 = array_get_buffer(arr2)

    # nothing to cat
    if arr2.size == 0:
        return
    # if arr1 size is 0 make sure it has a null terminator by doing a strcpy of an empty string.
    # a size of 0 might mean its unitialized.
    if arr1.size == 0:
        string_set_literal(arr1, "")
    if arr1.size + arr2.size > capacity - 1:
        print(
            "string_cat - arr1.size + arr2.size is > then the capacity of arr.",
            "\narr1 size:", arr1.size, "\narr2 size:", arr2.size,
            "\narr capacity:", capacity, "\narr1 str:", buffer1, "\narr2 str:",
            buffer2)
        exit(1)
    strcat(buffer1, buffer2)
    arr1.size += arr2.size
Exemple #15
0
    def set_path(self, game: Game, map: Map, acting_unit: Unit, p1: SDL_Point, p2: SDL_Point, check_unit_collissions: bool):
        # inc call number, doens't matter if it overflows just needs to be unique for each call
        self.call_number += 1
        # if the call number if 0 it means it overflowed, clear the tables so that previous
        # call numbers won't be treated as valid. Imagine call number 5 is set in a cell from the
        # previous 0 - MAX_SIZE iteration, if the current call number is 5 it will treat it as valid,
        # even though it is from the previous 0 - MAX_SIZE iteration
        if self.call_number == 0:
            memset(addr(self.g_arr), 0, 1)
            memset(addr(self.came_from), 0, 1)
            # reset size as it was just zero'd out
            self.g_arr.size = array_capacity(self.g_arr)
            self.came_from.size = array_capacity(self.came_from)
            # finally inc call number to 1 so that 0 call number values from memset are not
            # treated as valid from this call number (that would mean every cell was valid)
            self.call_number = 1
        # clear previous path data
        self.clear_prev_path_data()
        # make copies of p1 and p2 because there was a weird mutation bug
        start = deref(p1)
        target = deref(p2)
        # closest point to target - is only valid if find_closest_target param is true
        self.closest_point_to_target = start
        self.closest_dist_to_target = manhattan_distance(start, target)
        tile_point_hit_box_cpy = acting_unit.tile_point_hit_box

        if not(map.in_bounds_move_grid(target)):
            print("PathFinder.set path - target_point is not in bounds.")
            exit(1)
        if points_are_equal(start, target):
            print("Pathfinder.set_path - start and target points are equal.")
            return

        iters = 0
        reconstruct_path_iters = 0
        # max iters for now is the path capacity, though iters can be greater than
        # the number of tiles in the map if it gets stuck and needs go around obstacles.
        # a good starting point though, change later if people struggle to find paths.
        max_iters = array_capacity(self.path)
        # not sure if this is true but keeping it for now
        if max_iters > array_capacity(self.path):
            print("PathFinder.set_path max_iters must be <= path capacity")
            exit(1)
        neighbors = Array[SDL_Point](4)
        # set size directly because it will be manipulated with random access below
        neighbors.size = 4
        path_node = PathNode()
        path_node.p = start
        path_node.g = 0
        # self.g_arr.push(path_node)
        insert_point(self.g_arr, path_node.p, path_node,
                     map.rows, self.call_number)
        pq_node = PQNode()
        pq_node.p = start
        pq_node.f = manhattan_distance(start, target)
        self.pq_arr.push(pq_node)
        came_from = CameFrom()

        # don't exit if iters fails, it just means a path couldn't be found.
        # it is not likely an error condition (althought it could be)
        while iters < max_iters and self.pq_arr.size > 0:
            iters += 1

            # pop last idx from pq_arr. It is sorted so it is the
            # node with the min f value.
            pq_last_idx = self.pq_arr.size - 1
            current = self.pq_arr[pq_last_idx]
            self.pq_arr.size -= 1

            if points_are_equal(current.p, target):
                # print("Found target in", iters, "iters")
                self.path.push(target)
                while arr_contains_key(self.came_from, current.p, map.rows, self.call_number):
                    reconstruct_path_iters += 1
                    if reconstruct_path_iters > max_iters:
                        print(
                            "PathFinder.set_path - reconstruct_path iters > max_iters.")
                        exit(1)
                    came_from_handle = get_1d_from_2d_idx(current.p, map.rows)
                    came_from_ptr = self.came_from.at(came_from_handle)
                    current.p = came_from_ptr.to_point
                    if not(points_are_equal(current.p, start)):
                        self.path.push(current.p)

                # reverse the array as it is currently backwards
                self.path.reverse()
                return

            n0 = neighbors.at(0)
            n1 = neighbors.at(1)
            n2 = neighbors.at(2)
            n3 = neighbors.at(3)
            n0.x = current.p.x + 1
            n0.y = current.p.y
            n1.x = current.p.x - 1
            n1.y = current.p.y
            n2.x = current.p.x
            n2.y = current.p.y + 1
            n3.x = current.p.x
            n3.y = current.p.y - 1

            for n in neighbors:
                if not(map.in_bounds_move_grid(n)):
                    continue
                tile_point_hit_box_cpy.x = n.x
                tile_point_hit_box_cpy.y = n.y
                if check_unit_collissions and map.unit_occupies_tile_point_move_grid(game, tile_point_hit_box_cpy, acting_unit.handle):
                    continue
                g_handle = get_1d_from_2d_idx(current.p, map.rows)
                g_node = self.g_arr.at(g_handle)
                new_g_cost = g_node.g + 1
                neighbor_g_contains_handle = arr_contains_key(
                    self.g_arr, n, map.rows, self.call_number)
                neighbor_g_handle = get_1d_from_2d_idx(n, map.rows)
                neighbor_g = -1
                if neighbor_g_contains_handle:
                    neighbor_g_node = self.g_arr.at(neighbor_g_handle)
                    neighbor_g = neighbor_g_node.g
                if not(neighbor_g_contains_handle) or new_g_cost < neighbor_g:
                    f = manhattan_distance(n, target)

                    # update or push g_arr for the neighbor
                    path_node.g = new_g_cost
                    path_node.p = deref(n)
                    insert_point(self.g_arr, path_node.p,
                                 path_node, map.rows, self.call_number)

                    # push pq node and sort the pq
                    pq_node.f = f
                    pq_node.p = deref(n)
                    self.pq_arr.push(pq_node)
                    pq_insertion_sort(self.pq_arr)

                    # update or push a new came from to came from arr
                    came_from.from_point = deref(n)
                    came_from.to_point = current.p
                    insert_point(self.came_from, n, came_from,
                                 map.rows, self.call_number)

                    # possibly update closest point to target
                    dist = manhattan_distance(current.p, target)
                    if dist > 0 and dist < self.closest_dist_to_target:
                        self.closest_dist_to_target = dist
                        self.closest_point_to_target = current.p
Exemple #16
0
 def init(self):
     self.slots.size = array_capacity(self.slots)
     # zero'd out memory will set slot is empty to false, it is initially true.
     for slot in self.slots:
         slot.slot_is_empty = True
Exemple #17
0
def pool_init(game: Game, arr, last_in_use_handle_ptr: int):
    arr.size = array_capacity(arr)
    set(deref(last_in_use_handle_ptr), -1)
    for i, item in enumerate(arr):
        item.init(game, i)
Exemple #18
0
def pool_of_text_init(game: Game, arr, last_in_use_handle_ptr: int):
    # text uses text_init because there are many texts for each string size.
    arr.size = array_capacity(arr)
    set(deref(last_in_use_handle_ptr), -1)
    for i, item in enumerate(arr):
        item.text_init(game, i)