Skip to content

Commit 8ffbfa1

Browse files
Merge pull request #160 from 42core-team/debug-data
2 parents d8e41f6 + c0189b3 commit 8ffbfa1

File tree

36 files changed

+650
-353
lines changed

36 files changed

+650
-353
lines changed

bots/hardcore/configs/game.config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"units": [
4343
{
4444
"name": "Warrior", // name, for aesthetic / display purposes only
45-
"visualizer_asset_path": "warrior", // folder that the units visuals are picked from
45+
"visualizer_asset_path": "warrior", // folder that the units visuals are picked from by visualizer
4646
"cost": 150, // amount of gems needed to spawn the unit
4747
"hp": 22, // amount of healthpoints the unit spawns with
4848
"baseActionCooldown": 3, // base delay between action executions

bots/hardcore/gridmaster/inc/bot.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,4 @@
33

44
#include "core_lib.h"
55

6-
t_obj *ft_get_core_own(void);
7-
t_obj *ft_get_core_opponent(void);
8-
t_obj *ft_get_deposit_nearest(t_pos pos);
9-
t_obj *ft_get_gems_nearest(t_pos pos);
10-
t_obj *ft_get_deposit_gems_nearest(t_pos pos);
11-
t_obj *ft_get_units_opponent_nearest(t_pos pos);
12-
t_obj **ft_get_units_own(void);
13-
t_obj **ft_get_units_opponent(void);
14-
156
#endif /* BOT_H */

bots/hardcore/gridmaster/src/getters.c

Lines changed: 0 additions & 79 deletions
This file was deleted.
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
#include "bot.h"
22

3-
#include <stdio.h>
4-
#include <time.h>
5-
63
void ft_on_tick(unsigned long tick);
74

85
int main(int argc, char **argv)
96
{
107
return core_startGame("Gridmaster", argc, argv, ft_on_tick, false);
118
}
129

10+
static bool is_core_opponent(const t_obj *obj)
11+
{
12+
return (obj->type == OBJ_CORE && obj->s_core.team_id != game.my_team_id);
13+
}
14+
1315
void ft_on_tick(unsigned long tick)
1416
{
1517
(void)tick;
1618

1719
core_action_createUnit(UNIT_WARRIOR);
1820

19-
t_obj **units = ft_get_units_own();
20-
for (int i = 0; units && units[i]; i++)
21-
core_action_pathfind(units[i], ft_get_core_opponent()->pos);
22-
free(units);
21+
for (int i = 0; game.objects && game.objects[i]; i++)
22+
if (game.objects[i]->type == OBJ_UNIT && game.objects[i]->s_unit.team_id == game.my_team_id)
23+
core_action_pathfind(game.objects[i], core_get_obj_filter_nearest((t_pos){0, 0}, is_core_opponent)->pos);
2324
}

bots/hardcore/my-core-bot/inc/bot.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
#include "core_lib.h"
55

6+
typedef struct s_path
7+
{
8+
t_pos *steps;
9+
size_t length;
10+
} t_path;
11+
612
t_obj *ft_get_core_own(void);
713
t_obj *ft_get_core_opponent(void);
814
t_obj *ft_get_deposit_nearest(t_pos pos);
@@ -12,6 +18,6 @@ t_obj *ft_get_units_opponent_nearest(t_pos pos);
1218
t_obj **ft_get_units_own(void);
1319
t_obj **ft_get_units_opponent(void);
1420

15-
t_pos pathfind_next_step_dijkstra(t_pos start, t_pos target);
21+
t_path pathfind_full_path_dijkstra(t_pos start, t_pos target);
1622

1723
#endif /* BOT_H */

bots/hardcore/my-core-bot/src/main.c

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ void ft_on_tick(unsigned long tick);
44

55
int main(int argc, char **argv)
66
{
7-
return core_startGame("YOUR TEAM NAME HERE", argc, argv, ft_on_tick, false);
7+
return core_startGame("YOUR TEAM NAME HERE", argc, argv, ft_on_tick, true);
88
}
99

1010
// NOT SURE HOW TO GET STARTED?
@@ -28,9 +28,25 @@ void ft_on_tick(unsigned long tick)
2828
t_obj **own_team_warriors = core_get_objs_filter(ft_is_own_team_warrior);
2929
for (int i = 0; own_team_warriors && own_team_warriors[i]; i++)
3030
{
31-
core_action_move(own_team_warriors[i],
32-
pathfind_next_step_dijkstra(own_team_warriors[i]->pos, ft_get_core_opponent()->pos));
31+
t_path path = pathfind_full_path_dijkstra(own_team_warriors[i]->pos, ft_get_core_opponent()->pos);
32+
33+
// Add all path steps to debug visualization
34+
for (size_t j = 0; j < path.length; j++)
35+
{
36+
core_debug_addObjectPathStep(own_team_warriors[i], path.steps[j]);
37+
}
38+
39+
// Move to first step if path exists
40+
if (path.length > 0)
41+
{
42+
core_action_move(own_team_warriors[i], path.steps[0]);
43+
}
44+
45+
core_debug_addObjectInfo(own_team_warriors[i], "Moving towards opponent core :D\n");
3346
core_action_attack(own_team_warriors[i], ft_get_core_opponent());
47+
48+
// Clean up
49+
free(path.steps);
3450
}
3551
free(own_team_warriors);
3652
}

bots/hardcore/my-core-bot/src/pathfinding.c

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "bot.h"
22

3-
// pathfinding is super basic, but you can start using this if you want to
3+
// pathfinding is a basic dijkstra, but you can start using this if you want to
44

55
#include <limits.h>
66
#include <stdbool.h>
@@ -31,7 +31,6 @@ static unsigned long movement_cost_at(t_pos pos)
3131
}
3232
}
3333

