module Kewar.Layout.Types (Module (..), Position, Grid, fromChar, flipM, sumP, maxP, mkGrid, insertAt, insert, transpose, rows, cols, dimension, moveTo, overlapsWith) where
import Data.Array
import Data.Bifunctor (bimap, first)
import Data.List (groupBy)
import Data.Tuple (swap)
data Module
=
Black
|
White
deriving (Module -> Module -> Bool
(Module -> Module -> Bool)
-> (Module -> Module -> Bool) -> Eq Module
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Module -> Module -> Bool
$c/= :: Module -> Module -> Bool
== :: Module -> Module -> Bool
$c== :: Module -> Module -> Bool
Eq)
fromChar :: Char -> Maybe Module
fromChar :: Char -> Maybe Module
fromChar Char
'0' = Module -> Maybe Module
forall a. a -> Maybe a
Just Module
White
fromChar Char
'1' = Module -> Maybe Module
forall a. a -> Maybe a
Just Module
Black
fromChar Char
_ = Maybe Module
forall a. Maybe a
Nothing
flipM :: Module -> Module
flipM :: Module -> Module
flipM Module
Black = Module
White
flipM Module
White = Module
Black
type Position = (Int, Int)
sumP :: Position -> Position -> Position
sumP :: Position -> Position -> Position
sumP Position
a = (Int -> Int) -> (Int -> Int) -> Position -> Position
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (Position -> Int
forall a b. (a, b) -> a
fst Position
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (Position -> Int
forall a b. (a, b) -> b
snd Position
a Int -> Int -> Int
forall a. Num a => a -> a -> a
+)
maxP :: Position -> Position -> Position
maxP :: Position -> Position -> Position
maxP Position
a = (Int -> Int) -> (Int -> Int) -> Position -> Position
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Position -> Int
forall a b. (a, b) -> a
fst Position
a)) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (Position -> Int
forall a b. (a, b) -> b
snd Position
a))
type Grid = Array Position Module
type Size = (Position, Position)
mkGrid :: Size -> Grid
mkGrid :: Size -> Grid
mkGrid Size
b = Size -> [Module] -> Grid
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray Size
b (Module -> [Module]
forall a. a -> [a]
repeat Module
White)
insertAt :: Grid -> Position -> Module -> Grid
insertAt :: Grid -> Position -> Module -> Grid
insertAt Grid
g Position
p Module
m = Grid
g Grid -> [(Position, Module)] -> Grid
forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
// [(Position
p, Module
m)]
insert :: Grid -> [(Position, Module)] -> Grid
insert :: Grid -> [(Position, Module)] -> Grid
insert Grid
g [(Position, Module)]
as = Grid
g Grid -> [(Position, Module)] -> Grid
forall i e. Ix i => Array i e -> [(i, e)] -> Array i e
// [(Position, Module)]
as
transpose :: Grid -> Grid
transpose :: Grid -> Grid
transpose Grid
g = Size -> (Position -> Position) -> Grid -> Grid
forall i j e.
(Ix i, Ix j) =>
(i, i) -> (i -> j) -> Array j e -> Array i e
ixmap (Grid -> Size
forall i e. Array i e -> (i, i)
bounds Grid
g) Position -> Position
forall a b. (a, b) -> (b, a)
swap Grid
g
rows :: Grid -> [[(Position, Module)]]
rows :: Grid -> [[(Position, Module)]]
rows Grid
g = ((Position, Module) -> (Position, Module) -> Bool)
-> [(Position, Module)] -> [[(Position, Module)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (\((Int
a, Int
_), Module
_) ((Int
c, Int
_), Module
_) -> Int
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c) (Grid -> [(Position, Module)]
forall i e. Ix i => Array i e -> [(i, e)]
assocs Grid
g)
cols :: Grid -> [[(Position, Module)]]
cols :: Grid -> [[(Position, Module)]]
cols Grid
g = ((Position, Module) -> (Position, Module) -> Bool)
-> [(Position, Module)] -> [[(Position, Module)]]
forall a. (a -> a -> Bool) -> [a] -> [[a]]
groupBy (\((Int
a, Int
_), Module
_) ((Int
c, Int
_), Module
_) -> Int
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
c) (Grid -> [(Position, Module)]
forall i e. Ix i => Array i e -> [(i, e)]
assocs (Grid -> [(Position, Module)]) -> Grid -> [(Position, Module)]
forall a b. (a -> b) -> a -> b
$ Grid -> Grid
transpose Grid
g)
dimension :: Grid -> Int
dimension :: Grid -> Int
dimension Grid
g = (Int
r Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) Int -> Int -> Int
forall a. Num a => a -> a -> a
* (Int
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) where (Int
r, Int
c) = Size -> Position
forall a b. (a, b) -> b
snd (Size -> Position) -> Size -> Position
forall a b. (a -> b) -> a -> b
$ Grid -> Size
forall i e. Array i e -> (i, i)
bounds Grid
g
moveTo :: Position -> [(Position, Module)] -> [(Position, Module)]
moveTo :: Position -> [(Position, Module)] -> [(Position, Module)]
moveTo Position
p = ((Position, Module) -> (Position, Module))
-> [(Position, Module)] -> [(Position, Module)]
forall a b. (a -> b) -> [a] -> [b]
map (((Position, Module) -> (Position, Module))
-> [(Position, Module)] -> [(Position, Module)])
-> ((Position, Module) -> (Position, Module))
-> [(Position, Module)]
-> [(Position, Module)]
forall a b. (a -> b) -> a -> b
$ (Position -> Position) -> (Position, Module) -> (Position, Module)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first (Position -> Position -> Position
sumP Position
p)
overlapsWith :: Position -> (Position, Position) -> Bool
overlapsWith :: Position -> Size -> Bool
overlapsWith Position
p Size
r = Size -> Position -> Bool
forall a. Ix a => (a, a) -> a -> Bool
inRange Size
r Position
p