keep track of visited nodes to prevent infinite recursion
This commit is contained in:
@@ -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, [])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user