34-
// ---------- HELPERS ----------
3534
static inline size_t pos_to_index(t_pos p, unsigned long grid_size)
3635
{
3736
return (size_t)p.y * (size_t)grid_size + (size_t)p.x;
@@ -55,18 +54,47 @@ static inline bool pos_in_bounds(t_pos p, unsigned long grid)
5554
return p.x < grid && p.y < grid;
5655
}
5756

58-
// ---------- MAIN: DIJKSTRA NEXT STEP ----------
57+
static t_path reconstruct_full_path(size_t *parent, size_t start_idx, size_t goal_idx, unsigned long grid)
58+
{
59+
t_path result = {.steps = NULL, .length = 0};
60+
61+
// Count path length
62+
size_t count = 0;
63+
size_t cur = goal_idx;
64+
while (cur != start_idx && parent[cur] != (size_t)(-1))
65+
{
66+
count++;
67+
cur = parent[cur];
68+
}
69+
70+
if (count == 0) return result; // was already at target position
71+
72+
result.steps = malloc(count * sizeof(t_pos));
73+
if (!result.steps) return result;
74+
result.length = count;
75+
76+
cur = goal_idx;
77+
for (size_t i = count; i > 0; i--)
78+
{
79+
result.steps[i - 1] = index_to_pos(cur, grid);
80+
cur = parent[cur];
81+
}
82+
83+
return result;
84+
}
85+
5986
// Returns the next step towards target, or start if no path found / invalid input.
60-
t_pos pathfind_next_step_dijkstra(t_pos start, t_pos target)
87+
t_path pathfind_full_path_dijkstra(t_pos start, t_pos target)
6188
{
89+
t_path empty_path = {.steps = NULL, .length = 0};
6290
const unsigned long grid = game.config.gridSize;
6391
const size_t total = (size_t)grid * (size_t)grid;
6492

65-
if (grid == 0 || !pos_in_bounds(start, grid) || !pos_in_bounds(target, grid)) return start;
93+
if (grid == 0 || !pos_in_bounds(start, grid) || !pos_in_bounds(target, grid)) return empty_path;
6694

67-
if (start.x == target.x && start.y == target.y) return start;
95+
if (start.x == target.x && start.y == target.y) return empty_path;
6896

69-
// Setup
97+
// setup arrays
7098
unsigned long *distance = malloc(total * sizeof(unsigned long));
7199
bool *visited = malloc(total * sizeof(bool));
72100
size_t *parent = malloc(total * sizeof(size_t));
@@ -75,9 +103,8 @@ t_pos pathfind_next_step_dijkstra(t_pos start, t_pos target)
75103
free(distance);
76104
free(visited);
77105
free(parent);
78-
return start;
106+
return empty_path;
79107
}
80-
81108
for (size_t i = 0; i < total; ++i)
82109
{
83110
distance[i] = ULONG_MAX;
@@ -87,10 +114,9 @@ t_pos pathfind_next_step_dijkstra(t_pos start, t_pos target)
87114

88115
const size_t start_idx = pos_to_index(start, grid);
89116
const size_t target_idx = pos_to_index(target, grid);
90-
91117
distance[start_idx] = 0;
92118

93-
// Dijkstra (naive scan for smallest distance)
119+
// Dijkstra algorithm
94120
while (true)
95121
{
96122
size_t current = (size_t)(-1);
@@ -130,8 +156,7 @@ t_pos pathfind_next_step_dijkstra(t_pos start, t_pos target)
130156
}
131157
}
132158

133-
// Decide which goal to reconstruct to:
134-
// Prefer the real target; if unreachable, choose the best adjacent tile to the target.
159+
// Determine goal (prefer target, fallback to adjacent if unreachable)
135160
size_t goal_idx = target_idx;
136161

137162
if (distance[target_idx] == ULONG_MAX)
@@ -151,35 +176,21 @@ t_pos pathfind_next_step_dijkstra(t_pos start, t_pos target)
151176
t_pos adj = {.x = (unsigned short)nx, .y = (unsigned short)ny};
152177
size_t adj_idx = pos_to_index(adj, grid);
153178

154-
// Only consider reachable tiles (distance != inf)
155179
if (distance[adj_idx] != ULONG_MAX && distance[adj_idx] < best)
156180
{
157181
best = distance[adj_idx];
158182
best_idx = adj_idx;
159183
}
160184
}
161185

162-
if (best_idx != (size_t)(-1)) goal_idx = best_idx; // walk next to target
186+
if (best_idx != (size_t)(-1)) goal_idx = best_idx;
163187
}
164188

165-
// Reconstruct ONE step from start -> goal_idx
166-
t_pos next_step = start;
167-
if (distance[goal_idx] != ULONG_MAX)
168-
{
169-
size_t cur = goal_idx;
170-
size_t prev = (size_t)(-1);
171-
172-
while (cur != start_idx && parent[cur] != (size_t)(-1))
173-
{
174-
prev = cur;
175-
cur = parent[cur];
176-
}
177-
178-
if (cur == start_idx && prev != (size_t)(-1)) next_step = index_to_pos(prev, grid);
179-
}
189+
// Reconstruct full path
190+
t_path result = reconstruct_full_path(parent, start_idx, goal_idx, grid);
180191

181192
free(distance);
182193
free(visited);
183194
free(parent);
184-
return next_step;
195+
return result;
185196
}

0 commit comments

Comments
 (0)