From 12c28cd733ab10058b2aee6e44ab25ffb4bebe31 Mon Sep 17 00:00:00 2001 From: kiana-S Date: Tue, 21 Dec 2021 21:36:59 -0500 Subject: [PATCH] Added a toroidal space --- GOL/Space.hs | 42 +++++++++++++++++++++++++++++++++++++- conways-game-of-life.cabal | 4 +++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/GOL/Space.hs b/GOL/Space.hs index 890e9b3..3d0526a 100644 --- a/GOL/Space.hs +++ b/GOL/Space.hs @@ -1,10 +1,15 @@ {-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TypeFamilies #-} module GOL.Space where +import Data.Bifunctor +import Data.Distributive import Data.Functor.Rep +import Data.Vector (Vector, (!)) +import qualified Data.Vector as V -- | A space in which a Conway's Game of Life simulation -- takes place, with a notion of "neighbors to a cell" defined. @@ -25,4 +30,39 @@ class Representable f => Space f where -- grid. The graphical system requires a displayable space. class (Space f, Rep f ~ (Int, Int)) => DisplayableSpace f where sizex :: Int - sizey :: Int \ No newline at end of file + sizey :: Int + +-- * Standard spaces + +-- Unfortunately, due to the fact that Haskell doesn't have dependent types, +-- defining a GOL space to have an arbitrary size specified at runtime by +-- the user is completely impossible. There's simply no way to do it without +-- features that Haskell doesn't have. +-- So until we get generalized pi types in GHC, we'll have to make do with +-- hard-coded space sizes. + +-- | A 100x100 2D grid space. This space is _toroidal_, which means that +-- cells on the opposite edges are considered neighbors of each other. +newtype ToroidalSpace a = TS (Vector (Vector a)) + deriving (Show, Functor) + +instance Distributive ToroidalSpace where + distribute xs = tabulate (\p -> fmap (`index` p) xs) + +instance Representable ToroidalSpace where + type Rep ToroidalSpace = (Int, Int) + index (TS s) (i, j) = s ! j ! i + tabulate f = TS $ V.generate 100 (\x -> V.generate 100 $ \y -> f (x, y)) + +instance Space ToroidalSpace where + neighbors (i, j) = + bimap ((`mod` 100).(+i)) ((`mod` 100).(+j)) <$> + [ + (-1,-1), (0,-1), (1,-1), + (-1, 0), (1, 0), + (-1, 1), (0, 1), (1, 1) + ] + +instance DisplayableSpace ToroidalSpace where + sizex = 100 + sizey = 100 \ No newline at end of file diff --git a/conways-game-of-life.cabal b/conways-game-of-life.cabal index 00ee47e..a16603d 100644 --- a/conways-game-of-life.cabal +++ b/conways-game-of-life.cabal @@ -14,4 +14,6 @@ executable main build-depends: base, comonad, Yampa, - adjunctions \ No newline at end of file + distributive, + adjunctions, + vector \ No newline at end of file