diff --git a/Main.hs b/Main.hs
new file mode 100644
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,69 @@
+module Main where
+
+import Simulation
+
+import qualified UI.HSCurses.Curses as Curses
+import Control.Monad(replicateM)
+import Control.Concurrent(threadDelay)
+import System.Random
+import Data.List(intersperse)
+import Data.Array
+
+delay :: Int
+delay = 0
+density :: Float
+density = 0.375
+
+main :: IO ()
+main = do
+  window <- Curses.initScr
+  Curses.raw True
+  _ <- Curses.cursSet Curses.CursorInvisible
+  (rows, cols) <- Curses.scrSize
+  randomBoard (rows) (cols-1) >>= life 1000 window
+  Curses.resetParams
+  Curses.endWin
+
+life :: Int -> Curses.Window -> Board -> IO ()
+life 0 _ _ = return ()
+life gens window board = do
+    _ <- drawBoard board window
+    Curses.timeout delay
+    Curses.getch >>= \ch -> case Curses.decodeKey ch of 
+      Curses.KeyUnknown _ -> life (gens-1) window (step board)
+      _                   -> return ()
+
+drawBoard :: Board -> Curses.Window -> IO ()
+drawBoard board window = do
+  Curses.move 0 0
+  Curses.wAddStr window (boardRep board)
+  Curses.wRefresh window
+
+boardRep :: Board -> String
+boardRep board = concat . intersperse "\n" $ [rowStrings r | r <- [0..rs-1]]
+  where
+  rowStrings :: Int -> String
+  rowStrings r = concat [show (grid ! r ! c) | c <- [0..cs-1]]
+  rs = bRows board 
+  cs = bCols board 
+  grid = bGrid board
+
+randomBoard :: Int -> Int -> IO Board
+randomBoard rows cols = randomGrid rows cols >>= 
+                                \grid -> return $ Board grid rows cols
+
+randomGrid :: Int -> Int -> IO Grid
+randomGrid rs cs = replicateM cs randomRow >>= \rows -> return $ listArray (0, rs-1) rows
+  where
+  randomRow :: IO (Array Int State)
+  randomRow = randomListOfCells >>= \cells -> return $ listArray (0, cs-1) cells
+
+  randomListOfCells :: IO [State]
+  randomListOfCells = replicateM cs randomIO >>= return . map randomCell
+
+  randomCell :: Float -> State
+  randomCell r
+    | r < density  = Alive
+    | r >= density = Dead
+    | otherwise    = Dead
+
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/game-of-life.cabal b/game-of-life.cabal
new file mode 100644
--- /dev/null
+++ b/game-of-life.cabal
@@ -0,0 +1,29 @@
+-- Initial game-of-life.cabal generated by cabal init.  For further
+--  documentation, see http://haskell.org/cabal/users-guide/
+
+name:                game-of-life
+version:             0.1.0.0
+synopsis:            Conway's Game of Life
+-- description:         
+license:             MIT
+-- license-file:        LICENSE
+author:              Marcus Buffett
+maintainer:          marcusbuffett@me.com
+-- copyright:           
+-- category:            
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+
+executable game-of-life
+  main-is:             Main.hs
+  -- other-modules:       
+  -- other-extensions:    
+  build-depends:       base >=4.7 && <4.8,
+                       random,
+                       hscurses,
+                       array,
+                       text
+  -- hs-source-dirs:      
+  default-language:    Haskell2010
+  ghc-options:         -O2
