keep track of visited nodes to prevent infinite recursion

This commit is contained in:
2025-01-18 10:09:08 +00:00
parent f796f2f858
commit 00a9f22151

View File

@@ -132,17 +132,32 @@ struct
end end
(* new pathfinding using quad tree *) (* new pathfinding using quad tree *)
fun helpHasVisited (pos, find, visited) =
if pos = Vector.length visited then
false
else
let val cur = Vector.sub (visited, pos)
in cur = find orelse helpHasVisited (pos + 1, find, visited)
end
fun hasVisted (find, visited) =
helpHasVisited (0, Char.chr find, visited)
fun getUpwardsPath fun getUpwardsPath
(playerPlatID, currentPlatID, platforms, platformTree, dist) = (playerPlatID, currentPlatID, platforms, platformTree, dist, visited) =
if playerPlatID = currentPlatID then if playerPlatID = currentPlatID then
(dist, [currentPlatID]) (dist, [currentPlatID])
else else
let let
(* add current node to list of visited nodes *)
val chr = Char.chr currentPlatID
val visited = Vector.concat [Vector.fromList [chr], visited]
val currentPlat = Platform.find (currentPlatID, platforms) val currentPlat = Platform.find (currentPlatID, platforms)
val {x, y, width, ...} = currentPlat val {x, y, width, ...} = currentPlat
val searchY = y - Constants.jumpLimit - 1 val searchY = y - Constants.jumpLimit
val searchH = Constants.jumpLimit val searchH = Constants.jumpLimit + 1
(* todo: x/width are placeholder values. (* todo: x/width are placeholder values.
* They should define values that let reachable platforms * They should define values that let reachable platforms
@@ -166,6 +181,7 @@ struct
, currentPlat , currentPlat
, ~1 , ~1
, [] , []
, visited
) )
in in
if bestDist = ~1 then if bestDist = ~1 then
@@ -185,9 +201,23 @@ struct
, prevPlat , prevPlat
, bestDist , bestDist
, bestPath , bestPath
, visited
) = ) =
case lst of case lst of
id :: tl => id :: tl =>
if hasVisted (id, visited) then
helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, tl
, dist
, prevPlat
, bestDist
, bestPath
, visited
)
else
let let
val currentPlat = Platform.find (id, platforms) val currentPlat = Platform.find (id, platforms)
val {y = cy, ...} = currentPlat val {y = cy, ...} = currentPlat
@@ -197,7 +227,7 @@ struct
val platDist = dist + diff val platDist = dist + diff
val (newDist, newPath) = getUpwardsPath val (newDist, newPath) = getUpwardsPath
(playerPlatID, id, platforms, platformTree, platDist) (playerPlatID, id, platforms, platformTree, platDist, visited)
in in
if newDist = ~1 then if newDist = ~1 then
(* newPath is invalid, so reuse old path *) (* newPath is invalid, so reuse old path *)
@@ -210,6 +240,7 @@ struct
, prevPlat , prevPlat
, bestDist , bestDist
, bestPath , bestPath
, visited
) )
else if bestDist = ~1 then else if bestDist = ~1 then
(* bestPath is invalid *) (* bestPath is invalid *)
@@ -222,6 +253,7 @@ struct
, prevPlat , prevPlat
, newDist , newDist
, newPath , newPath
, visited
) )
else if newDist < bestDist then else if newDist < bestDist then
helpGetUpwardsPath helpGetUpwardsPath
@@ -233,6 +265,7 @@ struct
, prevPlat , prevPlat
, newDist , newDist
, newPath , newPath
, visited
) )
else else
helpGetUpwardsPath helpGetUpwardsPath
@@ -244,6 +277,7 @@ struct
, prevPlat , prevPlat
, bestDist , bestDist
, bestPath , bestPath
, visited
) )
end end
| [] => (bestDist, bestPath) | [] => (bestDist, bestPath)
@@ -309,7 +343,7 @@ struct
val (bestDist, bestPath) = val (bestDist, bestPath) =
if eID > ~1 andalso pID > ~1 then if eID > ~1 andalso pID > ~1 then
getUpwardsPath (pID, eID, platforms, platformTree, 0) getUpwardsPath (pID, eID, platforms, platformTree, 0, "")
else else
(~1, []) (~1, [])