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 = structure ValSet =
MakeBinVec MakeBinVec
(struct (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 (* l, e and q functions are not actually used in the ValSet
* because the IntSet is meant to contain keys while the ValSet * because the IntSet is meant to contain keys while the ValSet

View File

@@ -133,11 +133,11 @@ end
structure DistHeap = structure DistHeap =
MakeSkewHeap MakeSkewHeap
(struct (struct
type t = {distance: int, id: int} type t = {distance: int, id: int, comesFrom: int}
type id = int type id = int
(* default = defaultID returned when queue is empty *) (* 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 fun getID {id, distance = _} = id

View File

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