From f3a0b2bc81868475cc764df436802531a8f4fc3b Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 31 Jan 2025 04:10:58 +0000 Subject: [PATCH] write code for new loop implementation of dijkstra's algorithm, which uses a precomputed graphy; however, this is not used yet as we need to add the graph to the game type first, and pass it along with other parameters, down to the path-finding.sml function --- fcore/path-finding.sml | 63 ++++++++++++++++++++++++++++++++++++++++++ fcore/platform.sml | 15 ++++++---- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/fcore/path-finding.sml b/fcore/path-finding.sml index 587081f..ff47dd9 100644 --- a/fcore/path-finding.sml +++ b/fcore/path-finding.sml @@ -35,6 +35,69 @@ struct fun getPathList (pID, eID, eKeys, eVals) = helpGetPathList (pID, eID, eKeys, eVals, []) + fun helpExplore (pos, graphNode, minID, distSoFar, q) = + if pos = Vector.length graphNode then + q + else + let + val {distance = newPlatDist, id = newPlatID} = + Vector.sub (graphNode, pos) + + val totalDist = newPlatDist + distSoFar + + val insRecord = + {distance = totalDist, id = newPlatID, comesFrom = minID} + val insPos = DistVec.findInsPos (insRecord, q) + val q = DistVec.insert (q, insRecord, insPos) + in + helpExplore (pos + 1, graphNode, minID, distSoFar, q) + end + + fun explore (graphNode, minID, distSoFar, q) = + helpExplore (0, graphNode, minID, distSoFar, q) + + fun loop (pID, eID, platforms, platformTree, q, eKeys, eVals, graph) = + if IntSet.contains (pID, eKeys) then + (* return path if we explored pid *) + getPathList (pID, eID, eKeys, eVals) + else + (* continue dijkstra's algorithm *) + let + (* filtering duplicates because we have no decrease-key operation *) + val q = filterMinDuplicates (q, eKeys) + in + if DistVec.isEmpty q then + (* return empty list to signify that there is no path *) + [] + else + (* find reachable values from min in quad tree *) + let + val {distance = distSoFar, id = minID, comesFrom} = + DistVec.findMin q + + (* explore platforms connected to minID *) + val platPos = Platform.findPos (minID, platforms) + val plat = Vector.sub (platforms, platPos) + val graphNode = Vector.sub (graph, platPos) + + (* on each loop, increment distSoFar by 15. + * Result: paths that require jumps to fewer platforms are + * incentivised a little bit. *) + val q = explore (graphNode, minID, distSoFar + 15, q) + + (* mark platform with (id = minID) as explored *) + val insPos = IntSet.findInsPos (minID, eKeys) + val eKeys = IntSet.insert (eKeys, minID, insPos) + val eVals = + ValSet.insert + (eVals, {distance = distSoFar, from = comesFrom}, insPos) + in + loop (pID, eID, platforms, platformTree, q, eKeys, eVals, graph) + end + end + + (* dead loop function: remove after adding graph to game type + * and moving to other loop *) fun loop (pID, eID, platforms, platformTree, q, eKeys, eVals) = if IntSet.contains (pID, eKeys) then (* return path if we explored pid *) diff --git a/fcore/platform.sml b/fcore/platform.sml index a954396..d21a7f1 100644 --- a/fcore/platform.sml +++ b/fcore/platform.sml @@ -23,19 +23,24 @@ struct , QuadTree.create (Constants.worldWidth, Constants.worldHeight) ) - fun helpFind (findNum, vec, low, high) = + fun helpFindPos (findNum, vec, low, high) = let val mid = low + ((high - low) div 2) val platform = Vector.sub (vec, mid) val {id = curNum, x = _, y = _, width = _} = platform in - if curNum = findNum then platform - else if curNum < findNum then helpFind (findNum, vec, mid + 1, high) - else helpFind (findNum, vec, low, mid - 1) + if curNum = findNum then mid + else if curNum < findNum then helpFindPos (findNum, vec, mid + 1, high) + else helpFindPos (findNum, vec, low, mid - 1) end + fun findPos (findNum, vec) = + helpFindPos (findNum, vec, 0, Vector.length vec - 1) + fun find (findNum, vec) = - helpFind (findNum, vec, 0, Vector.length vec - 1) + let val pos = findPos (findNum, vec) + in Vector.sub (vec, pos) + end fun helpGetDrawVecWider (pos, platVec, acc, winWidth, winHeight, ratio, yOffset) =