Skip to content

Commit

Permalink
- batch search to fit in one frame
Browse files Browse the repository at this point in the history
  • Loading branch information
gnysek committed Aug 8, 2023
1 parent a0daa50 commit 8866754
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 8 deletions.
1 change: 1 addition & 0 deletions grafy.resource_order
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{"name":"vertex","order":1,"path":"scripts/vertex/vertex.yy",},
{"name":"connect_points","order":3,"path":"scripts/connect_points/connect_points.yy",},
{"name":"spr_line","order":1,"path":"sprites/spr_line/spr_line.yy",},
{"name":"search","order":2,"path":"scripts/search/search.yy",},
{"name":"graph_save","order":1,"path":"scripts/graph_save/graph_save.yy",},
{"name":"obj_editor","order":2,"path":"objects/obj_editor/obj_editor.yy",},
],
Expand Down
1 change: 1 addition & 0 deletions grafy.yyp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions objects/obj_editor/Create_0.gml
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@
graph_save(global.my_graph);
}

test_search = new search(global.my_graph, "A", "R", 1);


4 changes: 4 additions & 0 deletions objects/obj_editor/KeyPress_32.gml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

test_search.pass();

show_debug_message(test_search.result());
1 change: 1 addition & 0 deletions objects/obj_editor/obj_editor.yy

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 5 additions & 8 deletions scripts/graph/graph.gml
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,14 @@ function graph() constructor {
var smallest = undefined; // get node letter
while (!ds_priority_empty(nodes)) {
smallest = ds_priority_find_min(nodes);
ds_priority_delete_min(nodes);

graph_debug($"... traversing {smallest}");

if (smallest == _end) {
break;
// ends
}


ds_priority_delete_min(nodes);

graph_debug($"... traversing {smallest}");

if (smallest == undefined or dist[? smallest] == infinity) {
continue;
Expand All @@ -117,6 +116,7 @@ function graph() constructor {
// iterate over all neighbor vertices for this vertice
for(var i = 0, n = array_length(_vertex_keys); i < n; i++) {
neighbor = _vertex_keys[i];
graph_debug($"... >> {neighbor}");

len = dist[? smallest] + self.vertices[? smallest].connections[$ neighbor];

Expand All @@ -139,8 +139,6 @@ function graph() constructor {
array_insert(path, 1, smallest);
smallest = prev[? smallest];
}



for (var i = 1, n = array_length(path); i < n; i++) {
distance += self.vertices[? path[i-1]].connections[$ path[i]];
Expand All @@ -155,7 +153,6 @@ function graph() constructor {
ds_map_destroy(prev);
ds_priority_destroy(nodes);


//return
return {
path,
Expand Down
132 changes: 132 additions & 0 deletions scripts/search/search.gml
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
// example #1
test_search = new search(global.my_graph, "A", "C");
test_search.pass(); // will serach everything, as _max_passes = infinity
// example #2
test_search = new search(global.my_graph, "A", "C", 1);
// step event
var _s = test_search.pass();
if (_s) {
show_debug_message(_s.result());
}
*/


/// @param {Struct.graph} _graph
/// @param {String} _start
/// @param {String} _end
/// @param {Real} _max_passes
function search(_graph, _start, _end, _max_passes = infinity) constructor {
found = false;

keys = ds_map_keys_to_array(_graph.vertices);
dist = ds_map_create();
prev = ds_map_create();
nodes = ds_priority_create();
smallest = undefined;
where = _graph;
where_start = _start;
where_end = _end;

path = [];
distance = [];

for (var i = 0, n = array_length(keys); i < n; i++) {
if (keys[i] == where_start) {
// it's this node, so distance to it is 0 :)
dist[? keys[i]] = 0;
} else {
dist[? keys[i]] = infinity;
}
ds_priority_add(nodes, keys[i], dist[? keys[i]]);
prev[? keys[i]] = undefined;
}

nodes_visited_in_current_pass = 0;
nodes_visit_limit = max(_max_passes, 1);

graph_debug($"new search from {where_start} to {where_end}...");

static pass = function() {

if (found) return true;

nodes_visited_in_current_pass = 0;

while (!ds_priority_empty(nodes)) {
smallest = ds_priority_find_min(nodes);
if (smallest == where_end) {
found = true;

// now prepare results
path = [];
distance = 0;
path = [where_start];

while(prev[? smallest] != undefined) {
array_insert(path, 1, smallest);
smallest = prev[? smallest];
}

for (var i = 1, n = array_length(path); i < n; i++) {
distance += where.vertices[? path[i-1]].connections[$ path[i]];
}

graph_debug($"Found way with distance {distance} trough {path}.");

// cleanup
// don't forget about cleanup
ds_map_destroy(dist);
ds_map_destroy(prev);
ds_priority_destroy(nodes);

break;
// ends
}

ds_priority_delete_min(nodes);

graph_debug($"... traversing {smallest}");

if (smallest == undefined or dist[? smallest] == infinity) {
continue;
}

var _vertex_keys = where.vertices[? smallest].keys;
var neighbor = undefined, len = infinity;
// iterate over all neighbor vertices for this vertice
for(var i = 0, n = array_length(_vertex_keys); i < n; i++) {
neighbor = _vertex_keys[i];
graph_debug($"... >> {neighbor}");

len = dist[? smallest] + where.vertices[? smallest].connections[$ neighbor];

if(len < dist[? neighbor]) {
dist[? neighbor] = len;
prev[? neighbor] = smallest;

ds_priority_add(nodes, neighbor, len);
}
}

nodes_visited_in_current_pass++;
if (nodes_visited_in_current_pass >= nodes_visit_limit) {
break;
}
}

return found;
}

static result = function() {
return {
found,
path,
distance,
};
}
}
11 changes: 11 additions & 0 deletions scripts/search/search.yy

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8866754

Please sign in to comment.