This is a short post to mention the entries to the Game of Life challenge.
If you recall, I recently found a Wikipedia page about Conway’s Game of Life, a raster grid where each cell either lives or dies according to a set of rules, producing a new grid to repeat the process. The result is a living grid that could (depending on the starting positions) look like this:
The challenge was to use FME to implement the rules of the Game of Life, and produce an output demonstrating it.
I posted the challenge, and got solutions, on this page of our Knowledge Centre. Only two users (Takashi, and Joanna) submitted entries, but they each submitted multiple attempts, each improving on the last. They used a variety of technologies too: raster, point clouds, python, loops, variables, xml, and even databases. There were a lot of comments going back-and-forth and I think they enjoyed discussing the challenge as much as I enjoyed watching that discussion.
I’m not going to go into every submission in depth, or post a ton of screenshots, but I’m going to flag the different techniques used in each – that way if you are interested in examples of particular functionality you can look it up. If nothing interests you, then I looked up songs that had the phrase “Game of Life” in them, and posted them at the foot of the article for your amusement!
Joanna #1: Look at the timestamp on Joanna’s post. She submitted this just 4 hours after I posted the challenge! That’s amazing considering it contains a custom transformer with a “blocking” loop, one where the loop contains a group-based transformer. That’s pretty advanced stuff and this is a great example of that functionality. Joanna uses a point grid, each point representing a cell. The NeighborFinder finds the neighbors for each cell from which she calculates the alive/dead status and then converts the point grid to a raster. Using the AnimatedGIFWriter from the FME Store/Hub allowed her to animate the output. Find the custom transformer here and the workspace here.
Takashi #1: Takashi added to the challenge by deciding to do the task without using a blocking loop. He does this by not using spatial data, but by storing the data as a string of 1’s and 0’s; for example 00110101010101 etc. He then processes each cell by examining the contents of that string, thus avoiding a blocking transformer. The results go to build up the string for the next iteration. Finally the data is converted back to a raster image and written out. It’s brilliantly done – I just can’t decide whether the technique counts as best practice! Judge for yourself by downloading it from here.
Takashi #2: Next Takashi decided to try the task but using traditional raster, rather than a string of data. He uses a Master-Slave arrangement of two workspaces. The master workspace starts the process, creates the original dataset, then runs the slave workspace once per iteration. There’s (currently) not an option in the RasterResampler to sum the 8 surrounding squares, so Takashi creates 8 copies of the grid and offsets each left/right/up/down to stack the squares to sum vertically. Then he adds them together with a RasterBandCombiner. It’s a good example of using the WorkspaceRunner transformer in a master workspace to run a slave workspace n number of times, and you can find his workspaces here.
Takashi #3: Takashi’s third effort is a way smaller workspace, but that’s because much of the processing is contained within a Python script. This approach shows how tidy a workspace can be by embedding Python, but also how hard it is for other users to interpret. I certainly can’t look at it and tell what is happening the same way as a plain workspace. Seems to me that it uses an FME list and a Python array to do the work. You can download it here to see for yourself.
Joanna #2: Joanna’s second effort was to carry out the task without a blocking loop. It still uses a loop, but not a blocking one. This is a great example of using lists in a workspace, but also the use of nested loops in a custom transformer. The data is stored as a list, each cell being an entry in that list, similar to Takashi’s string of values. The inner loop runs through each element in the list, processing it, while the output loop repeats that process once per iteration. It’s a classic list-loop in FME, using the ListElementCounter, ListIndexer, and Tester transformers. If you need to create a loop using lists, it’s worth checking out her example here.
Takashi #4, #5, #6: I won’t go into too much detail, but attempt #4 was a way to run the process without using a loop at all. Instead it uses Cloners like my own Cloner-Loop technique. It’s a great example of that technique, plus the use of VariableSetter/Retrievers. Attempt #5: XML! You all love XML, don’t you? It’s a classy workspace that uses the XMLTemplater, TempPathnameCreator, XMLFragmenter, and a lot more; a great example of using more obscure transformers in the right place at the right time. And finally, attempt #6: a SQLite database! This uses the SQLExecutor to calculate the game-of-life rules using a join and union command.
Mark #1: It only seems fair that I share my solution too. It was a mix of what Joanna and Takashi had done. I knew it wasn’t possible to use a single raster feature with (say) 100 cells, so I split it up and created 100 raster features, each with only a single cell! With that it was simple to apply the NeighborFinder, using the new(ish) Number of Neighbors to Find parameter, creating a list of values that I could sum together. I implemented it using the Master-Slave layout and used the AnimatedGIFWriter to create the output. The major stumbling block was timing – the master workspace has to read back the slave’s results before the slave process is triggered again. So the slave has a Decelerator transformer inside it, and the master has a RasterCheckpointer and FeatureHolder to make sure the processing order is correct.
Personally I think this was a great challenge and both Takashi and Joanna made some fantastic, well-designed workspaces. I’ve awarded them 100 reputation points each in the knowledge centre. I also went back to the FME Golf challenge and awarded reputation to the contestants there – between 10 and 100 points, depending on your score. Kim, Roland, Ulf, Yves, Nariman – I couldn’t find an account for you to add the points to, so create an account if you can and I will add them now.
The current “challenge” on the knowledge centre is much easier: all you have to do is let us know your highlights of the recent FME World Tour. I’m torn between the What3Words contest and the great FMECoin photos. What’s your favourite?
Game of Life Songs
Can you spot the phrase “Game of Life” in these songs? Goin’ Back has been recorded many times, but my favourite is by The Icicle Works:
I also found “Promised You a Miracle” by Simple Minds, and “Intuition” by John Lennon.
Mark IrelandMark, aka iMark, is the FME Evangelist (est. 2004) and has a passion for FME Training. He likes being able to help people understand and use technology in new and interesting ways. One of his other passions is football (aka. Soccer). He likes both technology and soccer so much that he wrote an article about the two together! Who would’ve thought? (Answer: iMark)