module Game.LambdaHack.Area
( Area, vicinityXY, vicinityCardinalXY, insideXY
, normalizeArea, grid, validArea, trivialArea, expand
) where
import Game.LambdaHack.PointXY
import Game.LambdaHack.VectorXY
type Area = (X, Y, X, Y)
vicinityXY :: Area
-> PointXY
-> [PointXY]
vicinityXY area xy =
[ res | dxy <- movesXY, let res = shiftXY xy dxy, insideXY res area ]
vicinityCardinalXY :: Area
-> PointXY
-> [PointXY]
vicinityCardinalXY area xy =
[ res
| dxy <- movesCardinalXY, let res = shiftXY xy dxy, insideXY res area ]
insideXY :: PointXY -> Area -> Bool
insideXY (PointXY (x, y)) (x0, y0, x1, y1) =
x1 >= x && x >= x0 && y1 >= y && y >= y0
normalizeArea :: Area -> Area
normalizeArea (x0, y0, x1, y1) = (min x0 x1, min y0 y1, max x0 x1, max y0 y1)
grid :: (X, Y) -> Area -> [(PointXY, Area)]
grid (nx, ny) (x0, y0, x1, y1) =
let xd = x1 x0
yd = y1 y0
xborder = if nx == 1 then 3 else 2
yborder = if ny == 1 then 3 else 2
in [ (PointXY (x, y), (x0 + (xd * x `div` nx) + xborder,
y0 + (yd * y `div` ny) + yborder,
x0 + (xd * (x + 1) `div` nx) xborder,
y0 + (yd * (y + 1) `div` ny) yborder))
| x <- [0..nx1], y <- [0..ny1] ]
validArea :: Area -> Bool
validArea (x0, y0, x1, y1) = x0 <= x1 && y0 <= y1
trivialArea :: Area -> Bool
trivialArea (x0, y0, x1, y1) = x0 == x1 && y0 == y1
expand :: Area -> Int -> Area
expand (x0, y0, x1, y1) k = (x0 k, y0 k, x1 + k, y1 + k)