swarm-0.5.0.0: src/Swarm/Game/Scenario/Topography/Area.hs
{-# LANGUAGE OverloadedStrings #-}
-- |
-- SPDX-License-Identifier: BSD-3-Clause
module Swarm.Game.Scenario.Topography.Area where
import Data.Int (Int32)
import Data.List qualified as L
import Data.Maybe (listToMaybe)
import Linear (V2 (..))
import Swarm.Game.Location
-- | Height and width of a 2D map region
data AreaDimensions = AreaDimensions
{ rectWidth :: Int32
, rectHeight :: Int32
}
renderRectDimensions :: AreaDimensions -> String
renderRectDimensions (AreaDimensions w h) =
L.intercalate "x" $ map show [w, h]
invertY :: V2 Int32 -> V2 Int32
invertY (V2 x y) = V2 x (-y)
-- | Incorporates an offset by @-1@, since the area is
-- "inclusive" of the lower-right coordinate.
-- Inverse of 'cornersToArea'.
upperLeftToBottomRight :: AreaDimensions -> Location -> Location
upperLeftToBottomRight (AreaDimensions w h) upperLeft =
upperLeft .+^ displacement
where
displacement = invertY $ subtract 1 <$> V2 w h
-- | Converts the displacement vector between the two
-- diagonal corners of the rectangle into an 'AreaDimensions' record.
-- Adds one to both dimensions since the corner coordinates are "inclusive".
-- Inverse of 'upperLeftToBottomRight'.
cornersToArea :: Location -> Location -> AreaDimensions
cornersToArea upperLeft lowerRight =
AreaDimensions x y
where
V2 x y = (+ 1) <$> invertY (lowerRight .-. upperLeft)
-- | Has zero width or height.
isEmpty :: AreaDimensions -> Bool
isEmpty (AreaDimensions w h) = w == 0 || h == 0
-- | Extracts the dimensions of a map grid.
getAreaDimensions :: [[a]] -> AreaDimensions
getAreaDimensions cellGrid =
AreaDimensions w h
where
w = fromIntegral $ maybe 0 length $ listToMaybe cellGrid -- column count
h = fromIntegral $ length cellGrid -- row count