swarm-0.4: src/Swarm/Game/World/Coords.hs
{-# LANGUAGE PatternSynonyms #-}
-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- World coordinates.
module Swarm.Game.World.Coords (
Coords (..),
locToCoords,
coordsToLoc,
BoundsRectangle,
)
where
import Control.Lens (Rewrapped, Wrapped)
import Data.Array.IArray (Ix)
import Data.Int (Int32)
import GHC.Generics (Generic)
import Swarm.Game.Location (Location, pattern Location)
------------------------------------------------------------
-- World coordinates
------------------------------------------------------------
-- | World coordinates use (row,column) format, with the row
-- increasing as we move down the screen. We use this format for
-- indexing worlds internally, since it plays nicely with things
-- like drawing the screen, and reading maps from configuration
-- files. The 'locToCoords' and 'coordsToLoc' functions convert back
-- and forth between this type and 'Location', which is used when
-- presenting coordinates externally to the player.
newtype Coords = Coords {unCoords :: (Int32, Int32)}
deriving (Eq, Ord, Show, Ix, Generic)
instance Rewrapped Coords t
instance Wrapped Coords
-- | Convert an external (x,y) location to an internal 'Coords' value.
locToCoords :: Location -> Coords
locToCoords (Location x y) = Coords (-y, x)
-- | Convert an internal 'Coords' value to an external (x,y) location.
coordsToLoc :: Coords -> Location
coordsToLoc (Coords (r, c)) = Location c (-r)
-- | Represents the top-left and bottom-right coordinates
-- of a bounding rectangle of cells in the world map
type BoundsRectangle = (Coords, Coords)