From 4e5219fcccf9121de171c7dd8d12ff28889b8584 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Mon, 20 Jan 2025 11:17:00 +0000 Subject: [PATCH] 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 --- fcore/bin-vec.sml | 2 +- fcore/heap.sml | 4 ++-- fcore/path-finding.sml | 40 +++++++++++++++++++++++++--------------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/fcore/bin-vec.sml b/fcore/bin-vec.sml index ddee6e8..b3f6925 100644 --- a/fcore/bin-vec.sml +++ b/fcore/bin-vec.sml @@ -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 diff --git a/fcore/heap.sml b/fcore/heap.sml index 5a0d354..917a770 100644 --- a/fcore/heap.sml +++ b/fcore/heap.sml @@ -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 diff --git a/fcore/path-finding.sml b/fcore/path-finding.sml index c77251c..525ed73 100644 --- a/fcore/path-finding.sml +++ b/fcore/path-finding.sml @@ -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