{"id":756,"date":"2019-12-09T04:22:03","date_gmt":"2019-12-09T04:22:03","guid":{"rendered":"https:\/\/www.danielparente.net\/en\/2019\/12\/09\/game-of-life-with-flutter-flutter-community\/"},"modified":"2019-12-09T04:22:03","modified_gmt":"2019-12-09T04:22:03","slug":"game-of-life-with-flutter-flutter-community","status":"publish","type":"post","link":"https:\/\/www.danielparente.net\/en\/2019\/12\/09\/game-of-life-with-flutter-flutter-community\/","title":{"rendered":"Game of Life with Flutter &#8211; Flutter Community"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<div>\n<div class=\"ep\">\n<div class=\"n eq er es et\">\n<div class=\"o n\">\n<div><a rel=\"noopener\" href=\"https:\/\/medium.com\/@c.muehle18?source=post_page-----1b7e105e585e----------------------\" target=\"_blank\"><\/p>\n<div class=\"eu ev ew\"><img decoding=\"async\" alt=\"Christian Muehle\" class=\"r fe ew ev\" src=\"https:\/\/miro.medium.com\/fit\/c\/96\/96\/2*33dep1N4p1DanY6KzQIz9A.jpeg\" width=\"48\" height=\"48\"\/><\/div>\n<p><\/a><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Photo by <a href=\"https:\/\/unsplash.com\/@hjmckean?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Heather McKean<\/a> on <a href=\"https:\/\/unsplash.com\/s\/photos\/game-of-live?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Unsplash<\/a><\/figcaption><\/figure>\n<p id=\"d079\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">I would like to show you a version of Game of Life build with Flutter. My intention was to get some insights on the following topics:<\/p>\n<ul class=\"\">\n<li id=\"5c96\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij ik il\">Custom drawing \u2014 create your own UI-elements<\/li>\n<li id=\"9f67\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii ij ik il\">Very basic \u201cgame\u201d approach \u2014 game loop<\/li>\n<\/ul>\n<p id=\"a661\" class=\"hv hw ef at hx b hy jf ia jg ic jh ie ji ig jj ii\">Let\u2019s first start with a brief intro explaining what \u201cGame of Life\u201d is actually about. In case you know the board game called \u201cGame of Life\u201d I have to disappoint you \u2014 the game we are building here is a bit different. Below is the summary in my words, feel free to skip this and check the great <a href=\"https:\/\/en.wikipedia.org\/wiki\/Conway%27s_Game_of_Life\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Wikipedia article<\/a> directly.<\/p>\n<figure class=\"gr gs gt gu gv gw\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Not the Game of Life we are looking for &#8211; By <a href=\"https:\/\/gph.is\/2kaRrEv\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">GIPHY<\/a><\/figcaption><\/figure>\n<p id=\"87c6\" class=\"hv hw ef at hx b hy jf ia jg ic jh ie ji ig jj ii\">The game shows a board of cells which can either be alive or dead. Every turn, each cell gets checked and a new state (dead, alive) is calculated based on the current game board. The rules are quite simple \u2014 a cell will only change the state based on the following rules:<\/p>\n<ol class=\"\">\n<li id=\"74b1\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii jl ik il\">Any living cell with &lt; 2 live neighbors will be changed to dead in the next round<\/li>\n<li id=\"5bf6\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">If a dead cell has 3 living neighbors it will get alive in the next round<\/li>\n<li id=\"87bf\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">Any living cell with either two or three live neighbors (in all directions) will not change the state in the next round<\/li>\n<li id=\"305d\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">Any living cell with more than three neighbors will die in the next round<\/li>\n<\/ol>\n<p id=\"8639\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The game will run infinitely and every round will introduce a new generation of cells until all cells are dead or spread across the board in a way that they can&#8217;t interact with other cells according to the described rules above.<\/p>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"><figcaption class=\"ax fi hm hn ho dq do dp hp hq as cx\">Photo by <a href=\"https:\/\/unsplash.com\/@hjmckean?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Heather McKean<\/a> on <a href=\"https:\/\/unsplash.com\/s\/photos\/code?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Unsplash<\/a><\/figcaption><\/figure>\n<p id=\"56ec\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The complete project is hosted on GitHub. Please note, I\u2019m new to Flutter so please excuse any code smells you might spot:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"ed14\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">To start, either create a new flutter project or simply clone my repository. I will skip the project creation, in case you need a helping hand check out the great <a href=\"https:\/\/flutter.dev\/docs\/get-started\/install\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Flutter starting guide<\/a>.<\/p>\n<p id=\"9f7c\" class=\"hv hw ef at hx b hy jf ia jg ic jh ie ji ig jj ii\">We can divide the code into three main areas of tasks:<\/p>\n<ol class=\"\">\n<li id=\"d889\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii jl ik il\">The main widget \u2014 gets all parts of the game together<\/li>\n<li id=\"1fcb\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">The game logic class \u2014 all game rules are applied in here<\/li>\n<li id=\"8a90\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">The drawing department \u2014 drawing of the cells is handled in here<\/li>\n<\/ol>\n<p id=\"d7f4\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">If you\u2019re wondering why the code is split up like this, at first I like to separate code by its actual job and secondly I might want to reuse the game logic code (which is pure dart code) for other projects.<br \/>For example, we could set up a Game of Life web version using dart and the logic class from the Flutter project\u2026<\/p>\n<figure class=\"gr gs gt gu gv gw do dp paragraph-image\"\/>\n<p id=\"c727\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">To keep it short, the job of the main widget is to bring everything together and provide sizing information to our drawing department. Most of the code inside the <a href=\"https:\/\/github.com\/Dev-Owl\/GameOfLife\/blob\/master\/lib\/main.dart\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">main.dart<\/a> file is nothing special, nevertheless I would like to point out the more interesting places to get you started:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"6496\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The first line creates our logic class, it will be used to interact with our game. To get a new board and ensure the app is running in fullscreen during startup we use the <em class=\"le\">initState<\/em> method.<br \/>Thanks to the <em class=\"le\">_game<\/em> object we can simply call <em class=\"le\">resetWorld()<\/em> and get a fresh new start. The last method in the code allows the app to toggle the game between running or paused mode, the call to <em class=\"le\">setState <\/em>ensures that Flutter will update the UI accordingly.<br \/>To have something we can start\/pause we need a so called game loop. This loop is handled by our logic object (<em class=\"le\">_game<\/em>) but somehow we have to update our UI after each iteration to make sure our App shows changes. I decided to use a <em class=\"le\">StreamBuilder <\/em>for this job \u2014 with every loop the <em class=\"le\">StreamBuilder <\/em>gets a notification to update the UI.<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"2bc0\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">You might spot a bit more in the above code. It includes the callback to our toggle methods to start\/pause the game and also some size calculation for the cells. I will explain most of it in the following parts.<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"a8f1\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">To get the game started we have to fill the world, this job is done by the code below:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"1762\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The board itself is a simple <em class=\"le\">List<\/em> of boolean values. The <em class=\"le\">resetWorld<\/em> function performs the following steps:<\/p>\n<ol class=\"\">\n<li id=\"7653\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii jl ik il\">Fill the world with dead cells, from zero to <em class=\"le\">worldSize<\/em> (right now 1024 cells)<\/li>\n<li id=\"9f28\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">Getting a random number of cells up to 50% of the world size, see <a href=\"https:\/\/api.dartlang.org\/stable\/2.5.2\/dart-math\/Random\/nextInt.html\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">documentation for nextInt<\/a><\/li>\n<li id=\"0015\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">Mark cells as living until we reached the limit generated in our second step<\/li>\n<\/ol>\n<p id=\"c2b1\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">You might have noticed that the above logic could end up with less active cells as our second step decided. This is due to the fact that the third step doesn\u2019t check if the randomly selected cell is already active, it could happen that we set the same cell active twice.<\/p>\n<h2 id=\"6f21\" class=\"lg is ef at as it lh li lj lk ll lm ln lo lp lq lr\">Ready to go<\/h2>\n<p id=\"93b5\" class=\"hv hw ef at hx b hy jf ia jg ic jh ie ji ig jj ii\">Our game is ready to start, now we need to take care of the game loop that will update the cells based according to the game rules.<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"e4bc\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Game updates are handled by the <em class=\"le\">_runTheGame<\/em> Method. To ensure the loop is running \u201cslow\u201d enough it starts with sleep, our app will wait 350ms before it calculates the next round.<\/p>\n<p id=\"f628\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">This part might look complicated but it solves a problem that all Game of life implementation face:<\/p>\n<blockquote class=\"ls\">\n<div id=\"22d3\" class=\"lt lu lv at eg b lw lx ly lz ma mb ii\">\n<p class=\"eg b mc md ax\">How do you handle cells at the edge of the board?<\/p>\n<\/div>\n<\/blockquote>\n<p id=\"03c2\" class=\"hv hw ef at hx b hy me ia mf ic mg ie mh ig mi ii\">In my app the board has no real edges, if you are on the far right side and go one step to the right you will end up on the first left position. The same for the top or bottom end of the board, if you step over the edges you will end up on the opposite side. <br \/>It might remind you of the old <a href=\"https:\/\/www.google.com\/logos\/2010\/pacman10-i.html\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">Pacman game<\/a>.<br \/>The complete calculation to apply the game rules is done by changing the index inside the array to check all surrounding cells, left, right, top, bottom and diagonal.<\/p>\n<p id=\"1e5b\" class=\"hv hw ef at hx b hy jf ia jg ic jh ie ji ig jj ii\">Getting the logic on the screen is the job of our drawing department, in this game we don\u2019t require a lot of elements. Everything we need for custom drawing can be found in the code below.<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"41c0\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Flutter contains the great and easy to use <a href=\"https:\/\/api.flutter.dev\/flutter\/rendering\/CustomPainter-class.html\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\">CustomPainter<\/a>, the main idea is quite easy, it has two jobs:<\/p>\n<ol class=\"\">\n<li id=\"c9bb\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii jl ik il\">Draw the element with the provided size on the given canvas<\/li>\n<li id=\"e814\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii jl ik il\">Decide if you need to draw your element again<\/li>\n<\/ol>\n<p id=\"912a\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Our cells will be represented by a rectangle with rounded edges, the color depends on the cell state. Living cells will be green, dead cells will be orange.<br \/>Drawing the rectangle is done by the build in function <a href=\"https:\/\/api.flutter.dev\/flutter\/dart-ui\/Canvas\/drawRRect.html\" class=\"dc by hr hs ht hu\" target=\"_blank\" rel=\"noopener nofollow noreferrer\"><em class=\"le\">drawRRect<\/em><\/a><em class=\"le\"> <\/em>you need to pass a rectangle with size, position and the radius for the edges<em class=\"le\">.<\/em><\/p>\n<p id=\"dfb0\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">A cell has to be painted again only if:<\/p>\n<ul class=\"\">\n<li id=\"a335\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii ij ik il\">The position or size of the cell has changed, for example, because the user rotated the phone<\/li>\n<li id=\"6ce6\" class=\"hv hw ef at hx b hy im ia in ic io ie ip ig iq ii ij ik il\">The cell state changed, a living cell died or the other way around<\/li>\n<\/ul>\n<p id=\"ecb8\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Last puzzle piece is to arrange all cells in a way that our app renders the board, this is done by the code below:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"8b58\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">The big idea behind the code is to draw the board row by row based on the calculated sizes.<\/p>\n<p id=\"d457\" class=\"hv hw ef at hx b hy jf ia jg ic jh ie ji ig jj ii\">First, Flutter is awesome, I tried a lot of cross-platform development tools but I have to admit that Dart and Flutter are easy to start and the provided tooling just works ( I\u2019m using Linux, tested it also on Windows).<\/p>\n<p id=\"8e2e\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Creating custom UI elements is made in a logical two-step implementation, decide what you want to draw and when to redraw.<\/p>\n<p id=\"bb95\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Game of life itself can be implemented in many ways, for myself it\u2019s always a good way to test out a new platform\/language. Besides the technical point of view, I like to watch and see how a randomly created board develops into different patterns or simple fades out or gets stuck in a repeating motion.<\/p>\n<p id=\"da8f\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">If you are curious about all the different shapes\/pattern Game of life might generate check out the following resources:<\/p>\n<p id=\"2718\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">If you want to see an epic version of Game of life:<\/p>\n<figure class=\"gr gs gt gu gv gw\"\/>\n<p id=\"f84a\" class=\"hv hw ef at hx b hy hz ia ib ic id ie if ig ih ii\">Thanks for reading<\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"https:\/\/medium.com\/flutter-community\/game-of-life-with-flutter-1b7e105e585e?source=userActivityShare-d061b690ce09-1575145771&#038;_branch_match_id=729421149678234989\" target=\"_blank\" rel=\"noopener\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Photo by Heather McKean on Unsplash I would like to show you a version of Game of Life build with Flutter. My intention was to get some insights on the following topics: Custom drawing \u2014 create your own UI-elements Very basic \u201cgame\u201d approach \u2014 game loop Let\u2019s first start with a brief intro explaining [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":757,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1],"tags":[],"class_list":["post-756","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"blocksy_meta":[],"jetpack_featured_media_url":"https:\/\/e928cfdc7rs.exactdn.com\/info\/uploads\/sites\/3\/2019\/12\/Game-of-Life-with-Flutter-Flutter-Community-scaled.jpeg?strip=all","jetpack_shortlink":"https:\/\/wp.me\/p2TFCd-cc","jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts\/756","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/comments?post=756"}],"version-history":[{"count":0,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/posts\/756\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/media\/757"}],"wp:attachment":[{"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/media?parent=756"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/categories?post=756"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.danielparente.net\/en\/wp-json\/wp\/v2\/tags?post=756"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}