{"id":123,"date":"2008-05-08T14:39:11","date_gmt":"2008-05-08T19:39:11","guid":{"rendered":"http:\/\/mariusbancila.ro\/blog\/?p=123"},"modified":"2010-04-09T11:23:16","modified_gmt":"2010-04-09T09:23:16","slug":"game-of-life-in-f","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/","title":{"rendered":"Game of Life in F#"},"content":{"rendered":"<p>The Game of Life is a cellular automaton devised by the John Horton Conway in 1970. It is the best-known example of a cellular automaton. It consists of a collection of cells which, based on a few mathematical rules, can live, die or multiply. Depending on the initial conditions, the cells form various patterns throughout the course of the game.<\/p>\n<p>Here you can learn more about the game:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.bitstorm.org\/gameoflife\/\" target=\"_blank\">Game of Life<\/a><\/li>\n<li><a href=\"http:\/\/en.wikipedia.org\/wiki\/Conway's_Game_of_Life\" target=\"_blank\">Game of Life on Wikipedia<\/a><\/li>\n<\/ul>\n<p>I decided to implement this in F#. With all the code involving the user interface, it was nearly 300 lines of code. Pretty neat!<\/p>\n<p>\n<img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2008\/05\/gameoflife.png\" \/><\/p>\n<h3>Using the game<\/h3>\n<p>The life&#8217;s arena can take several sizes:<\/p>\n<ul>\n<li>Tiny: 15 x 10<\/li>\n<li>Small: 30 x 20<\/li>\n<li>Medium: 60 x 40<\/li>\n<li>Large: 120 x 80<\/li>\n<li>Huge: 150 x 100<\/li>\n<\/ul>\n<p>The size can be changed from the Game > Size menu.<\/p>\n<p>The following commands are available from the menu:<\/p>\n<ul>\n<li>Reset (Ctrl + R): Resets the game, all cells die<\/li>\n<li>Randomize (Ctrl + G): Randomly initialize alive cells<\/li>\n<li>Start\/Stop (Ctrl + B): Starts or stops continuos creation of new generations<\/li>\n<li>Step (Ctrl + N): Creates a new generation of cells<\/li>\n<\/ul>\n<p>In addition the followin commands are available from the File menu:<\/p>\n<ul>\n<li>Save (Ctrl + S): saves game to a bitmap file called gameolife_<timestamp>.bmp; this file is created in the working folder<\/li>\n<li>Save As&#8230; (Ctrl + Shift + S): saves the game to a file, giving you the possibility to chose the location and format (bmp, jpg, gif and png)<\/li>\n<\/ul>\n<p><strong>Note<\/strong>: The state of the game can be changed (killing cells, making others alive) simply by clicking with the mouse on the game panel.<\/p>\n<h3>Implementation in F#<\/h3>\n<p>Some comments on the implementation of the game. For more have a look at the code.<\/p>\n<p>I defined two records, one called Cell and one called World. The cell reprezents a cell and has a flag called Alive (which is self explanatory), and World represents the &#8216;arena of life&#8217;, containing a matrix of Cells.<\/p>\n<pre class=\"prettyprint\">\r\ntype Cell =\r\n { Alive : bool;}\r\n\r\ntype World =\r\n { Width : int;\r\n   Height : int;\r\n   Cells: Cell[,];}\r\n<\/pre>\n<p>Various arena sizes are defined in a descriminated union and the mapping between that and values for width and height are done in this function:<\/p>\n<pre class=\"prettyprint\">\r\ntype GameSize =\r\n   | Tiny\r\n   | Small\r\n   | Medium\r\n   | Large\r\n   | Huge\r\n\r\nlet sizeMapping (size:GameSize) = \r\n   match size with\r\n   | Tiny -> (15,10)\r\n   | Small -> (30, 20)\r\n   | Medium -> (60, 40)\r\n   | Large -> (120, 80)\r\n   | Huge -> (150, 100)\r\n<\/pre>\n<p>A next generation of cells is computed based on the rules of the game. For each cell the number of alived neighbors is computed and then the state of the cell is changes (if necessary).<\/p>\n<pre class=\"prettyprint\">\r\nlet nextGeneration (world:World) =\r\n   let alive = {new Cell with Alive = true}\r\n   let dead = {new Cell with Alive = false}\r\n   let newcells = Array2.create world.Width world.Height dead\r\n   for i = 0 to world.Width - 1 do\r\n      for j = 0 to world.Height - 1 do\r\n         let ncount = neighbors world j i\r\n         match world.Cells.(i,j).Alive with\r\n         | true -> if ncount = 2 || ncount = 3 then newcells.(i,j) &lt;- alive\r\n                   else newcells.(i,j) &lt;- dead\r\n         | _ -> if ncount = 3 then newcells.(i,j) &lt;- alive\r\n                  else newcells.(i,j) &lt;- dead\r\n      done\r\n   done\r\n   { world with Cells = newcells}\r\n<\/pre>\n<p>For computing the number of neighbors, I considered 9 cases:<\/p>\n<ul>\n<li>cell is one of the four corners<\/li>\n<li>cell is on one of the four edges (not a corner)<\/li>\n<li>cell is anywhere else in the matrix<\/li>\n<\/ul>\n<p>Depending on this position a list of neighbors is created and folded to compute the number of alive neighboring cells.<\/p>\n<pre class=\"prettyprint\">\r\nlet sum (neighbors:Cell list) =\r\n   neighbors |> List.fold_left (fun sum x -> if x.Alive then sum+1 else sum) 0\r\n\r\nlet neighbors (world:World) row col =\r\n   match row, col with\r\n   | _,_ when row = 0 && col = 0 -> sum [world.Cells.(1,0);world.Cells.(1,1);world.Cells.(0,1)]\r\n   | _,_ when row = 0 && col = world.Width-1 -> sum [world.Cells.(world.Width-2,0);world.Cells.(world.Width-2,1);world.Cells.(world.Width-1,1)]\r\n   | _,_ when row = world.Height-1 && col = 0 -> sum [world.Cells.(0, world.Height-2);world.Cells.(1, world.Height-2);world.Cells.(1,world.Height-1)]\r\n   | _,_ when row = world.Height-1 && col = world.Width-1 -> sum [world.Cells.(world.Width-1, world.Height-2);world.Cells.(world.Width-2, world.Height-2);world.Cells.(world.Width-2,world.Height-1)]\r\n   | _,_ when row = 0 && col > 0 && col &lt; world.Width-1 -> sum [world.Cells.(col-1,0);world.Cells.(col-1,1);world.Cells.(col,1);world.Cells.(col+1,1);world.Cells.(col+1,0);]\r\n   | _,_ when row = world.Height-1 && col > 0 && col &lt; world.Width-1 -> sum [world.Cells.(col-1,row);world.Cells.(col-1,row-1);world.Cells.(col,row-1);world.Cells.(col+1,row-1);world.Cells.(col+1,row);]\r\n   | _,_ when col = 0 && row > 0 && row &lt; world.Height-1 -> sum [world.Cells.(0,row-1);world.Cells.(1,row-1);world.Cells.(1,row);world.Cells.(1,row+1);world.Cells.(0,row+1);]\r\n   | _,_ when col = world.Width-1 && row > 0 && row &lt; world.Height-1 -> sum [world.Cells.(col,row-1);world.Cells.(col-1,row-1);world.Cells.(col-1,row);world.Cells.(col-1,row+1);world.Cells.(col,row+1);]\r\n   | _,_ -> sum [world.Cells.(col-1,row-1);world.Cells.(col,row-1);world.Cells.(col+1,row-1);world.Cells.(col+1,row);world.Cells.(col+1,row+1);world.Cells.(col,row+1);world.Cells.(col-1,row+1);world.Cells.(col-1,row);]\r\n<\/pre>\n<p>The rest is basically user interface code. But I made a parallel version of the game, when then computation of the next generation of cells is parallelized with the Parallel FX framework. Here is how the function looks.<\/p>\n<pre class=\"prettyprint\">\r\nlet nextGeneration (world:World) =\r\n   let alive = {new Cell with Alive = true}\r\n   let dead = {new Cell with Alive = false}\r\n   let newcells = Array2.create world.Width world.Height dead\r\n   Parallel.For(0, world.Width, (fun i ->\r\n      for j = 0 to world.Height - 1 do\r\n         let ncount = neighbors world j i\r\n         match world.Cells.(i,j).Alive with\r\n         | true -> if ncount = 2 || ncount = 3 then newcells.(i,j) &lt;- alive\r\n                   else newcells.(i,j) &lt;- dead\r\n         | _ -> if ncount = 3 then newcells.(i,j) &lt;- alive\r\n                  else newcells.(i,j) &lt;- dead\r\n      done\r\n   ))\r\n   { world with Cells = newcells}\r\n<\/pre>\n<h3>Source code<\/h3>\n<p>Here are the available downloads<\/p>\n<ul>\n<li>un-parallelized version, <a href=\"http:\/\/www.mariusbancila.ro\/archives\/fsharp\/GameOfLife.zip\">GameOfLife.zip<\/a><\/li>\n<li>parallelized version, <a href=\"http:\/\/www.mariusbancila.ro\/archives\/fsharp\/GameOfLife.Parallel.zip\">GameOfLife.Parallel.zip<\/a><\/li>\n<\/ul>\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Game of Life is a cellular automaton devised by the John Horton Conway in 1970. It is the best-known example of a cellular automaton. It consists of a collection of cells which, based on a few mathematical rules, can live, die or multiply. Depending on the initial conditions, the cells form various patterns throughout &#8230; <a title=\"Game of Life in F#\" class=\"read-more\" href=\"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/\" aria-label=\"Read more about Game of Life in F#\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[37],"tags":[51,50,49,47],"class_list":["post-123","post","type-post","status-publish","format-standard","hentry","category-fsharp","tag-automata","tag-f","tag-gameoflife","tag-parallel"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"automata,f#,gameoflife,parallel\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Game of Life in F#\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2008-05-08T19:39:11+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2010-04-09T09:23:16+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Game of Life in F#\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#article\",\"name\":\"Game of Life in F#\",\"headline\":\"Game of Life in F#\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"\\\/blog\\\/wp-content\\\/uploads\\\/2008\\\/05\\\/gameoflife.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#articleImage\"},\"datePublished\":\"2008-05-08T14:39:11+02:00\",\"dateModified\":\"2010-04-09T11:23:16+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":2,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#webpage\"},\"articleSection\":\"F#, automata, F#, gameoflife, parallel\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/#listItem\",\"name\":\".NET\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/#listItem\",\"position\":4,\"name\":\".NET\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/fsharp\\\/#listItem\",\"name\":\"F#\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/fsharp\\\/#listItem\",\"position\":5,\"name\":\"F#\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/fsharp\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#listItem\",\"name\":\"Game of Life in F#\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/#listItem\",\"name\":\".NET\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#listItem\",\"position\":6,\"name\":\"Game of Life in F#\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/fsharp\\\/#listItem\",\"name\":\"F#\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/\",\"name\":\"Game of Life in F#\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2008\\\/05\\\/08\\\/game-of-life-in-f\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2008-05-08T14:39:11+02:00\",\"dateModified\":\"2010-04-09T11:23:16+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Game of Life in F#","description":"","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/","robots":"max-image-preview:large","keywords":"automata,f#,gameoflife,parallel","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#article","name":"Game of Life in F#","headline":"Game of Life in F#","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"\/blog\/wp-content\/uploads\/2008\/05\/gameoflife.png","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#articleImage"},"datePublished":"2008-05-08T14:39:11+02:00","dateModified":"2010-04-09T11:23:16+02:00","inLanguage":"en-US","commentCount":2,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#webpage"},"articleSection":"F#, automata, F#, gameoflife, parallel"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/#listItem","name":".NET"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/#listItem","position":4,"name":".NET","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/#listItem","name":"F#"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/#listItem","position":5,"name":"F#","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#listItem","name":"Game of Life in F#"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/#listItem","name":".NET"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#listItem","position":6,"name":"Game of Life in F#","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/#listItem","name":"F#"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/","name":"Game of Life in F#","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2008-05-08T14:39:11+02:00","dateModified":"2010-04-09T11:23:16+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Game of Life in F#","og:url":"https:\/\/mariusbancila.ro\/blog\/2008\/05\/08\/game-of-life-in-f\/","article:published_time":"2008-05-08T19:39:11+00:00","article:modified_time":"2010-04-09T09:23:16+00:00","twitter:card":"summary","twitter:title":"Game of Life in F#"},"aioseo_meta_data":{"post_id":"123","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:13:46","updated":"2025-12-12 07:19:10","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":2,"uagb_excerpt":"The Game of Life is a cellular automaton devised by the John Horton Conway in 1970. It is the best-known example of a cellular automaton. It consists of a collection of cells which, based on a few mathematical rules, can live, die or multiply. Depending on the initial conditions, the cells form various patterns throughout&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/\" class=\"advgb-post-tax-term\">F#<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">F#<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/\" class=\"advgb-post-tax-term\">automata<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/\" class=\"advgb-post-tax-term\">F#<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/\" class=\"advgb-post-tax-term\">gameoflife<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/fsharp\/\" class=\"advgb-post-tax-term\">parallel<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">automata<\/span>","<span class=\"advgb-post-tax-term\">F#<\/span>","<span class=\"advgb-post-tax-term\">gameoflife<\/span>","<span class=\"advgb-post-tax-term\">parallel<\/span>"]}},"comment_count":"2","relative_dates":{"created":"Posted 18 years ago","modified":"Updated 17 years ago"},"absolute_dates":{"created":"Posted on May 8, 2008","modified":"Updated on April 9, 2010"},"absolute_dates_time":{"created":"Posted on May 8, 2008 2:39 pm","modified":"Updated on April 9, 2010 11:23 am"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-1Z","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/123","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=123"}],"version-history":[{"count":1,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/123\/revisions"}],"predecessor-version":[{"id":521,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/123\/revisions\/521"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}