rip out print statements which were solely for debugging
This commit is contained in:
@@ -740,18 +740,12 @@ struct
|
|||||||
|
|
||||||
fun canJumpOnPlatform (player, platforms, enemy: enemy, platformTree) =
|
fun canJumpOnPlatform (player, platforms, enemy: enemy, platformTree) =
|
||||||
let
|
let
|
||||||
|
(* todo: possibly get pID and eID of player/enemy in a different way *)
|
||||||
val pID = getPlatformBelowPlayer (player, platformTree, platforms)
|
val pID = getPlatformBelowPlayer (player, platformTree, platforms)
|
||||||
|
|
||||||
val {x, y, ...} = enemy
|
val {x, y, ...} = enemy
|
||||||
|
|
||||||
val eID = getPlatformBelowEnemy (enemy, platformTree, platforms)
|
val eID = getPlatformBelowEnemy (enemy, platformTree, platforms)
|
||||||
|
|
||||||
val _ = print "start best path:\n"
|
|
||||||
|
|
||||||
val bestPath = PathFinding.start (pID, eID, platforms, platformTree)
|
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
|
val distance = Constants.moveEnemyBy * Constants.jumpLimit
|
||||||
|
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ struct
|
|||||||
val plat3 = {id = 3, x = 355, y = 659, width = 555}
|
val plat3 = {id = 3, x = 355, y = 659, width = 555}
|
||||||
val plat4 = {id = 4, x = 155, y = 855, width = 199}
|
val plat4 = {id = 4, x = 155, y = 855, width = 199}
|
||||||
val plat5 = {id = 5, x = 155, y = 759, width = 199}
|
val plat5 = {id = 5, x = 155, y = 759, width = 199}
|
||||||
val plat6 = {id = 6, x = 155, y = 610, width = 199}
|
val plat6 = {id = 6, x = 155, y = 710, width = 199}
|
||||||
val platforms = Vector.fromList [plat1, plat2, plat3, plat4, plat5, plat6]
|
val platforms = Vector.fromList [plat1, plat2, plat3, plat4, plat5, plat6]
|
||||||
val platformTree = Platform.generateTree platforms
|
val platformTree = Platform.generateTree platforms
|
||||||
|
|
||||||
|
|||||||
@@ -2,241 +2,231 @@ structure PathFinding =
|
|||||||
struct
|
struct
|
||||||
(* functor for adding reachable platforms to queue *)
|
(* functor for adding reachable platforms to queue *)
|
||||||
structure FindReachable =
|
structure FindReachable =
|
||||||
struct
|
struct
|
||||||
open GameType
|
open GameType
|
||||||
|
|
||||||
type env =
|
type env =
|
||||||
{ platforms: GameType.platform vector
|
{ platforms: GameType.platform vector
|
||||||
, currentPlat: GameType.platform
|
, currentPlat: GameType.platform
|
||||||
, eKeys: IntSet.elem vector
|
, eKeys: IntSet.elem vector
|
||||||
, distSoFar: int
|
, distSoFar: int
|
||||||
}
|
}
|
||||||
|
|
||||||
type state = ValSet.elem vector * DistHeap.t
|
type state = ValSet.elem vector * DistHeap.t
|
||||||
|
|
||||||
fun isBetween (p1, check, p2) = check >= p1 andalso check <= p2
|
fun isBetween (p1, check, p2) = check >= p1 andalso check <= p2
|
||||||
|
|
||||||
fun canJumpUpTo (prevPlat: platform, currentPlat: platform) =
|
fun canJumpUpTo (prevPlat: platform, currentPlat: platform) =
|
||||||
let
|
let
|
||||||
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
||||||
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
||||||
|
|
||||||
val prevFinishX = prevX + prevWidth
|
val prevFinishX = prevX + prevWidth
|
||||||
val curFinishX = curX + curWidth
|
val curFinishX = curX + curWidth
|
||||||
in
|
in
|
||||||
(isBetween (prevX, curX, prevFinishX)
|
(isBetween (prevX, curX, prevFinishX)
|
||||||
orelse
|
orelse
|
||||||
isBetween (prevX, curFinishX, prevFinishX)
|
isBetween (prevX, curFinishX, prevFinishX) andalso prevY + 155 >= curY)
|
||||||
andalso prevY + 155 >= curY)
|
end
|
||||||
end
|
|
||||||
|
|
||||||
fun canDropDownTo (prevPlat: platform, currentPlat: platform) =
|
fun canDropDownTo (prevPlat: platform, currentPlat: platform) =
|
||||||
let
|
let
|
||||||
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
||||||
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
||||||
|
|
||||||
val prevFinishX = prevX + prevWidth
|
val prevFinishX = prevX + prevWidth
|
||||||
val curFinishX = curX + curWidth
|
val curFinishX = curX + curWidth
|
||||||
in
|
in
|
||||||
(isBetween (prevX, curX, prevFinishX)
|
(isBetween (prevX, curX, prevFinishX)
|
||||||
orelse
|
orelse isBetween (prevX, curFinishX, prevFinishX) andalso prevY <= curY)
|
||||||
isBetween (prevX, curFinishX, prevFinishX) andalso prevY <= curY)
|
end
|
||||||
end
|
|
||||||
|
|
||||||
fun isReachableFromLeft (prevPlat, currentPlat) =
|
fun isReachableFromLeft (prevPlat, currentPlat) =
|
||||||
(* prev = right/from, current = left/to *)
|
(* prev = right/from, current = left/to *)
|
||||||
let
|
let
|
||||||
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
||||||
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
||||||
|
|
||||||
val enemyX = prevX
|
val enemyX = prevX
|
||||||
val xDiff = prevX - curX
|
val xDiff = prevX - curX
|
||||||
in
|
in
|
||||||
if xDiff <= Constants.jumpLimit then
|
if xDiff <= Constants.jumpLimit then
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val enemyApexX = enemyX - Constants.jumpLimit
|
val enemyApexX = enemyX - Constants.jumpLimit
|
||||||
val enemyApexY = prevY + Constants.jumpLimit
|
val enemyApexY = prevY + Constants.jumpLimit
|
||||||
|
|
||||||
val curFinishX = curX + curWidth
|
val curFinishX = curX + curWidth
|
||||||
|
|
||||||
val diffApexY = enemyApexY - curY
|
val diffApexY = enemyApexY - curY
|
||||||
val diffApexX = enemyApexX - curFinishX
|
val diffApexX = enemyApexX - curFinishX
|
||||||
in
|
in
|
||||||
diffApexX <= diffApexY orelse diffApexY <= 0
|
diffApexX <= diffApexY orelse diffApexY <= 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fun isReachableFromRight (prevPlat, currentPlat) =
|
fun isReachableFromRight (prevPlat, currentPlat) =
|
||||||
(* prev = left/from, current = right/to *)
|
(* prev = left/from, current = right/to *)
|
||||||
let
|
let
|
||||||
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
val {x = prevX, y = prevY, width = prevWidth, ...} = prevPlat
|
||||||
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
val {x = curX, y = curY, width = curWidth, ...} = currentPlat
|
||||||
|
|
||||||
(* last x coordinate where enemy can fully fit on prevPlat *)
|
(* last x coordinate where enemy can fully fit on prevPlat *)
|
||||||
val enemyX = prevX + prevWidth - Constants.enemySize
|
val enemyX = prevX + prevWidth - Constants.enemySize
|
||||||
|
|
||||||
val xDiff = curX - prevX
|
val xDiff = curX - prevX
|
||||||
in
|
in
|
||||||
if xDiff <= Constants.jumpLimit then
|
if xDiff <= Constants.jumpLimit then
|
||||||
(* platform is possible to jump to without falling *)
|
(* platform is possible to jump to without falling *)
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
val enemyApexX = enemyX + Constants.jumpLimit
|
val enemyApexX = enemyX + Constants.jumpLimit
|
||||||
val enemyApexY = prevY + Constants.jumpLimit
|
val enemyApexY = prevY + Constants.jumpLimit
|
||||||
|
|
||||||
val diffApexY = enemyApexY - curY
|
val diffApexY = enemyApexY - curY
|
||||||
val diffApexX = enemyApexX - curX
|
val diffApexX = enemyApexX - curX
|
||||||
in
|
in
|
||||||
diffApexY <= 0 orelse diffApexX <= diffApexY
|
diffApexY <= 0 orelse diffApexX <= diffApexY
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fun insertIfNotExistsOrShorter
|
fun insertIfNotExistsOrShorter
|
||||||
(dist, eKeys, eVals, foldPlatID, q, fromPlatID) =
|
(dist, eKeys, eVals, foldPlatID, q, fromPlatID) =
|
||||||
let
|
let
|
||||||
val pos = IntSet.findInsPos (foldPlatID, eKeys)
|
val pos = IntSet.findInsPos (foldPlatID, eKeys)
|
||||||
in
|
in
|
||||||
if pos <> ~1 andalso pos <> Vector.length eKeys then
|
if pos <> ~1 andalso pos <> Vector.length eKeys then
|
||||||
let
|
let
|
||||||
val key = IntSet.sub (eKeys, pos)
|
val key = IntSet.sub (eKeys, pos)
|
||||||
in
|
in
|
||||||
if pos = key then
|
if pos = key then
|
||||||
(* may need to update record in eVals if it is shorter *)
|
(* may need to update record in eVals if it is shorter *)
|
||||||
let
|
let
|
||||||
val {distance = oldDist, ...} = ValSet.sub (eVals, pos)
|
val {distance = oldDist, ...} = ValSet.sub (eVals, pos)
|
||||||
in
|
in
|
||||||
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 =
|
val eVals =
|
||||||
ValSet.updateAtIdx
|
ValSet.updateAtIdx
|
||||||
(eVals, {distance = dist, from = fromPlatID}, pos)
|
(eVals, {distance = dist, from = fromPlatID}, pos)
|
||||||
in
|
in
|
||||||
(eVals, q)
|
(eVals, q)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(* return existing *)
|
(* return existing *)
|
||||||
(eVals, q)
|
(eVals, q)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(* key not explored, so add to queue *)
|
(* key not explored, so add to queue *)
|
||||||
let
|
let
|
||||||
val q =
|
val q =
|
||||||
DistHeap.insert
|
DistHeap.insert
|
||||||
( { distance = dist
|
( {distance = dist, id = foldPlatID, comesFrom = fromPlatID}
|
||||||
, id = foldPlatID
|
, q
|
||||||
, comesFrom = fromPlatID
|
)
|
||||||
}
|
in
|
||||||
, q
|
(eVals, q)
|
||||||
)
|
end
|
||||||
in
|
end
|
||||||
(eVals, q)
|
else
|
||||||
end
|
(* key not explored, so add to queue *)
|
||||||
end
|
let
|
||||||
else
|
val q =
|
||||||
(* key not explored, so add to queue *)
|
DistHeap.insert
|
||||||
let
|
({distance = dist, id = foldPlatID, comesFrom = fromPlatID}, q)
|
||||||
val q =
|
in
|
||||||
DistHeap.insert
|
(eVals, q)
|
||||||
( { distance = dist
|
end
|
||||||
, id = foldPlatID
|
end
|
||||||
, comesFrom = fromPlatID
|
|
||||||
}
|
|
||||||
, q
|
|
||||||
)
|
|
||||||
in
|
|
||||||
(eVals, q)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
fun fState ((eVals, q), env, foldPlatID) =
|
fun fState ((eVals, q), env, foldPlatID) =
|
||||||
let
|
let
|
||||||
val {platforms, currentPlat, eKeys, distSoFar} = env
|
val {platforms, currentPlat, eKeys, distSoFar} = env
|
||||||
val curPlatID = #id currentPlat
|
val curPlatID = #id currentPlat
|
||||||
val foldPlat = Platform.find (foldPlatID, platforms)
|
val foldPlat = Platform.find (foldPlatID, platforms)
|
||||||
in
|
in
|
||||||
if
|
if
|
||||||
canJumpUpTo (currentPlat, foldPlat)
|
canJumpUpTo (currentPlat, foldPlat)
|
||||||
orelse canDropDownTo (currentPlat, foldPlat)
|
orelse canDropDownTo (currentPlat, foldPlat)
|
||||||
then
|
then
|
||||||
let
|
let
|
||||||
(* only need to calculate vertical distance *)
|
(* only need to calculate vertical distance *)
|
||||||
val {y = py, ...} = currentPlat
|
val {y = py, ...} = currentPlat
|
||||||
val {y = cy, ...} = foldPlat
|
val {y = cy, ...} = foldPlat
|
||||||
val dist = abs (py - cy)
|
val dist = abs (py - cy)
|
||||||
val dist = dist + distSoFar
|
val dist = dist + distSoFar
|
||||||
in
|
in
|
||||||
insertIfNotExistsOrShorter
|
insertIfNotExistsOrShorter
|
||||||
(dist, eKeys, eVals, foldPlatID, q, curPlatID)
|
(dist, eKeys, eVals, foldPlatID, q, curPlatID)
|
||||||
end
|
end
|
||||||
else if
|
else if
|
||||||
isReachableFromLeft (currentPlat, foldPlat)
|
isReachableFromLeft (currentPlat, foldPlat)
|
||||||
orelse isReachableFromRight (currentPlat, foldPlat)
|
orelse isReachableFromRight (currentPlat, foldPlat)
|
||||||
then
|
then
|
||||||
let
|
let
|
||||||
val {x = px, y = py, width = pw, ...} = currentPlat
|
val {x = px, y = py, width = pw, ...} = currentPlat
|
||||||
val {x = cx, y = cy, width = cw, ...} = foldPlat
|
val {x = cx, y = cy, width = cw, ...} = foldPlat
|
||||||
|
|
||||||
val pFinishX = px + pw
|
val pFinishX = px + pw
|
||||||
val cFinishX = cx + cw
|
val cFinishX = cx + cw
|
||||||
|
|
||||||
val dist =
|
val dist =
|
||||||
if py = cy then
|
if py = cy then
|
||||||
let
|
let
|
||||||
(* if on same y coordinate,
|
(* if on same y coordinate,
|
||||||
* only need to calculate horizontal distance *)
|
* only need to calculate horizontal distance *)
|
||||||
val d1 = abs (px - cx)
|
val d1 = abs (px - cx)
|
||||||
val d2 = abs (px - cFinishX)
|
val d2 = abs (px - cFinishX)
|
||||||
val d3 = abs (pFinishX - cx)
|
val d3 = abs (pFinishX - cx)
|
||||||
val d4 = abs (pFinishX - cFinishX)
|
val d4 = abs (pFinishX - cFinishX)
|
||||||
|
|
||||||
val min = Int.min (d1, d2)
|
val min = Int.min (d1, d2)
|
||||||
val min = Int.min (min, d3)
|
val min = Int.min (min, d3)
|
||||||
in
|
in
|
||||||
Int.min (min, d4)
|
Int.min (min, d4)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
(* if they have different y coordinate,
|
(* if they have different y coordinate,
|
||||||
* need to calculate diagonal length/hypotenuse by pythagoras
|
* need to calculate diagonal length/hypotenuse by pythagoras
|
||||||
* *)
|
* *)
|
||||||
val x1 = abs (px - cx)
|
val x1 = abs (px - cx)
|
||||||
val x2 = abs (px - cFinishX)
|
val x2 = abs (px - cFinishX)
|
||||||
val x3 = abs (pFinishX - cx)
|
val x3 = abs (pFinishX - cx)
|
||||||
val x4 = abs (pFinishX - cFinishX)
|
val x4 = abs (pFinishX - cFinishX)
|
||||||
|
|
||||||
val x = Int.min (x1, x2)
|
val x = Int.min (x1, x2)
|
||||||
val x = Int.min (x, x3)
|
val x = Int.min (x, x3)
|
||||||
val x = Int.min (x, x4)
|
val x = Int.min (x, x4)
|
||||||
|
|
||||||
(* there is only one y coordinate for platform
|
(* there is only one y coordinate for platform
|
||||||
* so don't need to 'minimise' it
|
* so don't need to 'minimise' it
|
||||||
* *)
|
* *)
|
||||||
val y = abs (py - cy)
|
val y = abs (py - cy)
|
||||||
|
|
||||||
(* pythagoras *)
|
(* pythagoras *)
|
||||||
val xsq = x * x
|
val xsq = x * x
|
||||||
val ysq = y * y
|
val ysq = y * y
|
||||||
val hypsq = xsq + ysq
|
val hypsq = xsq + ysq
|
||||||
|
|
||||||
(* square root to find diagonal length *)
|
(* square root to find diagonal length *)
|
||||||
val dg = Real.fromInt hypsq
|
val dg = Real.fromInt hypsq
|
||||||
val dg = Math.sqrt dg
|
val dg = Math.sqrt dg
|
||||||
in
|
in
|
||||||
Real.toInt IEEEReal.TO_NEAREST dg
|
Real.toInt IEEEReal.TO_NEAREST dg
|
||||||
end
|
end
|
||||||
val dist = dist + distSoFar
|
val dist = dist + distSoFar
|
||||||
in
|
in
|
||||||
insertIfNotExistsOrShorter
|
insertIfNotExistsOrShorter
|
||||||
(dist, eKeys, eVals, foldPlatID, q, curPlatID)
|
(dist, eKeys, eVals, foldPlatID, q, curPlatID)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
(eVals, q)
|
(eVals, q)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
fun filterMinDuplicates (q, eKeys) =
|
fun filterMinDuplicates (q, eKeys) =
|
||||||
let
|
let
|
||||||
@@ -262,7 +252,6 @@ struct
|
|||||||
val pos = IntSet.findInsPos (curID, eKeys)
|
val pos = IntSet.findInsPos (curID, eKeys)
|
||||||
|
|
||||||
val {from, distance, ...} = ValSet.sub (eVals, pos)
|
val {from, distance, ...} = ValSet.sub (eVals, pos)
|
||||||
val _ = print ("266 distance = " ^ Int.toString distance ^ "\n")
|
|
||||||
in
|
in
|
||||||
helpGetPathList (from, eID, eKeys, eVals, acc)
|
helpGetPathList (from, eID, eKeys, eVals, acc)
|
||||||
end
|
end
|
||||||
@@ -271,19 +260,20 @@ struct
|
|||||||
helpGetPathList (pID, eID, eKeys, eVals, [])
|
helpGetPathList (pID, eID, eKeys, eVals, [])
|
||||||
|
|
||||||
fun addPlatforms (pos, (eVals, q), env) =
|
fun addPlatforms (pos, (eVals, q), env) =
|
||||||
let
|
let
|
||||||
val {platforms, ...} = env
|
val {platforms, ...} = env
|
||||||
in
|
in
|
||||||
if pos = Vector.length platforms then (eVals, q)
|
if pos = Vector.length platforms then
|
||||||
else
|
(eVals, q)
|
||||||
let
|
else
|
||||||
val foldPlat = Vector.sub (platforms, pos)
|
let
|
||||||
val foldPlatID = #id foldPlat
|
val foldPlat = Vector.sub (platforms, pos)
|
||||||
val (eVals, q) = FindReachable.fState ((eVals, q), env, foldPlatID)
|
val foldPlatID = #id foldPlat
|
||||||
in
|
val (eVals, q) = FindReachable.fState ((eVals, q), env, foldPlatID)
|
||||||
addPlatforms (pos + 1, (eVals, q), env)
|
in
|
||||||
end
|
addPlatforms (pos + 1, (eVals, q), env)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
fun loop (pID, eID, platforms, platformTree, q, eKeys, eVals) =
|
fun loop (pID, eID, platforms, platformTree, q, eKeys, eVals) =
|
||||||
let
|
let
|
||||||
|
|||||||
Reference in New Issue
Block a user