![]() ![]() To improve the elegance and performance of this codebase.Īs it turns out, cellular automata are well represented by comonads. Like any good Haskeller I’d like to leverage whatever abstractions I can Is how I rendered the above implementation using the brick library.īut, this post is not about brick. Which is a fantastic package that providesĪ high level declarative API to develop terminal interface applicationsĪlong with a number of useful widgets - not to mention 17 awesomeĭemo programs, great documentation, and a responsive google group. My real challenge and where I spent the most effort was in theįrontend, rendering and handling user interaction from a terminal. Most of the tedious legwork was done in the grid package. So, you can see I was able to speed through the actual GoL logic since Which is how I wanted to implement this version. elemsįurthermore, using the toroidal style of grid allows modular boundaries (` elem ` neighbours b c )) $ b population :: Board -> Int population = length. mapWithKey rule b where rule :: Cell -> St -> St rule c Dead | liveNeighbors c = 3 = Alive | otherwise = Dead rule c Alive | liveNeighbors c = 2 = Alive | liveNeighbors c = 3 = Alive | otherwise = Dead liveNeighbors :: Cell -> Int liveNeighbors c = population $ GM. Game evolution was very straightforward: step :: Board -> Board step b = GM. I even get a neighbours function that returns all 8 neighbours of a cellĪlong with many more useful functions, so implementing In fact, the toList function that we get from the Grid typeclass confirms this: λ > toList $ blinker 3 3 It was nice to do this first because I got a lot for free.Įssentially my board looks like a mapping of (x,y) coordinates to cell states. In my first pass at this, instead of creating a custom data structure directlyĪ really cool library that is useful for exploring mathematical grids/graphs/lattices: import ( Index ) import ( TorOctGrid ) import ( LGridMap ) data St = Alive | Dead type Board = LGridMap TorOctGrid St type Cell = Index Board (Someone did this, or some of it, in Haskell Of computing the game is known as HashLife, which is a pretty objectively complex The difficulty is in programming it efficiently. To play around with the GoL (link set to “initial” version before comonads).Īs you can guess from the rules above, the GoL is very easy to program Yesterday I finished a little terminal application Any dead cell with exactly three live neighbours becomes alive.Any live cell with exactly two or three live neighbours stays alive.The grid evolves to step t + 1 based on these simple rules: The grid evolves in discrete steps of time t. In a nutshell, there is a 2D grid of cells, each of which has two possible states: alive or dead. It is one of many examples of complex systems. Is a cellular automaton of simple cells, each following simple rules,įrom which very complex behavior emerges under the right conditions. If you already know what the GoL is, skip the introduction,Īnd if you’re already familiar with comonads and how theyĪre defined in Haskell, feel free to skip down to the performance section. I’m going to talk a little bit about Conway’s Game of Life,Īnd the performance improvement that they have to offer. ![]()
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |