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,67 +201,85 @@ struct
, prevPlat , prevPlat
, bestDist , bestDist
, bestPath , bestPath
, visited
) = ) =
case lst of case lst of
id :: tl => id :: tl =>
let if hasVisted (id, visited) then
val currentPlat = Platform.find (id, platforms) helpGetUpwardsPath
val {y = cy, ...} = currentPlat ( playerPlatID
val {y = py, ...} = prevPlat , platforms
, platformTree
, tl
, dist
, prevPlat
, bestDist
, bestPath
, visited
)
else
let
val currentPlat = Platform.find (id, platforms)
val {y = cy, ...} = currentPlat
val {y = py, ...} = prevPlat
val diff = py - cy val diff = py - cy
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 *)
helpGetUpwardsPath helpGetUpwardsPath
( playerPlatID ( playerPlatID
, platforms , platforms
, platformTree , platformTree
, tl , tl
, dist , dist
, prevPlat , prevPlat
, bestDist , bestDist
, bestPath , bestPath
) , visited
else if bestDist = ~1 then )
(* bestPath is invalid *) else if bestDist = ~1 then
helpGetUpwardsPath (* bestPath is invalid *)
( playerPlatID helpGetUpwardsPath
, platforms ( playerPlatID
, platformTree , platforms
, tl , platformTree
, dist , tl
, prevPlat , dist
, newDist , prevPlat
, newPath , newDist
) , newPath
else if newDist < bestDist then , visited
helpGetUpwardsPath )
( playerPlatID else if newDist < bestDist then
, platforms helpGetUpwardsPath
, platformTree ( playerPlatID
, tl , platforms
, dist , platformTree
, prevPlat , tl
, newDist , dist
, newPath , prevPlat
) , newDist
else , newPath
helpGetUpwardsPath , visited
( playerPlatID )
, platforms else
, platformTree helpGetUpwardsPath
, tl ( playerPlatID
, dist , platforms
, prevPlat , platformTree
, bestDist , tl
, bestPath , dist
) , prevPlat
end , bestDist
, bestPath
, visited
)
end
| [] => (bestDist, bestPath) | [] => (bestDist, bestPath)
(* pathfinding *) (* pathfinding *)
@@ -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, [])