------------------------------------------------------------------------
-- |
-- Module      :  Math.Geometry.HexGridInternal
-- Copyright   :  (c) Amy de Buitléir 2012-2019
-- License     :  BSD-style
-- Maintainer  :  amy@nualeargais.ie
-- Stability   :  experimental
-- Portability :  portable
--
-- A module containing private @HexGrid2@ internals. Most developers 
-- should use @HexGrid2@ instead. This module is subject to change 
-- without notice.
--
------------------------------------------------------------------------
{-# LANGUAGE TypeFamilies, FlexibleContexts, DeriveGeneric #-}

module Math.Geometry.Grid.HexagonalInternal2 where

import Prelude hiding (null)
import GHC.Generics (Generic)
import Math.Geometry.GridInternal

data HexDirection = Northwest | North | Northeast | Southeast | South |
                      Southwest deriving (Int -> HexDirection -> ShowS
[HexDirection] -> ShowS
HexDirection -> String
(Int -> HexDirection -> ShowS)
-> (HexDirection -> String)
-> ([HexDirection] -> ShowS)
-> Show HexDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HexDirection] -> ShowS
$cshowList :: [HexDirection] -> ShowS
show :: HexDirection -> String
$cshow :: HexDirection -> String
showsPrec :: Int -> HexDirection -> ShowS
$cshowsPrec :: Int -> HexDirection -> ShowS
Show, HexDirection -> HexDirection -> Bool
(HexDirection -> HexDirection -> Bool)
-> (HexDirection -> HexDirection -> Bool) -> Eq HexDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HexDirection -> HexDirection -> Bool
$c/= :: HexDirection -> HexDirection -> Bool
== :: HexDirection -> HexDirection -> Bool
$c== :: HexDirection -> HexDirection -> Bool
Eq, (forall x. HexDirection -> Rep HexDirection x)
-> (forall x. Rep HexDirection x -> HexDirection)
-> Generic HexDirection
forall x. Rep HexDirection x -> HexDirection
forall x. HexDirection -> Rep HexDirection x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep HexDirection x -> HexDirection
$cfrom :: forall x. HexDirection -> Rep HexDirection x
Generic)

-- | An unbounded grid with hexagonal tiles
--   The grid and its indexing scheme are illustrated in the user guide,
--   available at <https://github.com/mhwombat/grid/wiki>.
data UnboundedHexGrid = UnboundedHexGrid deriving (UnboundedHexGrid -> UnboundedHexGrid -> Bool
(UnboundedHexGrid -> UnboundedHexGrid -> Bool)
-> (UnboundedHexGrid -> UnboundedHexGrid -> Bool)
-> Eq UnboundedHexGrid
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UnboundedHexGrid -> UnboundedHexGrid -> Bool
$c/= :: UnboundedHexGrid -> UnboundedHexGrid -> Bool
== :: UnboundedHexGrid -> UnboundedHexGrid -> Bool
$c== :: UnboundedHexGrid -> UnboundedHexGrid -> Bool
Eq, Int -> UnboundedHexGrid -> ShowS
[UnboundedHexGrid] -> ShowS
UnboundedHexGrid -> String
(Int -> UnboundedHexGrid -> ShowS)
-> (UnboundedHexGrid -> String)
-> ([UnboundedHexGrid] -> ShowS)
-> Show UnboundedHexGrid
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UnboundedHexGrid] -> ShowS
$cshowList :: [UnboundedHexGrid] -> ShowS
show :: UnboundedHexGrid -> String
$cshow :: UnboundedHexGrid -> String
showsPrec :: Int -> UnboundedHexGrid -> ShowS
$cshowsPrec :: Int -> UnboundedHexGrid -> ShowS
Show, (forall x. UnboundedHexGrid -> Rep UnboundedHexGrid x)
-> (forall x. Rep UnboundedHexGrid x -> UnboundedHexGrid)
-> Generic UnboundedHexGrid
forall x. Rep UnboundedHexGrid x -> UnboundedHexGrid
forall x. UnboundedHexGrid -> Rep UnboundedHexGrid x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep UnboundedHexGrid x -> UnboundedHexGrid
$cfrom :: forall x. UnboundedHexGrid -> Rep UnboundedHexGrid x
Generic)

