Pathfinding initial implementation [2 errors]
This commit is contained in:
15
src/common/utils.odin
Normal file
15
src/common/utils.odin
Normal file
@@ -0,0 +1,15 @@
|
||||
package common
|
||||
|
||||
// Generic contains function for an (dynamic) array
|
||||
list_contains :: proc(list: []$T, element: T) -> bool {
|
||||
for el in list do if el == element do return true
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Inserts element into the list after asserting that element is not already within
|
||||
insert_if_not_exists :: proc(list: ^[]$T, element: T) {
|
||||
if list_contains(list, element) do return
|
||||
|
||||
append(list, element)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import rl "vendor:raylib"
|
||||
import "core:math/rand"
|
||||
|
||||
import "common"
|
||||
import inf "infrastructure"
|
||||
@@ -99,5 +100,19 @@ delete_entity :: proc(self: ^Simulator, entity_index: u32, type: common.Entity)
|
||||
|
||||
// Returns a random node that has no cars on it
|
||||
get_free_node :: proc(self: ^Simulator) -> u32 {
|
||||
car_occupied_nodes: [dynamic]u32
|
||||
|
||||
for car in self.cars {
|
||||
node, ok := car.node_pos.?
|
||||
if !ok do continue
|
||||
|
||||
if common.list_contains(car_occupied_nodes[:], node) do continue
|
||||
append(&car_occupied_nodes, node)
|
||||
}
|
||||
|
||||
for {
|
||||
node := rand.uint32_max(u32(len(self.nodes)))
|
||||
|
||||
if !common.list_contains(car_occupied_nodes[:], node) do return node
|
||||
}
|
||||
}
|
||||
43
src/pathfinding.odin
Normal file
43
src/pathfinding.odin
Normal file
@@ -0,0 +1,43 @@
|
||||
package main
|
||||
|
||||
import "common"
|
||||
import inf "infrastructure"
|
||||
|
||||
// Returns path to destination node => road => node
|
||||
get_path_to_destination :: proc(self: ^Simulator, source: u32, destination: u32) -> []u32 {
|
||||
source_node := self.nodes[source]
|
||||
destination_node := self.nodes[destination]
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Returns if path is reachable from node => destination
|
||||
get_destination_reachable :: proc(self: ^Simulator, node_to_search: u32, destination: u32, nodes_to_ignore: ^[]u32) -> bool {
|
||||
if !self.nodes[node_to_search].enabled || common.list_contains(nodes_to_ignore[:], node_to_search) do return false
|
||||
append(nodes_to_ignore, node_to_search)
|
||||
|
||||
if node_to_search == destination do return true
|
||||
for node in get_neighbouring_nodes(self, node_to_search) {
|
||||
if get_destination_reachable(self, node, destination, nodes_to_ignore) do return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@(private="file")
|
||||
get_neighbouring_nodes :: proc(self: ^Simulator, node_index: u32) -> []u32 {
|
||||
node := self.nodes[node_index]
|
||||
neighbour_nodes := make([dynamic]u32, 0, len(node.roads))
|
||||
|
||||
for road_index in node.roads {
|
||||
road := self.roads[road_index]
|
||||
|
||||
// We pick the node that is not the original node with which we reached the node
|
||||
// But rather the other node, on the end
|
||||
next_node := road.nodes[0] == node_index ? road.nodes[1] : road.nodes[0]
|
||||
|
||||
if !common.list_contains(neighbour_nodes[:], next_node) do append(&neighbour_nodes, next_node)
|
||||
}
|
||||
|
||||
return neighbour_nodes[:]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package system
|
||||
|
||||
import inf "../infrastructure"
|
||||
|
||||
get_path_to_destination :: proc(source: u32, destination: u32, nodes: []inf.Node) {
|
||||
source_node := nodes[source]
|
||||
destination_node := nodes[destination]
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,32 +19,31 @@ Car :: struct {
|
||||
// Car's destination node
|
||||
destination: Maybe(u32),
|
||||
// Tracks on which node car has been last
|
||||
node_pos: u32,
|
||||
//
|
||||
// if null car is not on node
|
||||
node_pos: Maybe(u32),
|
||||
// if null car is not on road
|
||||
road_pos: Maybe(u32),
|
||||
// tracks absolute pos
|
||||
actual_pos: rl.Vector2,
|
||||
}
|
||||
|
||||
// Constructor
|
||||
car_init :: proc(nodes: []inf.Node) -> Car {
|
||||
rand_origin := rand.uint32_max(nodes_len)
|
||||
|
||||
car_init :: proc(node: u32, nodes: []inf.Node) -> Car {
|
||||
return {
|
||||
fuel_level = common.FUEL_MAX,
|
||||
max_speed = common.CAR_MAX_SPEED,
|
||||
origin = rand_origin,
|
||||
node_pos = rand_origin,
|
||||
actual_pos =
|
||||
origin = node,
|
||||
node_pos = node,
|
||||
actual_pos = nodes[node].pos
|
||||
}
|
||||
}
|
||||
|
||||
// Sets a (valid) route for the car
|
||||
//
|
||||
// Does NOT guarantee the route is reachable (TODO?)
|
||||
// Does NOT guarantee the route is reachable (TODO!)
|
||||
car_set_route :: proc(self: ^Car, nodes_len: u32) {
|
||||
for self.origin == self.destination {
|
||||
self.destination = rand.uint32_max(nodes_len)
|
||||
}
|
||||
|
||||
for self.origin == self.destination do self.destination = rand.uint32_max(nodes_len)
|
||||
}
|
||||
|
||||
// Updates (origin and destination) node reference
|
||||
|
||||
Reference in New Issue
Block a user