{"id":18017925,"url":"https://github.com/zac-garby/automaton","last_synced_at":"2025-04-04T16:18:41.880Z","repository":{"id":116695703,"uuid":"178913967","full_name":"zac-garby/automaton","owner":"zac-garby","description":"Cellular Automaton Library for Haskell","archived":false,"fork":false,"pushed_at":"2019-04-17T11:08:08.000Z","size":9899,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T01:43:23.138Z","etag":null,"topics":["automaton","haskell"],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zac-garby.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-01T17:33:00.000Z","updated_at":"2019-04-17T11:08:09.000Z","dependencies_parsed_at":null,"dependency_job_id":"cbec3d06-6ec1-4cb9-9380-cf1cff771789","html_url":"https://github.com/zac-garby/automaton","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zac-garby%2Fautomaton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zac-garby%2Fautomaton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zac-garby%2Fautomaton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zac-garby%2Fautomaton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zac-garby","download_url":"https://codeload.github.com/zac-garby/automaton/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247208307,"owners_count":20901570,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automaton","haskell"],"created_at":"2024-10-30T04:26:12.688Z","updated_at":"2025-04-04T16:18:41.857Z","avatar_url":"https://github.com/zac-garby.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Automaton\n\nA Haskell library for easily defining cellular automata.\n\n - Quite fast\n - Some helpful functions to generate a random grid, apply game-of-life rules, and more\n - Simple to define a new rule\n\n\u003cp align=\"center\"\u003e\n \u003cimg src=\"eg/gol.gif\"\u003e\n\u003c/p\u003e\n\nTo run an example, clone the repository and install [gifgen](https://github.com/lukechilds/gifgen), then run:\n\n```\ncabal exec bash # or zsh, or whatever\nrm -r out/*     # only if you've run this already\nghc -O2 gol.hs\n./gol           # might take a while. i should probably do some parallel stuff\ngifgen -o out.gif -f 25 out/%d.png\n```\n\nOr, if you can't be bothered to install gifgen, you could generate a gif with `ffmpeg` or some other tool, or just look at the contents of `out/` yourself. You can try framerates other than 25fps, but with gifgen, it seems that if you set it higher than that, it skips frames when playing it back, which is not ideal.\n\n## Example\n\nThis is an example, to show how simple it is to make a game-of-life. Though it's a bit unfair, because game-of-life is actually defined inside the library already:\n\n```haskell\nmain = do\n    board \u003c- random 256 256 (False, True)\n    \n    forM_ (zip [1..] $ take 1024 $ steps gol board) $ \\(i, b) -\u003e do\n        img \u003c- renderBoard (option (rgb 0 0 0) (rgb 255 255 255)) b\n        savePngFile (\"out/\" ++ show i ++ \".png\") img\n        putStrLn $ \"finished step \" ++ show i ++ \" of 1024\"\n```\n\nIf you want to define your own automaton, you will have to make a `Rule a` and a `Palette a`, where `a` is the type of the cells of the grid your automaton will live on. These types are defined as:\n\n```haskell\ntype Pos = (Int, Int)\ntype Rule a = Pos -\u003e Board a -\u003e a -\u003e a\ntype Palette a = a -\u003e Color          -- Color comes from Graphics.GD\n```\n\n`Palette a` will only be needed if you want to render your automaton using the built-in rendering functions, which in 99% of cases you will.\n\nAnd example rule would be `gol`, defined in the library:\n\n```haskell\ngol :: Rule Bool\ngol pos board True = let n = countNeighbours id board pos in n == 2 || n == 3\ngol pos board False = let n = countNeighbours id board pos in n == 3\n```\n \u003e `countNeighbours` is used to count the number of immediate neighbours around a given cell (specified by `pos`) which satisfy a predicate. Here, the predicate is `id`, because the game-of-life board is a grid of booleans and so `id` will cause it to count the number of neighbours which are `True`.\n\nIt says that an \"alive\" cell will remain alive only if it has 2 or 3 neighbours, and a \"dead\" cell will become alive only if it has 3 neighbours.\n\nA palette for this might look like this:\n\n```haskell\npalette :: Palette Bool\npalette True = rgb 255 255 255\npalette False = rgb 0 0 0\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzac-garby%2Fautomaton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzac-garby%2Fautomaton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzac-garby%2Fautomaton/lists"}