instance Grid UnboundedHexGrid where
  type Index UnboundedHexGrid = (Int, Int)
  type Direction UnboundedHexGrid = HexDirection
  indices :: UnboundedHexGrid -> [Index UnboundedHexGrid]
indices UnboundedHexGrid
_ = [Index UnboundedHexGrid]
forall a. HasCallStack => a
undefined
  neighbours :: UnboundedHexGrid
-> Index UnboundedHexGrid -> [Index UnboundedHexGrid]
neighbours UnboundedHexGrid
_ (x,y) = 
    [(Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1,Int
y), (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1,Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1), (Int
x,Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1), (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1,Int
y), (Int
xInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1,Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1), (Int
x,Int
yInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)]
  distance :: UnboundedHexGrid
-> Index UnboundedHexGrid -> Index UnboundedHexGrid -> Int
distance UnboundedHexGrid
_ (x1, y1) (x2, y2) = 
    [Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum [Int -> Int
forall a. Num a => a -> a
abs (Int
x2Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x1), Int -> Int
forall a. Num a => a -> a
abs (Int
y2Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
y1), Int -> Int
forall a. Num a => a -> a
abs(Int
z2Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
z1)]
    where z1 :: Int
z1 = -Int
x1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y1
          z2 :: Int
z2 = -Int
x2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y2
  directionTo :: UnboundedHexGrid
-> Index UnboundedHexGrid
-> Index UnboundedHexGrid
-> [Direction UnboundedHexGrid]
directionTo UnboundedHexGrid
_ (x1, y1) (x2, y2) = [HexDirection] -> [HexDirection]
f1 ([HexDirection] -> [HexDirection])
-> ([HexDirection] -> [HexDirection])
-> [HexDirection]
-> [HexDirection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [HexDirection] -> [HexDirection]
f2 ([HexDirection] -> [HexDirection])
-> ([HexDirection] -> [HexDirection])
-> [HexDirection]
-> [HexDirection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [HexDirection] -> [HexDirection]
f3 ([HexDirection] -> [HexDirection])
-> ([HexDirection] -> [HexDirection])
-> [HexDirection]
-> [HexDirection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [HexDirection] -> [HexDirection]
f4 ([HexDirection] -> [HexDirection])
-> ([HexDirection] -> [HexDirection])
-> [HexDirection]
-> [HexDirection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [HexDirection] -> [HexDirection]
f5 ([HexDirection] -> [HexDirection])
-> ([HexDirection] -> [HexDirection])
-> [HexDirection]
-> [HexDirection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [HexDirection] -> [HexDirection]
f6 ([HexDirection] -> [HexDirection])
-> [HexDirection] -> [HexDirection]
forall a b. (a -> b) -> a -> b
$ []
    where f1 :: [HexDirection] -> [HexDirection]
f1 [HexDirection]
ds =  if Int
dy Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
dz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then HexDirection
NorthHexDirection -> [HexDirection] -> [HexDirection]
forall a. a -> [a] -> [a]
:[HexDirection]
ds else [HexDirection]
ds
          f2 :: [HexDirection] -> [HexDirection]
f2 [HexDirection]
ds =  if Int
dy Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
&& Int
dz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then HexDirection
SouthHexDirection -> [HexDirection] -> [HexDirection]
forall a. a -> [a] -> [a]
:[HexDirection]
ds else [HexDirection]
ds
          f3 :: [HexDirection] -> [HexDirection]
f3 [HexDirection]
ds =  if Int
dx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
dz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then HexDirection
NortheastHexDirection -> [HexDirection] -> [HexDirection]
forall a. a -> [a] -> [a]
:[HexDirection]
ds else [HexDirection]
ds
          f4 :: [HexDirection] -> [HexDirection]
f4 [HexDirection]
ds =  if Int
dx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
&& Int
dy Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then HexDirection
NorthwestHexDirection -> [HexDirection] -> [HexDirection]
forall a. a -> [a] -> [a]
:[HexDirection]
ds else [HexDirection]
ds
          f5 :: [HexDirection] -> [HexDirection]
f5 [HexDirection]
ds =  if Int
dx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 Bool -> Bool -> Bool
&& Int
dy Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then HexDirection
SoutheastHexDirection -> [HexDirection] -> [HexDirection]
forall a. a -> [a] -> [a]
:[HexDirection]
ds else [HexDirection]
ds
          f6 :: [HexDirection] -> [HexDirection]
f6 [HexDirection]
ds =  if Int
dx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
&& Int
dz Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 then HexDirection
SouthwestHexDirection -> [HexDirection] -> [HexDirection]
forall a. a -> [a] -> [a]
:[HexDirection]
ds else [HexDirection]
ds
          dx :: Int
dx = Int
x2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x1
          dy :: Int
dy = Int
y2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y1
          z1 :: Int
z1 = -Int
x1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y1
          z2 :: Int
z2 = -Int
x2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
y2
          dz :: Int
dz = Int
z2 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
z1
  contains :: UnboundedHexGrid -> Index UnboundedHexGrid -> Bool
contains UnboundedHexGrid
_ Index UnboundedHexGrid
_ = Bool
True
  null :: UnboundedHexGrid -> Bool
null UnboundedHexGrid
_ = Bool
False
  nonNull :: UnboundedHexGrid -> Bool
nonNull UnboundedHexGrid
_ = Bool
True

--
-- Hexagonal grids with hexagonal tiles
--

-- | A hexagonal grid with hexagonal tiles
--   The grid and its indexing scheme are illustrated in the user guide,
--   available at <https://github.com/mhwombat/grid/wiki>.
data HexHexGrid = HexHexGrid Int [(Int, Int)] deriving (HexHexGrid -> HexHexGrid -> Bool
(HexHexGrid -> HexHexGrid -> Bool)
-> (HexHexGrid -> HexHexGrid -> Bool) -> Eq HexHexGrid
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HexHexGrid -> HexHexGrid -> Bool
$c/= :: HexHexGrid -> HexHexGrid -> Bool
== :: HexHexGrid -> HexHexGrid -> Bool
$c== :: HexHexGrid -> HexHexGrid -> Bool
Eq, (forall x. HexHexGrid -> Rep HexHexGrid x)
-> (forall x. Rep HexHexGrid x -> HexHexGrid) -> Generic HexHexGrid
forall x. Rep HexHexGrid x -> HexHexGrid
forall x. HexHexGrid -> Rep HexHexGrid x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep HexHexGrid x -> HexHexGrid
$cfrom :: forall x. HexHexGrid -> Rep HexHexGrid x
Generic)

instance Show HexHexGrid where show :: HexHexGrid -> String
show (HexHexGrid Int
s [(Int, Int)]
_) = String
"hexHexGrid " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
s

instance Grid HexHexGrid where
  type Index HexHexGrid = (Int, Int)
  type Direction HexHexGrid = HexDirection
  indices :: HexHexGrid -> [Index HexHexGrid]
indices (HexHexGrid Int
_ [(Int, Int)]
xs) = [(Int, Int)]
[Index HexHexGrid]
xs
  neighbours :: HexHexGrid -> Index HexHexGrid -> [Index HexHexGrid]
neighbours = UnboundedHexGrid
-> HexHexGrid -> Index HexHexGrid -> [Index HexHexGrid]
forall u g.
(Eq (Index u), Grid g, Grid u, Index g ~ Index u) =>
u -> g -> Index g -> [Index g]
neighboursBasedOn UnboundedHexGrid
UnboundedHexGrid
  distance :: HexHexGrid -> Index HexHexGrid -> Index HexHexGrid -> Int
distance = UnboundedHexGrid
-> HexHexGrid -> Index HexHexGrid -> Index HexHexGrid -> Int
forall g u.
(Eq (Index g), Grid g, Grid u, Index g ~ Index u) =>
u -> g -> Index g -> Index g -> Int
distanceBasedOn UnboundedHexGrid
UnboundedHexGrid
  directionTo :: HexHexGrid
-> Index HexHexGrid -> Index HexHexGrid -> [Direction HexHexGrid]
directionTo = UnboundedHexGrid
-> HexHexGrid
-> Index HexHexGrid
-> Index HexHexGrid
-> [Direction HexHexGrid]
forall g u.
(Eq (Index g), Eq (Direction g), Grid g, Grid u, Index g ~ Index u,
 Direction g ~ Direction u) =>
u -> g -> Index g -> Index g -> [Direction g]
directionToBasedOn UnboundedHexGrid
UnboundedHexGrid
  contains :: HexHexGrid -> Index HexHexGrid -> Bool
contains HexHexGrid
g (x,y) = -Int
Size HexHexGrid
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
x Bool -> Bool -> Bool
&& Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
Size HexHexGrid
s Bool -> Bool -> Bool
&& Bool
check
    where s :: Size HexHexGrid
s = HexHexGrid -> Size HexHexGrid
forall g. FiniteGrid g => g -> Size g
size HexHexGrid
g
          check :: Bool
check = if Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
                    then -Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
y Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
Size HexHexGrid
s
                    else -Int
Size HexHexGrid
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
y Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x

instance FiniteGrid HexHexGrid where
  type Size HexHexGrid = Int
  size :: HexHexGrid -> Size HexHexGrid
size (HexHexGrid Int
s [(Int, Int)]
_) = Int
Size HexHexGrid
s
  maxPossibleDistance :: HexHexGrid -> Int
maxPossibleDistance g :: HexHexGrid
g@(HexHexGrid Int
s [(Int, Int)]
_) = HexHexGrid -> Index HexHexGrid -> Index HexHexGrid -> Int
forall g. Grid g => g -> Index g -> Index g -> Int
distance HexHexGrid
g (-Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1,Int
0) (Int
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1,Int
0)

instance BoundedGrid HexHexGrid where
  tileSideCount :: HexHexGrid -> Int
tileSideCount HexHexGrid
_ = Int
6
  boundary :: HexHexGrid -> [Index HexHexGrid]
boundary HexHexGrid
g = 
    [(Int, Int)]
northwest [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int, Int)]
northeast [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int, Int)]
east [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int, Int)]
southeast [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int, Int)]
southwest [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int, Int)]
west
    where s :: Size HexHexGrid
s = HexHexGrid -> Size HexHexGrid
forall g. FiniteGrid g => g -> Size g
size HexHexGrid
g
          northwest :: [(Int, Int)]
northwest = [(Int
k,Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) | Int
k <- [-Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1,-Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
2..Int
0]]
          northeast :: [(Int, Int)]
northeast = [(Int
k,Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k) | Int
k <- [Int
1,Int
2..Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]]
          east :: [(Int, Int)]
east = [(Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1,Int
k) | Int
k <- [-Int
1,-Int
2..(-Int
Size HexHexGrid
s)Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1]]
          southeast :: [(Int, Int)]
southeast = [(Int
k,(-Int
Size HexHexGrid
s)Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) | Int
k <- [Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
2,Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
3..Int
0]]
          southwest :: [(Int, Int)]
southwest = [(Int
k,(-Int
Size HexHexGrid
s)Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
k) | Int
k <- [-Int
1,-Int
2..(-Int
Size HexHexGrid
s)Int -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1]]
          west :: [(Int, Int)]
west = [(-Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1,Int
k) | Int
k <- [Int
1,Int
2..Int
Size HexHexGrid
sInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
2]]
  centre :: HexHexGrid -> [Index HexHexGrid]
centre HexHexGrid
_ = [(Int
0,Int
0)]

-- | @'hexHexGrid' s@ returns a grid of hexagonal shape, with
--   sides of length @s@, using hexagonal tiles. If @s@ is nonnegative, the 
--   resulting grid will have @3*s*(s-1) + 1@ tiles. Otherwise, the resulting 
--   grid will be null and the list of indices will be null.
hexHexGrid :: Int -> HexHexGrid
hexHexGrid :: Int -> HexHexGrid
hexHexGrid Int
r = Int -> [(Int, Int)] -> HexHexGrid
HexHexGrid Int
r [(Int
x, Int
y) | Int
x <- [-Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1..Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1], Int
y <- Int -> [Int]
f Int
x]
  where f :: Int -> [Int]
f Int
x = if Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 then [Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x .. Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1] else [Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
r .. Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
x]

--
-- Rectangular grids with hexagonal tiles
--

-- | A rectangular grid with hexagonal tiles
--   The grid and its indexing scheme are illustrated in the user guide,
--   available at <https://github.com/mhwombat/grid/wiki>.
data RectHexGrid = RectHexGrid (Int, Int) [(Int, Int)]
  deriving (RectHexGrid -> RectHexGrid -> Bool
(RectHexGrid -> RectHexGrid -> Bool)
-> (RectHexGrid -> RectHexGrid -> Bool) -> Eq RectHexGrid
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: RectHexGrid -> RectHexGrid -> Bool
$c/= :: RectHexGrid -> RectHexGrid -> Bool
== :: RectHexGrid -> RectHexGrid -> Bool
$c== :: RectHexGrid -> RectHexGrid -> Bool
Eq, (forall x. RectHexGrid -> Rep RectHexGrid x)
-> (forall x. Rep RectHexGrid x -> RectHexGrid)
-> Generic RectHexGrid
forall x. Rep RectHexGrid x -> RectHexGrid
forall x. RectHexGrid -> Rep RectHexGrid x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep RectHexGrid x -> RectHexGrid
$cfrom :: forall x. RectHexGrid -> Rep RectHexGrid x
Generic)

instance Show RectHexGrid where 
  show :: RectHexGrid -> String
show (RectHexGrid (Int
r,Int
c) [(Int, Int)]
_) = String
"rectHexGrid " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
r String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
c

instance Grid RectHexGrid where
  type Index RectHexGrid = (Int, Int)
  type Direction RectHexGrid = HexDirection
  indices :: RectHexGrid -> [Index RectHexGrid]
indices (RectHexGrid (Int, Int)
_ [(Int, Int)]
xs) = [(Int, Int)]
[Index RectHexGrid]
xs
  neighbours :: RectHexGrid -> Index RectHexGrid -> [Index RectHexGrid]
neighbours = UnboundedHexGrid
-> RectHexGrid -> Index RectHexGrid -> [Index RectHexGrid]
forall u g.
(Eq (Index u), Grid g, Grid u, Index g ~ Index u) =>
u -> g -> Index g -> [Index g]
neighboursBasedOn UnboundedHexGrid
UnboundedHexGrid
  distance :: RectHexGrid -> Index RectHexGrid -> Index RectHexGrid -> Int
distance = UnboundedHexGrid
-> RectHexGrid -> Index RectHexGrid -> Index RectHexGrid -> Int
forall g u.
(Eq (Index g), Grid g, Grid u, Index g ~ Index u) =>
u -> g -> Index g -> Index g -> Int
distanceBasedOn UnboundedHexGrid
UnboundedHexGrid
  directionTo :: RectHexGrid
-> Index RectHexGrid
-> Index RectHexGrid
-> [Direction RectHexGrid]
directionTo = UnboundedHexGrid
-> RectHexGrid
-> Index RectHexGrid
-> Index RectHexGrid
-> [Direction RectHexGrid]
forall g u.
(Eq (Index g), Eq (Direction g), Grid g, Grid u, Index g ~ Index u,
 Direction g ~ Direction u) =>
u -> g -> Index g -> Index g -> [Direction g]
directionToBasedOn UnboundedHexGrid
UnboundedHexGrid
  contains :: RectHexGrid -> Index RectHexGrid -> Bool
contains RectHexGrid
g (x,y) = Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
x Bool -> Bool -> Bool
&& Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
c Bool -> Bool -> Bool
&& Int
y0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
y Bool -> Bool -> Bool
&& Int
y Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
y1
    where (Int
r,Int
c) = RectHexGrid -> Size RectHexGrid
forall g. FiniteGrid g => g -> Size g
size RectHexGrid
g
          y0 :: Int
y0 = Int -> Int -> Int
rectHexGridY Int
x Int
0
          y1 :: Int
y1 = Int -> Int -> Int
rectHexGridY Int
x (Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
--          (y0,y1) = rectHexGridYEndpoints r x

instance FiniteGrid RectHexGrid where
  type Size RectHexGrid = (Int, Int)
  size :: RectHexGrid -> Size RectHexGrid
size (RectHexGrid (Int, Int)
s [(Int, Int)]
_) = (Int, Int)
Size RectHexGrid
s
  maxPossibleDistance :: RectHexGrid -> Int
maxPossibleDistance g :: RectHexGrid
g@(RectHexGrid (Int
r,Int
c) [(Int, Int)]
_) = 
    RectHexGrid -> Index RectHexGrid -> Index RectHexGrid -> Int
forall g. Grid g => g -> Index g -> Index g -> Int
distance RectHexGrid
g (Int
0,Int
0) (Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1,Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-(Int
c Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2))

instance BoundedGrid RectHexGrid where
  tileSideCount :: RectHexGrid -> Int
tileSideCount RectHexGrid
_ = Int
6
  boundary :: RectHexGrid -> [Index RectHexGrid]
boundary RectHexGrid
g =
    [(Int
0,Int -> Int -> Int
rectHexGridY Int
0 Int
j) | Int
j <- [Int
0..Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1], Int
cInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0]                -- West
      [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int
x,Int -> Int -> Int
rectHexGridY Int
x (Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)) | Int
x <- [Int
1..Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1], Int
rInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
0]       -- North
      [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1,Int -> Int -> Int
rectHexGridY (Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) Int
j) | Int
j <- [Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
2,Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
3..Int
0], Int
cInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
1] -- East
      [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int
x,Int -> Int -> Int
rectHexGridY Int
x Int
0) | Int
x <- [Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
2,Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
3..Int
1], Int
rInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
1]       -- South
    where (Int
r,Int
c) = RectHexGrid -> Size RectHexGrid
forall g. FiniteGrid g => g -> Size g
size RectHexGrid
g

-- | @'rectHexGrid' r c@ returns a grid in the shape of a 
--   parallelogram with @r@ rows and @c@ columns, using hexagonal tiles.
--   If @r@ and @c@ are both nonnegative, the resulting grid will have
--   @r*c@ tiles. Otherwise, the resulting grid will be null and the
--   list of indices will be null.
rectHexGrid :: Int -> Int -> RectHexGrid
rectHexGrid :: Int -> Int -> RectHexGrid
rectHexGrid Int
r Int
c = 
  (Int, Int) -> [(Int, Int)] -> RectHexGrid
RectHexGrid (Int
r,Int
c) [(Int
x,Int -> Int -> Int
rectHexGridY Int
x Int
j) | Int
x <- [Int
0..Int
cInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1], Int
j <- [Int
0..Int
rInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1]]

rectHexGridY :: Int -> Int -> Int
rectHexGridY :: Int -> Int -> Int
rectHexGridY Int
x Int
j = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
x Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2