module Game.LambdaHack.Point
( Point, toPoint, showPoint
, origin, chessDist, adjacent, vicinity, vicinityCardinal
, inside, displacementXYZ, bla
) where
import qualified Data.List as L
import Game.LambdaHack.PointXY
import Game.LambdaHack.VectorXY
import Game.LambdaHack.Area
import Game.LambdaHack.Utils.Assert
type Point = Int
showPoint :: X -> Point -> String
showPoint lxsize = show . fromPoint lxsize
toPoint :: X -> PointXY -> Point
toPoint lxsize (PointXY (x, y)) =
assert (lxsize > x && x >= 0 && y >= 0 `blame` (lxsize, x, y)) $
x + y * lxsize
fromPoint :: X -> Point -> PointXY
fromPoint lxsize loc =
assert (loc >= 0 `blame` (lxsize, loc)) $
PointXY (loc `rem` lxsize, loc `quot` lxsize)
origin :: Point
origin = 0
chessDist :: X -> Point -> Point -> Int
chessDist lxsize loc0 loc1
| PointXY (x0, y0) <- fromPoint lxsize loc0
, PointXY (x1, y1) <- fromPoint lxsize loc1 =
chessDistXY $ VectorXY (x1 x0, y1 y0)
adjacent :: X -> Point -> Point -> Bool
adjacent lxsize s t = chessDist lxsize s t == 1
vicinity :: X -> Y -> Point -> [Point]
vicinity lxsize lysize loc =
map (toPoint lxsize) $
vicinityXY (0, 0, lxsize 1, lysize 1) $
fromPoint lxsize loc
vicinityCardinal :: X -> Y -> Point -> [Point]
vicinityCardinal lxsize lysize loc =
map (toPoint lxsize) $
vicinityCardinalXY (0, 0, lxsize 1, lysize 1) $
fromPoint lxsize loc
inside :: X -> Point -> Area -> Bool
inside lxsize loc = insideXY $ fromPoint lxsize loc
displacementXYZ :: X -> Point -> Point -> VectorXY
displacementXYZ lxsize loc0 loc1
| PointXY (x0, y0) <- fromPoint lxsize loc0
, PointXY (x1, y1) <- fromPoint lxsize loc1 =
VectorXY (x1 x0, y1 y0)
bla :: X -> Y -> Int -> Point -> Point -> Maybe [Point]
bla _ _ _ source target | source == target = Nothing
bla lxsize lysize eps source target = Just $
let s = fromPoint lxsize source
e = fromPoint lxsize target
inBounds p@(PointXY (x, y)) =
lxsize > x && x >= 0 && lysize > y && y >= 0 && p /= s
in L.map (toPoint lxsize) $ L.takeWhile inBounds $ L.tail $ blaXY eps s e