From 6783dac9e077dc2d9727c6f51e740bbab7cc4744 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Mon, 20 Jan 2025 02:38:22 +0000 Subject: [PATCH] a bit of bug fixing regarding implementation of dijstra's algorithm (next to fix: query towards quad/platform tree) --- fcore/enemy-behaviour.sml | 26 ++++++----------------- fcore/heap.sml | 12 +++++++---- fcore/path-finding.sml | 44 +++++++++++++++++---------------------- 3 files changed, 33 insertions(+), 49 deletions(-) diff --git a/fcore/enemy-behaviour.sml b/fcore/enemy-behaviour.sml index 60d6ec2..53522fb 100644 --- a/fcore/enemy-behaviour.sml +++ b/fcore/enemy-behaviour.sml @@ -31,7 +31,7 @@ struct val ey = ey + Constants.enemySize - 1 val width = Constants.enemySize - val height = 2 + val height = Platform.platHeight val ww = Constants.worldWidth val wh = Constants.worldHeight @@ -746,26 +746,12 @@ struct val eID = getPlatformBelowEnemy (enemy, platformTree, platforms) - val (bestDist, bestPath) = - if eID > ~1 andalso pID > ~1 then - getUpwardsPath (pID, eID, platforms, platformTree, 0, "") - else - (~1, []) + val _ = print "start best path:\n" - val _ = - if bestDist = ~1 then - print "no path\n" - else - let - val _ = print "has path:\n" - val _ = - List.map - (fn platID => - print ("best path platID: " ^ Int.toString platID ^ "\n")) - bestPath - in - () - end + val bestPath = PathFinding.start (pID, eID, platforms, platformTree) + val _ = List.map (fn c => print (Int.toString c ^ "\n")) bestPath + + val _ = print "finished best path\n\n" val distance = Constants.moveEnemyBy * Constants.jumpLimit diff --git a/fcore/heap.sml b/fcore/heap.sml index 03cc903..5a0d354 100644 --- a/fcore/heap.sml +++ b/fcore/heap.sml @@ -74,13 +74,17 @@ struct | insert (x, ts) = NODE (x, 0, []) :: ts - fun findMin [] = Elem.default - | findMin [t] = root t - | findMin (t :: ts) = - let val x = findMin ts + fun helpFindMin (prev, []) = root prev + | helpFindMin (prev, [t]) = root t + | helpFindMin (prev, t :: ts) = + let val x = helpFindMin (t, ts) in if Elem.leq (root t, x) then root t else x end + fun findMin [] = Elem.default + | findMin [t] = root t + | findMin (t :: ts) = helpFindMin (t, ts) + fun getMin (prevT, t) = case t of [t] => (t, []) diff --git a/fcore/path-finding.sml b/fcore/path-finding.sml index 1aae2f4..c77251c 100644 --- a/fcore/path-finding.sml +++ b/fcore/path-finding.sml @@ -249,10 +249,12 @@ struct let val acc = curID :: acc val pos = IntSet.findInsPos (curID, eKeys) + val {from, ...} = ValSet.sub (eVals, pos) val from = Char.ord from in - helpGetPathList (from, eID, eKeys, eVals, acc) + if from = curID then acc + else helpGetPathList (from, eID, eKeys, eVals, acc) end fun getPathList (pID, eID, eKeys, eVals) = @@ -262,9 +264,8 @@ struct let (* filtering duplicates because we have no decrease-key operation *) val q = filterMinDuplicates (q, eKeys) - val pidPos = IntSet.findInsPos (pID, eKeys) in - if pidPos = ~1 orelse pidPos = Vector.length eKeys then + if IntSet.contains (pID, eKeys) then (* return path if we explored pid *) getPathList (pID, eID, eKeys, eVals) else @@ -275,10 +276,6 @@ struct if minID = ~1 then (* return empty list to signify that there is no path *) [] - else if minID = pID then - (* found path to destination so reconstruct path and return - * todo: maybe delete branch? pID is not explored... *) - getPathList (pID, eID, eKeys, eVals) else (* find reachable values from min in quad tree *) let @@ -300,12 +297,14 @@ struct val state = (eVals, q) - val {x, y, width, ...} = plat - val height = Platform.platHeight - + (* calculate area to fold over quad tree *) val ww = Constants.worldWidth val wh = Constants.worldHeight + val {x, y, width, ...} = plat + val y = y - Constants.jumpLimit + val height = wh - y + (* fold over quad tree, updating any distances * we find the shortest path for *) val (eVals, q) = FindReachable.foldRegion @@ -322,24 +321,19 @@ struct val q = DistHeap.empty val q = DistHeap.insert ({distance = 0, id = eID}, q) - (* initialise explored keys and values *) + (* explored keys and values *) val eKeys = IntSet.empty val eVals = ValSet.empty - val insPos = IntSet.findInsPos (eID, eKeys) - val eKeys = IntSet.insert (eKeys, eID, insPos) - - (* important: starting node will have a key that points to itself. - * For example, if starting node is #"e", then the record will say - * the "from" field is #"e". - * This is different from the other nodes, where the "from" field - * will be the ID of the previous node which led to the current one. - * This is our terminating condition when reconstructing paths: - * If the key matching this value is the same as the "from" node, - * then we're done reconstructing the path and can return the path list. - * *) - val eVal = {distance = 0, from = Char.chr eID} - val eVals = ValSet.insert (eVals, eVal, insPos) + (* important: starting node will have a key that points to itself. + * For example, if starting node is #"e", then the record will say + * the "from" field is #"e". + * This is different from the other nodes, where the "from" field + * will be the ID of the previous node which led to the current one. + * This is our terminating condition when reconstructing paths: + * If the key matching this value is the same as the "from" node, + * then we're done reconstructing the path and can return the path list. + * *) in loop (pID, eID, platforms, platformTree, q, eKeys, eVals) end