fix bug with value inserted into ValSet: before, the value inserted into the 'from' field was the ID of the current platform, but this is incorrect as it is circular. To fix, the 'from' field now contains the ID of the previous platform which this platform was found from

This commit is contained in:
2025-01-20 11:17:00 +00:00
parent 9c46e09ce4
commit 4e5219fccc
3 changed files with 28 additions and 18 deletions

View File

@@ -156,7 +156,7 @@ structure IntSet =
structure ValSet =
MakeBinVec
(struct
type elem = {distance: int, from: char}
type elem = {distance: int, from: int}
(* l, e and q functions are not actually used in the ValSet
* because the IntSet is meant to contain keys while the ValSet

View File

@@ -133,11 +133,11 @@ end
structure DistHeap =
MakeSkewHeap
(struct
type t = {distance: int, id: int}
type t = {distance: int, id: int, comesFrom: int}
type id = int
(* default = defaultID returned when queue is empty *)
val default = {distance = ~1, id = ~1}
val default = {distance = ~1, id = ~1, comesFrom = ~1}
fun getID {id, distance = _} = id

View File

@@ -112,11 +112,9 @@ struct
if dist < oldDist then
(* update values as we found a shorter path *)
let
val eVals = ValSet.updateAtIdx
( eVals
, {distance = dist, from = Char.chr fromPlatID}
, pos
)
val eVals =
ValSet.updateAtIdx
(eVals, {distance = dist, from = fromPlatID}, pos)
in
(eVals, q)
end
@@ -128,7 +126,13 @@ struct
(* key not explored, so add to queue *)
let
val q =
DistHeap.insert ({distance = dist, id = foldPlatID}, q)
DistHeap.insert
( { distance = dist
, id = foldPlatID
, comesFrom = fromPlatID
}
, q
)
in
(eVals, q)
end
@@ -136,7 +140,14 @@ struct
else
(* key not explored, so add to queue *)
let
val q = DistHeap.insert ({distance = dist, id = foldPlatID}, q)
val q =
DistHeap.insert
( { distance = dist
, id = foldPlatID
, comesFrom = fromPlatID
}
, q
)
in
(eVals, q)
end
@@ -251,10 +262,8 @@ struct
val pos = IntSet.findInsPos (curID, eKeys)
val {from, ...} = ValSet.sub (eVals, pos)
val from = Char.ord from
in
if from = curID then acc
else helpGetPathList (from, eID, eKeys, eVals, acc)
helpGetPathList (from, eID, eKeys, eVals, acc)
end
fun getPathList (pID, eID, eKeys, eVals) =
@@ -271,7 +280,7 @@ struct
else
(* continue dijkstra's algorithm *)
let
val {distance = distSoFar, id = minID} = DistHeap.findMin q
val {distance = distSoFar, id = minID, comesFrom} = DistHeap.findMin q
in
if minID = ~1 then
(* return empty list to signify that there is no path *)
@@ -285,8 +294,9 @@ struct
(* add explored *)
val insPos = IntSet.findInsPos (minID, eKeys)
val eKeys = IntSet.insert (eKeys, minID, insPos)
val eVals = ValSet.insert
(eVals, {distance = distSoFar, from = Char.chr minID}, insPos)
val eVals =
ValSet.insert
(eVals, {distance = distSoFar, from = comesFrom}, insPos)
val env =
{ platforms = platforms
@@ -308,7 +318,7 @@ struct
(* fold over quad tree, updating any distances
* we find the shortest path for *)
val (eVals, q) = FindReachable.foldRegion
(x, y, width, height, 0, 0, ww, wh, env, state, platformTree)
(0, 0, ww, wh, 0, 0, ww, wh, env, state, platformTree)
in
loop (pID, eID, platforms, platformTree, q, eKeys, eVals)
end
@@ -319,7 +329,7 @@ struct
let
(* initialise data structures: the priority queue and the explored map *)
val q = DistHeap.empty
val q = DistHeap.insert ({distance = 0, id = eID}, q)
val q = DistHeap.insert ({distance = 0, id = eID, comesFrom = eID}, q)
(* explored keys and values *)
val eKeys = IntSet.empty