From 31e6547d478ba45695c14805976a93d6077cbdea Mon Sep 17 00:00:00 2001 From: doyle Date: Sat, 16 Sep 2023 19:47:59 +1000 Subject: [PATCH] Start working on A* --- External/tely | 2 +- feely_pona.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++++- feely_pona_unity.h | 1 + 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/External/tely b/External/tely index 1b331f9..39af5c5 160000 --- a/External/tely +++ b/External/tely @@ -1 +1 @@ -Subproject commit 1b331f9ab37baa31b345d5be8d71a8c4c7946f87 +Subproject commit 39af5c5627404982ec9200b2155f0b5c8874bf8f diff --git a/feely_pona.cpp b/feely_pona.cpp index 74a3a67..172821c 100644 --- a/feely_pona.cpp +++ b/feely_pona.cpp @@ -297,7 +297,71 @@ void FP_GameUpdate(TELY_Platform *platform, TELY_Game *game, TELY_Renderer *rend if (TELY_Platform_InputScanCodeIsPressed(input, TELY_PlatformInputScanCode_F1)) { // NOTE: Do A* algorithm Dqn_V2 world_pos = TELY_Game_CalcEntityWorldPos(game, player->handle); - Dqn_V2I player_tile = platform->core.window_size / FP_TILE_SIZE; + Dqn_V2I player_tile = Dqn_V2I_InitNx2(world_pos.x / FP_TILE_SIZE, world_pos.y / FP_TILE_SIZE); + Dqn_V2I target_tile = Dqn_V2I_InitNx2(30, 10); + + Dqn_FArray frontier = {}; + Dqn_FArray_Add(&frontier, player_tile); + + Dqn_usize tile_count_x = DQN_CAST(Dqn_usize)(platform->core.window_size.w / FP_TILE_SIZE); + Dqn_usize tile_count_y = DQN_CAST(Dqn_usize)(platform->core.window_size.h / FP_TILE_SIZE); + + Dqn_DSMap cost_so_far = Dqn_DSMap_Init(128); + Dqn_DSMap came_from = Dqn_DSMap_Init(128); + DQN_DEFER { + Dqn_DSMap_Deinit(&came_from); + Dqn_DSMap_Deinit(&cost_so_far); + }; + + + // NOTE: Initialise the starting cost + { + uint64_t tile_as_u64 = (DQN_CAST(uint64_t)player_tile.y << 32) | (DQN_CAST(uint64_t)player_tile.x << 0); + Dqn_DSMapKey key = Dqn_DSMap_KeyU64(&cost_so_far, tile_as_u64); + Dqn_DSMap_Set(&cost_so_far, key, 0 /*value*/, nullptr); + } + + while (frontier.size) { + Dqn_V2I current = frontier.data[0]; + if (current == target_tile) + break; + + Dqn_FArray neighbours = {}; + Dqn_V2I left = Dqn_V2I_InitNx2(current.x - 1, current.y); + Dqn_V2I right = Dqn_V2I_InitNx2(current.x + 1, current.y); + Dqn_V2I top = Dqn_V2I_InitNx2(current.x, current.y - 1); + Dqn_V2I bottom = Dqn_V2I_InitNx2(current.x, current.y + 1); + + if (left.x >= 0) + Dqn_FArray_Add(&neighbours, left); + if (right.x <= tile_count_x) + Dqn_FArray_Add(&neighbours, right); + if (top.y >= 0) + Dqn_FArray_Add(&neighbours, top); + if (bottom.y >= 0) + Dqn_FArray_Add(&neighbours, bottom); + + uint64_t curr_tile_as_u64 = (DQN_CAST(uint64_t)current.y << 32) | (DQN_CAST(uint64_t)current.x << 0); + Dqn_DSMapKey curr_tile_key = Dqn_DSMap_KeyU64(&cost_so_far, curr_tile_as_u64); + + #if 0 + for (Dqn_V2I next : neighbours) { + Dqn_usize new_cost = curr_cost + 1; + Dqn_usize *prev_cost = Dqn_DSMap_Find(&cost_so_far, curr_tile_key); + if (!prev_curr_cost || new_cost < *prev_curr_cost) { + *prev_cost = new_cost; + Dqn_usize manhattan_dist = DQN_ABS(target_tile.x - current.x) + DQN_ABS(target_tile.y - current.y); + Dqn_usize estimated_finish_cost = new_cost + manhattan_dist; + + // TODO(doyle): Find the insert location + + uint64_t next_tile_as_u64 = (DQN_CAST(uint64_t)next.y << 32) | (DQN_CAST(uint64_t)next.x << 0); + Dqn_DSMapKey next_tile_key = Dqn_DSMap_KeyU64(&came_from, next_tile_as_u64); + Dqn_DSMap_Set(&came_from, next_tile_key, curr_tile_as_u64); + } + } + #endif + } } } else { game->camera.world_pos += dir_vector * 5.f; diff --git a/feely_pona_unity.h b/feely_pona_unity.h index 30d2fbb..40cf9d8 100644 --- a/feely_pona_unity.h +++ b/feely_pona_unity.h @@ -32,6 +32,7 @@ #define DQN_ONLY_SLICE #define DQN_ONLY_LIST #define DQN_ONLY_VARRAY +#define DQN_ONLY_DSMAP #define DQN_ONLY_FS #define _CRT_SECURE_NO_WARNINGS #define DQN_IMPLEMENTATION