I am recreating an old family favorite board game in Godot (Rail Baron). You roll dice and then move that far along railroads (edges) from stop to stop (vertices). essentially it's "exercises in graph theory: the game".
The function I've written to find all vertices k moves away from a given node (giving the legal moves after a die roll) doesn't work because if a node has been visited before, the function won't recur on that node, meaning each node can only be traveled once while looking for all paths. I know I could just ignore the requirement that nodes only be traversed once per path, but that would become very computationally expensive as I would be generating many possible routes that no human would ever take - and it's also against the game rules (your train has to continue in the same direction as long as it's on one railroad).
Can I have my cake and eat it too?
Here's a pdf of the game board to help visualize the graph https://www.railgamefans.com/rbp/files/u21sm.pdf
and here is my pathfinding function. My graph is represented as an adjacency list.
var visited = []
func get_move_options(i, stop):
var counter = i
visited.append(stop)
while counter > 0:
counter -= 1
for neighbor in adjList[stop]:
if not neighbor.name in visited:
get_move_options(counter, neighbor.name)
var stopNodeHighlight = get_parent().get_node(stop).get_node('Highlight')
if stopNodeHighlight:
stopNodeHighlight.visible = true
Instead of the visited array/list have a 'parent' parameter the node from witch you came from. Then simply check if neighbor.name != parent
If you are on a node where you can turn back freely (If you can turn right back on crossroads) you can set parent
to something invalid.
func get_move_options(i, stop,parent):
var counter = i
if ... : (you can turn back from here (train is not on rail? you can put i>2 to check if we are on a crossroad))
parent="Something unrealistic like null or this stupid string"
while counter > 0:
counter -= 1
for neighbor in adjList[stop]:
if not neighbor.name != parent:
get_move_options(counter, neighbor.name,stop)
var stopNodeHighlight = get_parent().get_node(stop).get_node('Highlight')
if stopNodeHighlight:
stopNodeHighlight.visible = true
Note: If I made a syntax error sorry I don't know the language