pathfinding with bfs
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
Path :: struct {
|
||||
tiles: []Tile_Coord,
|
||||
count: int,
|
||||
}
|
||||
|
||||
path_clear :: proc(path: ^Path) {
|
||||
delete(path.tiles)
|
||||
path.tiles = nil
|
||||
path.count = 0
|
||||
}
|
||||
|
||||
pathfind_bfs :: proc(tilemap: ^Tilemap, start, goal: Tile_Coord, path: ^Path) -> bool {
|
||||
path_clear(path)
|
||||
|
||||
if start == goal {
|
||||
path.tiles[0] = start
|
||||
path.count = 1
|
||||
return true
|
||||
}
|
||||
|
||||
w, h := tilemap.width, tilemap.height
|
||||
|
||||
parents: [MAP_HEIGHT][MAP_WIDTH]Tile_Coord
|
||||
visited: [MAP_HEIGHT][MAP_WIDTH]bool
|
||||
|
||||
found := false
|
||||
|
||||
for y in 0 ..< h {
|
||||
for x in 0 ..< w {
|
||||
parents[y][x] = {-1, -1}
|
||||
}
|
||||
}
|
||||
|
||||
queue: [MAP_WIDTH * MAP_HEIGHT]Tile_Coord
|
||||
head, tail: int = 0, 0
|
||||
|
||||
queue[tail] = start; tail += 1
|
||||
visited[start.y][start.x] = true
|
||||
parents[start.y][start.x] = start
|
||||
|
||||
for head < tail {
|
||||
current := queue[head]; head += 1
|
||||
|
||||
if current == goal {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
||||
for offset in NEIGHBOR_OFFSET {
|
||||
nx := current.x + offset.x
|
||||
ny := current.y + offset.y
|
||||
if !tile_in_bounds(tilemap, nx, ny) ||
|
||||
visited[ny][nx] ||
|
||||
!tile_walkable(tilemap, nx, ny) {
|
||||
continue
|
||||
}
|
||||
|
||||
visited[ny][nx] = true
|
||||
parents[ny][nx] = current
|
||||
queue[tail] = {nx, ny}
|
||||
tail += 1
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
|
||||
rev: [MAX_PATH]Tile_Coord
|
||||
rev_count := 0
|
||||
cur := goal
|
||||
for {
|
||||
rev[rev_count] = cur
|
||||
rev_count += 1
|
||||
if cur == start {
|
||||
break
|
||||
}
|
||||
cur = parents[cur.y][cur.x]
|
||||
if rev_count >= MAX_PATH {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
path.tiles = make([]Tile_Coord, rev_count)
|
||||
path.count = rev_count
|
||||
for i in 0 ..< rev_count {
|
||||
path.tiles[i] = rev[rev_count - 1 - i]
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user