Thanks for this - nice to see it done in a modern language! I wrote this in BASIC on an 8-bit computer many moons ago, but each iteration took more than a minute, so I rewrote it to use a single 2-D grid. The state was held in the least significant bit, i.e. odd values were alive, evens were dead. I started with only 0 or 1 values, then scanned the array. If a cell was odd, I added 2 to each of the surrounding 8 cells, otherwise I skipped, saving a lot of processing time. Next I scanned the grid and if a cell contained 5, 6 or 7 the cell was alive so I made it 1, otherwise it was dead so I made it 0. This change got the processing time for each iteration down to a few seconds.
Nice to see the old tricks to save memory and processing! Even if i never had to deal with those early computer ;-) i do try those kind of tricks (i've done a bit af asm for game cheat or modding, i think its there i learn to work on bits). On mine like you i only consider alive cell but instead of adding 2 to there own value i left shift their dedicated neighbour value (firstly set to 1) so i could use 2 mask of rule (each bit corresponding to an amount of neighbours with the least significant meaning 0) so with the same binary AND between those value i can compute next state no matter what the rules are. and since left shifting and binary AND are really easy for computer it's a bit faster than adding and testing (but apparently not in js... still quite the same ^^) Here is my implementation but don't mind the code it's too messy (implementing stuff over stuff over stuff ... etc ... one day i will refactor it ^^) vassilyd.github.io/GameOfLife/ (And by checking that 4 year old code i realised that what i was saying before was only idea i was about to implement... but never done it... right now it still work by incrementing, but do use a binary AND for test) I do like the 4,5,6 birth and 2,3,4,5 survive rules, thing turn into linear stable shape (i mean only horizontal, vertical and diagonal line) for the outside with unstable kinda glowing inner + those shape slowly grow and merge until they have only those linear outside line, i call this mode "crystal mode" ^^ (one day i should also implement a selection option of some nice rules like this one)
You’ve got me thinking now, I almost want to go write this in batch. Which, you know, doesn’t have arrays (and I’m not going to sit there and enter 80x80 variables either 😂 if you wish it has arrays hard enough you can just pretend it does and write the code anyway. I did Minesweeper in batch earlier this year, the underlying concepts are pretty similar (counting neighbours), the trick would be switching between two “boards” but I don’t see why you couldn’t, in Minesweeper I pre-computed the counts because it’s slow doing it while playing. I wonder what would run faster, your GWBASIC implementation on a couple MHz computer of the day, or the batch version on a modern GHz machine. I don’t really miss basic, but there are times when I’d consider some good ‘ol GOTO for nostalgia. I bet it would be close, because batch is… Yeah.
@@thedave1771 Oh to have the time to play with coding again! Batch probably allows a text string of 6400 characters which could be manipulated to contain a two-dimensional array. I used the method described with a single array as only the eight cells surrounding a living cell need accessing, rather than the eight cells surrounding every cell, making the process several times quicker.
@@clivemitchell3229 there’s actually a way to include a variable inside another variable’s name, so if you wish hard enough can have an “array” accessible as %myarray[%%x,%%y]% and it’s a lot faster than pulling arbitrary characters out of a huge string. It’s not an array, just loose variables, but if we’re all okay with pretending JavaScript has arrays… Setting is easy, reading is harder, and of course you’re writing your own functions for every little thing. I just can’t bring myself to like Powershell. I should, if you asked me to describe what I want in a CLI it would look a lot more like Powershell than anything else out there, but the only thing I find enjoyable about writing Powershell is being finished, so I end up in batch. I really should stop.
Perfect for training list, of course there´s easier ways to do it, but there are also people who need these kind of videos, this guy is th Bob Ross of coding
I really love the “game of life” , it on my Mac screen saver too, really enjoy the way you explain how the code works, checking the rules and then wrap around logic. Pls keep up the great work!!!
Thank you, Daniel, another instructive and fun video. You‘re such an inspiration to me. Please keep on. I „co-programmed“ Asteroids following your suggestions, now I‘m working on Solitaire, learning the hard way how the loop() function is actually an interrupt, thus it is difficult to expect some variables to be set by functions called AFTER the loop() call😂
Took me a few months of very interrupted work, but i got it working just with the processing reference and my knowledge of classes. It's super inefficient, but it works beautifully.
Dan, maybe someone already told you this, but I couldn't help noticing... In the live video last Friday you laughed at the suggestion of the Game of Life on a torus. But, ironically, this is exactly what you've done. Think about it... Wrapping left to right is equivalent to making the flat map into a cylinder. And then wrapping top to bottom takes that cylinder and bends it around so it forms a torus! The only thing you didn't do is render it in 3D. Now, that would be a coding challenge. :)
That makes sense since you can think about a long rectangle being curled into a hollow cylinder, and then the circles on the end curled around to touch each other - and since opposing edges on a rectangle are the same length by definition, this will all match up exactly. The only problem is when it's too square, it'll have to be stretched a lot...
You know what would be even nicer? By changing the direction in which you wrap you could simulate the Game of Life on a Mobius strip, or even on a Klein bottle! *Laughs Mathematically* simple.wikipedia.org/wiki/Klein_bottle simple.wikipedia.org/wiki/M%C3%B6bius_strip
If anyone is interested, i made exactly this! I put it up on this website: eirik.tech/Game-of-life/index.html Feel free to check out the source code too: github.com/eirikhalvard/game-of-life
When the cells just stay in one spot, We know they have gotten too smart, We know that they are building civilization, And we know they are going to war.
haha. Then I guess the most intelligent cells are those that join together to form a square? That seemed to be the most common "stable" shape. (That is if I did it right : (
I have a small coding challenge idea. Imagine a grid of dots, like a really big grid. And when you click on any part of the grid, it creates an illusion of a ripple effect, like you're looking at water from a top-down view. And the illusion will be created by manipulating the size of dots (or circles if you will, since they will get bigger and smaller)
wouldnt this work by just making every cell next to a live cell switch states? It wouldn't be a circular, it would be more like a roughly rotated square increasing in size but it would be a "ripple" effect
Sooo weird - I just discovered this channel with your old CA videos a few days ago and then here's this new video. My current Introduction to Programming/Java project is to make a tic tac toe game, and that seems so much less daunting after soaking in all of this witchery. lol I'm quite keen on trying to tackle The Game of Life. It's so helpful seeing a professional programmer's process step-by-step like this. Thanks!
I was watching some interviews with John Conway recently and it occurred to me that since he grew to hate the Game of Life, it would be an appropriate way to celebrate his life and legacy. And also it’s just about the only thing he did that I can genuinely understand well enough to explain it, his contributions to higher math are… Impressive. I wanted to do it a bit differently though, in that I wanted to support no fixed board size. In particular if you start four gliders going up, down, left and right, it should run until they exceed the 2^32 board. This means they can take 2^31 steps in any direction, although since a step takes at least two generations we’re helpfully back to at least 2^32 generations before encountering the border. I ended up using sparse storage for the cells, so the 4 gliders will take the same RAM (and CPU) whether they’re a few squares apart or are 2^30 away in each direction. and I don’t need to purchase the 2exabytes of storage to maintain the board. The calculate function can impose borders, which turned out to be trivially simple (no need to do bounds-checks while computing, for example), I just don’t calculate neighbours beyond the range and therefore they’re automatically dead. Since you can query and cell, the neighbours function doesn’t need to “not” check beyond borders, it just sees dead cells. Technically this reduces the theoretical board by 1 in every direction but the implementation is so trivially simple. Next up, I want to multithread the generations so I can throw all 20 of my CPU cores at it, and down the road it might be interesting to use a GPU for calculations too, but that’s well beyond my abilities right now. How to visualize it? That’s easy, you can’t. The viewport can be moved anywhere, and can return whatever size you want, but I am not attempting to render beyond 1 pixel per cell and I’m not aware of any patterns that are designed to work with 4x or more cells comprising of a single pixel, so a true zoom wouldn’t be that useful. Or would it? It took about 45 minutes to write the backend, but I’ve spent a bunch of hours here and there playing with the UI as I decided I wanted no flickering, and to use colour to represent the distance from the centre point, and since I’m a console monkey, the interface has been the learning curve. I did write an interactive console version first, then a UI using the same backend. I want to eventually do a iOS and Android version as well, just to toss it in the portfolio. The colour effect turned out so nice that I decided to give the option to render the colour gradient over ~1000 steps, so a reasonably large monitor can visualize the effect. I’ve never before made anything I found visually appealing, nor do I usually care about such things, so it’s been an interesting challenge. Watching it in JS is amusing and fun, especially since I don’t know any JS at all.
Outstanding! I have been fascinated by the Game Of Life for decades. I've wanted to try my hand at coding it, but always wondered how to get it from one generation to the next. I'll try making each cell an object and see what happens!!!
Thank you so much for this! I was able to take your video tutorial and transfer the knowledge from it into Processing’s python library. I successfully coded the GameOfLife on my own! :)
I remember being assigned this as a project freshman year in my computer science program. I was able to get it working correctly but others did not. The trick was to start with an empty array as your next generation and calculate from the current generartion. We did no animate it, we just displayed 0s for empty cells and 1 for non empty cells.
Rather than having two 2d arrays, I gave each Cell (I made them objects) an "active" and "expected" boolean. The Active boolean was the "current" 2d array, and the expected boolean was for the next grid. I would loop through every cell, calculating the next state, and set the Expected boolean to match the desired state. The active state didn't change. Once I finished this iteration with every cell, I looped through the grid once more to set active to equal expected.
back when the IBM PC was a new computer, I wrote a game of Life for it. I think it was about 50 lines of TurboBASIC code. 2D arrays are easy-peezy in BASIC. You DIM and that's it. I used one array for the current state, and a second array I called WORK, which is where we built the new generation. Then I simply copied the Work array to the current array and displayed. My version was the only one I knew of that could save and load shapes. I made mine wrap also, and I allowed you to chose the size of your playing field as well as delay interval to control the speed. Yours looks good. You're a better man than I. I wouldn't even try that in Javascript.
I really love the way you work, the charisma, the good vibes all you make it's so good enough to make it interesting and incredible... I really enjoy your videos :-)
I know this video is really old at this point, but you could very easily just start a new array filled with zeroes, loop through the 'old' grid once, then for each 1 you encounter add one to the 'new' array, if a value reaches above 0 you add it to a separate 'alive' array, if a value reaches above 3 you remove it from the 'alive' array if it exists. Then, once you're done, simply redraw the original array, checking for each cell if it exists in the 'alive' array, and if so setting it to 1, if not setting it to 0. This way you only go through the original array once instead of counting neighbours for each cell, then in the drawing step you only check for values in an indexed array (that could be string keys (`x+'-'+y`)) and you basically end up with something that's 4x as fast as counting each neighbour.
Edge cases, simplified: if ( x > (cols-1)) x -= cols; // 10 becomes 0 if ( x < 0) x += cols; // -1 becomes 9 if (y > (rows-1)) y -= rows; // 10 becomes 0 if (y < 0) y += cols; // -1 becomes 9
The video is really helpful for me because this game was a few years ago on the matura exam in Poland so I enjoy watching you code the game. Greetings from Poland, dude :D
as I promise: github.com/dhvalden/learning_python/blob/master/my_game_of_life.py However, I just translated it to Python, but I haven't been successful in adding another features :( part of the learning process I guess
The Game of Life has been my primary interview question (though I also have a few graph/algorithm questions for variety.) It's great because it leads to obvious extensions, such as borderless with wrapping, and opens the discussion of how to make an infinite game of life, which many have difficulty answering. Finally, it's fun to introduce n-dimensional extension, and how to change existing loops to deal with multiple dimensions, and finally, how to make the system parallelizable for truly massive user experience. If they get through all that, they almost always get hired, and do great later.
That's really interesting. Do you mean infinite over time or over an infinite grid? In Python, I would start with a list of lists, and have add rows/columns whenever a live cell needs to be created outside the original lists, although the size of the list will grow exponentially. Parallelization is also very interesting, maybe dividing the board into slightly overlapping zones, each of which is processed by a separate thread, then stitching the zones together? I'm naively guessing, but the minimum overlap should be around 3 tiles, to make sure no cell at the border is confused.
Whenever I work with grids, I usually end up using a single array from top left to bottom right, and to check relationships, I use (i - gridsize) for up, where i is the number of the gridspace itself in the array, (i + gridsize) for down, (i + 1) for right and (i - 1) for left. Getting edges is a little harder, where if i % gridsize is 0 then you're on the left edge and if if i % size is equal to size - 1 then you're on the right edge, but that doesn't handle having different x and y sized very well. In that case, I guess having two variables, rowSize and columnSize could suffice, though.
rather than fixed arrays, use twin dual circular linked lists of "active" cells; then you have an undefined infinite grid. The "Life" can grow ad hoc forever, and you never have to consider the entire grid... only the cells that are active. marcus
I'm not sure what you mean but have you implemented that? It sounds like it doesn't take into consideration the fact that during each cycle of the simulation the generation of the next cycle has to take into consideration that all the cells have to be processed before making changes to any cell.
@@dannygjk Not necessarily, for example i've done it by only processing the alive cell, incrementing each neighbour's neightbourAmount value first then indeed i still process it for all cell, i guess i could also ignore cell with no alive neightbour here, but only in base rules, if you use another rule that specify birth with 0 neighbours then you have to process all cell... It all depend on how far you wanna extend the possibility ;-) Anyway indeed a linked list type (with also a link to each neighbour in cell object) could allow an infinite grid, as long as your computer handle it ^^ (but not sure how to handle interactivity, without getting too laggy, since to get a particular position you need to go through the whole list, don't you?)
@@dannygjk Yes cause i wanted a GOL that can work with any rules (including a 0 neighbours rule for birth...). but like i said if you stick to the base one there is no reason to process dead cell not surrounded by at least one alive cell. So you could only process alive cell and their neightbours in the second loop too. For Mark idea to work i guess he would need at least an x and y property in his cell object and a pointer to each neightbours + a previous and next pointer. In that list you will only have alive cell and their neighbour, creating new one when needed and eventually destroying those that become isolated (or use a secondary list where all isolated cell goes and not get processed but can be switch back to the active one at any time). And for the rendering, during the process you save minimum and maximum of x and y of cells and there you know the needed size of the grid. I'm not saying this is what Mark was talking about but might be close enough ^^ Anyway i do prefer using 2D array for that (also array can be extended even if it could get messy ^^)
@@SylouCool I found that keeping it simple seemed to work fastest for the 'normal' living/dying rules tho I was working with only cells that fit in the display. I would scan for live cells then increment the neighbor count for the surrounding cells in a neighbor count 2D array.
The starting point for The Game Of Life is always two, two-dimensional arrays. If you make each array two indexes "wider" and "taller" than your display, this simplifies the coding since positions -1 and +1 to the pixel which you are calculating will always exist and so you won't need any "exception processing" to handle the edges of the map. You flip the "working" array (which is the one to be displayed) between the two arrays, with the other array being the "target" array. The calculations are done on the "working" array and the results are placed in the "target" array. Once all pixels have been calculated, the arrays are switched and the new "working" array is displayed. If done correctly, the array elements along each edge (beyond the displayed range) are never calculated and so always stay "dead." Of course, you can always decide to challenge yourself and make the field "wrap around" so that the pixel on the furthest-right of the screen in a particular row is considered to be a neighbour to the furthest-left pixel in the same row, but this requires slightly more complicated logic. Which I now see was actually done in this video, in spite of the fact that by default the game's rules assume that the field does not wrap around.
A lot of this code is really similar to the framework i used to build my minesweeper clone in python. An idea i had about updating the grid would be to make a 3D array with the extra nested array being there to hold a value which basically makes sure each cell “remembers” whether it must change or not. After setting that value for each cell, you would then check it for each cell, if it’s a 1, change it, if it’s a 0, leave it alone, set it to 0, and then you have your next grid. I have no idea whether this solution is efficient or not but i personally like it
When you're doing 2D arrays it's WAY better that your "Initial array" is of the rows and inside each row there's the column. Not only is that how it's normally done when doing stuff with Matrices, but also, it's far better to have your outer loop be the Rows (which tends to be less than the columns), and then iterate through each cell in that row.
You actually don't need two grids, since each cell is either on or off, you can use the first bit to represent the current state and the the second bit to represent the previous (or next state) so basically you fill the grids with 0,1,2 and 3
I recently made the game of life in minecraft as a datapack, and I get recommended this. *_RUclips knows everything. RUclips sees everything. RUclips is everything._*
It’s a different game if you play it on a torus. Better to implement it as a list of live cells. Each generation then consists of first generating a list of neighbors by incrementing a counter for each of the eight cells around each live cell. Then generating the next list of live cells by examining the state and count of each entry in that list. This allows for an arbitrarily large grid, implements the game correctly, and makes it much easier to detect and deal with repeating and traveling patterns.
for anyone that needs the branchless version for calculating next state: (assuming you are using an array of booleans for handling state) int counter = sum of all 8 booleans around current[xy]; current[xy] = previous[xy]; current[xy] = current[xy] and (counter == 2); current[xy] = current[xy] or (counter == 3); same behaviour as: if(counter == 3) { current[xy] = true; } else if(counter != 2) { current[xy] = false; } else { current[xy] = previous[xy]; }
Love your vids, thank you so much for your service here. Once I heard you started with lingo like myself it all made sense why your methods clicked so well. cheers
This is awesome! I have a couple of pretty rudimentary ideas that I want to do. I love the idea of being able to "draw" on it, so I'm going to implement that. I also want to make it pretty! So I'm going to cycle through a rainbow of color values and, for every generation, I'm going to change the fill color for live cells. It'll be a rainbow explosion!
I'm racking my brain trying to figure out where "width" and "height" were defined at 13:49 at line 16 you have: 'cols = width / resolution' But I don't see width defined anywhere else in the code, what am I missing?
I think it’s the language or environment he’s using, some default variables we don’t see. When he checks for mousePressed(), for instance, he uses mouseX and mouseY values he doesn’t define either.
A little late! Thanks for the video(s). I played around with the code. I added some features: 1. I added the 'grid'/'next' array switching, because voila! 2. I added an age for cells (back and white) with a color table for display. It allows to have nice effects 3. I added mouseClicked event, which allows to set pointed cell to "reactivate" some parts of the grid. Bye!
I just had the idea of Minesweeper but the mines are living cells and are always changing. After all, both algorithms contain a grid of cells which know how many neighbours they have
Challenge: Create a hexagonal (6 sided) version. Hint: the rules need to be simplified to not check 2 living neighbours, only 3. Bonus points: find a glider (I’ve never found one myself)
I have created many, many, initial conditions, aka rules, I can configure them symmetrical, non symmetrical, horizontal, and diagonal. I also have rules that are infinite. They never shrink, and they never die, they only evolve. Conway’s rule is too destructive, on average, it dies off faster than I can toast some bread in a toaster. There’s probably 50 different rules, I have created.
Neat, I've always wanted to try it with different types of cells because the vanilla game of life doesn't have any cell diversity, Imagine a cell that randomly mutates into stronger version of its self, so it can survive overpopulation and underpopulation better. or a cell that has greater influence around it so instead of just influencing its direct neighbours it can influence in lets say a 5x5 grid or destructive cell that just annihilates everything around it and so on, I believe more diversity in cells can create more complex behaviours compared to having multiple rules with basic cell types, the possibilities are endless really.
Idea: Make a 2 game where the map is based on the Game of Life. The player will have to move through the map and manipulate the game to make the map behave as intended. Like, the player can have a weapon that shoot the food blocks to certain parts of the map, to start a new event, freeze some parts of the map, something like that ;)
Would be interesting if you could implement more than one option for each of the cells and form little "tribes" to see which ones take over/fight for survival of the planet. I'm no coder myself so I don't think I could ever accomplish this but it's a nice thought and I think if someone ever did do this it would be pretty fun to watch.
well, you could just make a 1D array instead of a 2d one and use that with x * rows + y making an access function if you get confused. it's as dumb as this: char _string[] = "hello\0world"; //cursed string? printf("%s %s",_string,_string+6); but it works just fine.
Was thinking, if you run through each square and it's association with another, you now have a link with the other active square which means you can store information in an object for the connected square. So each square in the array would have an object of { tl: 0, t: 0, tr: 0, ml: 0, mr: 0, bl: 0, b: 0, br: 0 } if a block finds a square at mr (middle right) it can tell the other square's object (ml) is also 1 which means that following squares can skip anything [tl, t, tr, ml] if you get what I mean :-P
Added if (update == true) {...} at top of rules section of Draw and two functions (below) function keyPressed () { update = true; } function mouseClicked () { update = false; grid[floor (mouseX / resolution)][floor (mouseY / resolution)] = !grid[ floor (mouseX / resolution) ][floor (mouseY / resolution)]; } This let me start and stop cell updates and toggle individual cells between alive and dead.
Im really glad you do all your code from scratch without internal functions or third party libraries. It really helps understand the logic involved.
@Stephen Davies Yeah but that’s not the logic-y bit
@@NStripleseven I think rendering it's the harder part of the project. The code for the cell logic is quite simple.
@@adrian5b that’s true, but it’s not the interesting bit algorithm-wise.
if you already know the rules of Life, skip to 7:09
Thanks man!
What are the 'rules of life'?
@@Pradeep.Poonia Well, just watch the video and don't skip past 7:09, heh.
@@Pradeep.Poonia
Eat sleep code
bro, you've reached enlightenment?
This is the best coding channel ever!
Rest In Peace, John Conway 💜
Wait is he dead...what kind of Dwayne Johnson am I living under...
2020 suck huh?
He was getting pretty reclusive in his old age. Maybe he only had one neighbor.
I m here
@@kavinbharathi xDDD
This is one of if not the best examples of how random and interesting an idea can be with such simple rules
Thanks for this - nice to see it done in a modern language! I wrote this in BASIC on an 8-bit computer many moons ago, but each iteration took more than a minute, so I rewrote it to use a single 2-D grid.
The state was held in the least significant bit, i.e. odd values were alive, evens were dead.
I started with only 0 or 1 values, then scanned the array. If a cell was odd, I added 2 to each of the surrounding 8 cells, otherwise I skipped, saving a lot of processing time. Next I scanned the grid and if a cell contained 5, 6 or 7 the cell was alive so I made it 1, otherwise it was dead so I made it 0.
This change got the processing time for each iteration down to a few seconds.
Nice to see the old tricks to save memory and processing!
Even if i never had to deal with those early computer ;-) i do try those kind of tricks (i've done a bit af asm for game cheat or modding, i think its there i learn to work on bits).
On mine like you i only consider alive cell but instead of adding 2 to there own value i left shift their dedicated neighbour value (firstly set to 1) so i could use 2 mask of rule (each bit corresponding to an amount of neighbours with the least significant meaning 0) so with the same binary AND between those value i can compute next state no matter what the rules are. and since left shifting and binary AND are really easy for computer it's a bit faster than adding and testing (but apparently not in js... still quite the same ^^)
Here is my implementation but don't mind the code it's too messy (implementing stuff over stuff over stuff ... etc ... one day i will refactor it ^^) vassilyd.github.io/GameOfLife/ (And by checking that 4 year old code i realised that what i was saying before was only idea i was about to implement... but never done it... right now it still work by incrementing, but do use a binary AND for test)
I do like the 4,5,6 birth and 2,3,4,5 survive rules, thing turn into linear stable shape (i mean only horizontal, vertical and diagonal line) for the outside with unstable kinda glowing inner + those shape slowly grow and merge until they have only those linear outside line, i call this mode "crystal mode" ^^ (one day i should also implement a selection option of some nice rules like this one)
You’ve got me thinking now, I almost want to go write this in batch.
Which, you know, doesn’t have arrays (and I’m not going to sit there and enter 80x80 variables either 😂 if you wish it has arrays hard enough you can just pretend it does and write the code anyway. I did Minesweeper in batch earlier this year, the underlying concepts are pretty similar (counting neighbours), the trick would be switching between two “boards” but I don’t see why you couldn’t, in Minesweeper I pre-computed the counts because it’s slow doing it while playing.
I wonder what would run faster, your GWBASIC implementation on a couple MHz computer of the day, or the batch version on a modern GHz machine. I don’t really miss basic, but there are times when I’d consider some good ‘ol GOTO for nostalgia.
I bet it would be close, because batch is… Yeah.
@@thedave1771 Oh to have the time to play with coding again!
Batch probably allows a text string of 6400 characters which could be manipulated to contain a two-dimensional array.
I used the method described with a single array as only the eight cells surrounding a living cell need accessing, rather than the eight cells surrounding every cell, making the process several times quicker.
@@clivemitchell3229 there’s actually a way to include a variable inside another variable’s name, so if you wish hard enough can have an “array” accessible as %myarray[%%x,%%y]% and it’s a lot faster than pulling arbitrary characters out of a huge string.
It’s not an array, just loose variables, but if we’re all okay with pretending JavaScript has arrays…
Setting is easy, reading is harder, and of course you’re writing your own functions for every little thing.
I just can’t bring myself to like Powershell. I should, if you asked me to describe what I want in a CLI it would look a lot more like Powershell than anything else out there, but the only thing I find enjoyable about writing Powershell is being finished, so I end up in batch.
I really should stop.
Perfect for training list, of course there´s easier ways to do it, but there are also people who need these kind of videos, this guy is th Bob Ross of coding
I really love the “game of life” , it on my Mac screen saver too, really enjoy the way you explain how the code works, checking the rules and then wrap around logic. Pls keep up the great work!!!
16:35
you could use different numbers for modes, 0 - old=dead, new=dead
1 - old=dead, new=alive
2 - old=alive, new=dead
3 - old=alive, new=alive
Thank you, Daniel,
another instructive and fun video. You‘re such an inspiration to me. Please keep on. I „co-programmed“ Asteroids following your suggestions, now I‘m working on Solitaire, learning the hard way how the loop() function is actually an interrupt, thus it is difficult to expect some variables to be set by functions called AFTER the loop() call😂
Took me a few months of very interrupted work, but i got it working just with the processing reference and my knowledge of classes. It's super inefficient, but it works beautifully.
Dan, maybe someone already told you this, but I couldn't help noticing...
In the live video last Friday you laughed at the suggestion of the Game of Life on a torus. But, ironically, this is exactly what you've done. Think about it... Wrapping left to right is equivalent to making the flat map into a cylinder. And then wrapping top to bottom takes that cylinder and bends it around so it forms a torus! The only thing you didn't do is render it in 3D. Now, that would be a coding challenge. :)
Yes, yes, yes, this is true! Thanks for the reminder, I love the idea of actually trying to render it on a torus in 3D!
That makes sense since you can think about a long rectangle being curled into a hollow cylinder, and then the circles on the end curled around to touch each other - and since opposing edges on a rectangle are the same length by definition, this will all match up exactly. The only problem is when it's too square, it'll have to be stretched a lot...
You know what would be even nicer? By changing the direction in which you wrap you could simulate the Game of Life on a Mobius strip, or even on a Klein bottle! *Laughs Mathematically*
simple.wikipedia.org/wiki/Klein_bottle
simple.wikipedia.org/wiki/M%C3%B6bius_strip
Rory Slegtenhorst So laggy... lol
If anyone is interested, i made exactly this! I put it up on this website: eirik.tech/Game-of-life/index.html
Feel free to check out the source code too:
github.com/eirikhalvard/game-of-life
Wonderfull 35:46, the final music note just when the game fall into a stable state !!!! That was written ;)
Nice job, Dan !!
Imagine if our universe was just some alien making a tutorial.
When the cells just stay in one spot,
We know they have gotten too smart,
We know that they are building civilization,
And we know they are going to war.
haha. Then I guess the most intelligent cells are those that join together to form a square? That seemed to be the most common "stable" shape. (That is if I did it right : (
Funky B they have built walls of fortification. We must bow down to our new leaders.
Holy mother of god...
I have a small coding challenge idea. Imagine a grid of dots, like a really big grid. And when you click on any part of the grid, it creates an illusion of a ripple effect, like you're looking at water from a top-down view. And the illusion will be created by manipulating the size of dots (or circles if you will, since they will get bigger and smaller)
Post it in his Git Repo for Challenge Ideas
I know this is old but that would be cool
there's a lreally cool ibrary for that actually!! RippleJS
wouldnt this work by just making every cell next to a live cell switch states? It wouldn't be a circular, it would be more like a roughly rotated square increasing in size but it would be a "ripple" effect
Sooo weird - I just discovered this channel with your old CA videos a few days ago and then here's this new video. My current Introduction to Programming/Java project is to make a tic tac toe game, and that seems so much less daunting after soaking in all of this witchery. lol I'm quite keen on trying to tackle The Game of Life. It's so helpful seeing a professional programmer's process step-by-step like this. Thanks!
I had a whiteboard interview today with this challenge, so coincidental!
this was asked in interview? for what role?
bruh what?
Why did they ask this??
Did they ask to code the above thing??
@@nanda_8 I'm a software developer and I was asked to do this as a coding challenge in one of the stages of applying for the position.
I am working on mine.And I was Looking for some resource and then your video poped up in the notification.You always Help.Thanks
I was watching some interviews with John Conway recently and it occurred to me that since he grew to hate the Game of Life, it would be an appropriate way to celebrate his life and legacy. And also it’s just about the only thing he did that I can genuinely understand well enough to explain it, his contributions to higher math are… Impressive.
I wanted to do it a bit differently though, in that I wanted to support no fixed board size. In particular if you start four gliders going up, down, left and right, it should run until they exceed the 2^32 board. This means they can take 2^31 steps in any direction, although since a step takes at least two generations we’re helpfully back to at least 2^32 generations before encountering the border. I ended up using sparse storage for the cells, so the 4 gliders will take the same RAM (and CPU) whether they’re a few squares apart or are 2^30 away in each direction. and I don’t need to purchase the 2exabytes of storage to maintain the board. The calculate function can impose borders, which turned out to be trivially simple (no need to do bounds-checks while computing, for example), I just don’t calculate neighbours beyond the range and therefore they’re automatically dead. Since you can query and cell, the neighbours function doesn’t need to “not” check beyond borders, it just sees dead cells. Technically this reduces the theoretical board by 1 in every direction but the implementation is so trivially simple.
Next up, I want to multithread the generations so I can throw all 20 of my CPU cores at it, and down the road it might be interesting to use a GPU for calculations too, but that’s well beyond my abilities right now.
How to visualize it? That’s easy, you can’t. The viewport can be moved anywhere, and can return whatever size you want, but I am not attempting to render beyond 1 pixel per cell and I’m not aware of any patterns that are designed to work with 4x or more cells comprising of a single pixel, so a true zoom wouldn’t be that useful. Or would it?
It took about 45 minutes to write the backend, but I’ve spent a bunch of hours here and there playing with the UI as I decided I wanted no flickering, and to use colour to represent the distance from the centre point, and since I’m a console monkey, the interface has been the learning curve. I did write an interactive console version first, then a UI using the same backend. I want to eventually do a iOS and Android version as well, just to toss it in the portfolio.
The colour effect turned out so nice that I decided to give the option to render the colour gradient over ~1000 steps, so a reasonably large monitor can visualize the effect. I’ve never before made anything I found visually appealing, nor do I usually care about such things, so it’s been an interesting challenge.
Watching it in JS is amusing and fun, especially since I don’t know any JS at all.
Great! I really hope I will remember the modulus 'trick' if I ever need it. Awesome.
Thanks for watching!
@The Coding Train, this video helped me get my current job and I'm extremely grateful!
Hi Nathen, I have the same challenge, did you implement it in python??
Outstanding! I have been fascinated by the Game Of Life for decades. I've wanted to try my hand at coding it, but always wondered how to get it from one generation to the next. I'll try making each cell an object and see what happens!!!
You are one of the best teachers of my life. Thanks for all the videos and all the inspiration.
Every now and again Dan will check his super special ceiling notes.
I enjoyed watching; thanks
Thank you so much for this! I was able to take your video tutorial and transfer the knowledge from it into Processing’s python library. I successfully coded the GameOfLife on my own! :)
I remember being assigned this as a project freshman year in my computer science program. I was able to get it working correctly but others did not. The trick was to start with an empty array as your next generation and calculate from the current generartion. We did no animate it, we just displayed 0s for empty cells and 1 for non empty cells.
Rather than having two 2d arrays, I gave each Cell (I made them objects) an "active" and "expected" boolean. The Active boolean was the "current" 2d array, and the expected boolean was for the next grid. I would loop through every cell, calculating the next state, and set the Expected boolean to match the desired state. The active state didn't change.
Once I finished this iteration with every cell, I looped through the grid once more to set active to equal expected.
back when the IBM PC was a new computer, I wrote a game of Life for it. I think it was about 50 lines of TurboBASIC code. 2D arrays are easy-peezy in BASIC. You DIM and that's it. I used one array for the current state, and a second array I called WORK, which is where we built the new generation. Then I simply copied the Work array to the current array and displayed. My version was the only one I knew of that could save and load shapes. I made mine wrap also, and I allowed you to chose the size of your playing field as well as delay interval to control the speed. Yours looks good. You're a better man than I. I wouldn't even try that in Javascript.
23:54 I love how when he's thinking it's like he's being touched by demons 😂😂
I really love the way you work, the charisma, the good vibes all you make it's so good enough to make it interesting and incredible... I really enjoy your videos :-)
I only know python but goddamn this guy can teach javascript
I only know javascript but goddamn this guy can teach me more
Thanks for uploading, and showing. This is helping me understand the fun aspects of coding. Trying to land a job, no luck yet.
I'm a fairly new CS student in college and this guy is crazy good at this stuff I hope to be as good as you one day great video.
I know this video is really old at this point, but you could very easily just start a new array filled with zeroes, loop through the 'old' grid once, then for each 1 you encounter add one to the 'new' array, if a value reaches above 0 you add it to a separate 'alive' array, if a value reaches above 3 you remove it from the 'alive' array if it exists. Then, once you're done, simply redraw the original array, checking for each cell if it exists in the 'alive' array, and if so setting it to 1, if not setting it to 0.
This way you only go through the original array once instead of counting neighbours for each cell, then in the drawing step you only check for values in an indexed array (that could be string keys (`x+'-'+y`)) and you basically end up with something that's 4x as fast as counting each neighbour.
I have no intention of coding in java but i'm watching pretty much all your coding challenges for some insight like that % solution. Classy!
Glad to hear!
it's javascript, not java :P
He's not coding in Java here, it's JavaScript. Java and JavaScript are like day and night.
Edge cases, simplified:
if ( x > (cols-1)) x -= cols; // 10 becomes 0
if ( x < 0) x += cols; // -1 becomes 9
if (y > (rows-1)) y -= rows; // 10 becomes 0
if (y < 0) y += cols; // -1 becomes 9
thank you!
Just do (x+10)%10 and (y+10)%10, no ifs
I admire your teaching. Thanks for all the videos you make
The video is really helpful for me because this game was a few years ago on the matura exam in Poland so I enjoy watching you code the game. Greetings from Poland, dude :D
This is the best solution for leetcode 289 I have seen,thank you !
This is very helpful because i personally use p5js for JavaScript stuff, that's awesome
Dude you're awesome... I'll try to replicate this in python just to learn and for fun :-)
as I promise: github.com/dhvalden/learning_python/blob/master/my_game_of_life.py
However, I just translated it to Python, but I haven't been successful in adding another features :( part of the learning process I guess
@@dhvalden page not found :(
@@dhvalden still you have the python implementation please??
I finally made my own on C#!
Thank you so much! You're the best!
Thank you for this! I was confused with the edges and modulo, your explanation cleared it up! Around the 29:47 time mark
Hii, I didn't get it for edge ... and it doesn't work for me in python !! any help please??
dude you're so awsome, thx a lot for this
Got a real mad scientist vibe goin on
The Game of Life has been my primary interview question (though I also have a few graph/algorithm questions for variety.) It's great because it leads to obvious extensions, such as borderless with wrapping, and opens the discussion of how to make an infinite game of life, which many have difficulty answering. Finally, it's fun to introduce n-dimensional extension, and how to change existing loops to deal with multiple dimensions, and finally, how to make the system parallelizable for truly massive user experience. If they get through all that, they almost always get hired, and do great later.
That's really interesting. Do you mean infinite over time or over an infinite grid? In Python, I would start with a list of lists, and have add rows/columns whenever a live cell needs to be created outside the original lists, although the size of the list will grow exponentially. Parallelization is also very interesting, maybe dividing the board into slightly overlapping zones, each of which is processed by a separate thread, then stitching the zones together? I'm naively guessing, but the minimum overlap should be around 3 tiles, to make sure no cell at the border is confused.
YES! I've been wanting this, thank you Dan!
Whenever I work with grids, I usually end up using a single array from top left to bottom right, and to check relationships, I use (i - gridsize) for up, where i is the number of the gridspace itself in the array, (i + gridsize) for down, (i + 1) for right and (i - 1) for left. Getting edges is a little harder, where if i % gridsize is 0 then you're on the left edge and if if i % size is equal to size - 1 then you're on the right edge, but that doesn't handle having different x and y sized very well. In that case, I guess having two variables, rowSize and columnSize could suffice, though.
rather than fixed arrays, use twin dual circular linked lists of "active" cells; then you have an undefined infinite grid. The "Life" can grow ad hoc forever, and you never have to consider the entire grid... only the cells that are active.
marcus
I'm not sure what you mean but have you implemented that? It sounds like it doesn't take into consideration the fact that during each cycle of the simulation the generation of the next cycle has to take into consideration that all the cells have to be processed before making changes to any cell.
@@dannygjk Not necessarily, for example i've done it by only processing the alive cell, incrementing each neighbour's neightbourAmount value first then indeed i still process it for all cell, i guess i could also ignore cell with no alive neightbour here, but only in base rules, if you use another rule that specify birth with 0 neighbours then you have to process all cell... It all depend on how far you wanna extend the possibility ;-)
Anyway indeed a linked list type (with also a link to each neighbour in cell object) could allow an infinite grid, as long as your computer handle it ^^ (but not sure how to handle interactivity, without getting too laggy, since to get a particular position you need to go through the whole list, don't you?)
@@SylouCool So you are processing all cells before you modify?
@@dannygjk Yes cause i wanted a GOL that can work with any rules (including a 0 neighbours rule for birth...). but like i said if you stick to the base one there is no reason to process dead cell not surrounded by at least one alive cell. So you could only process alive cell and their neightbours in the second loop too.
For Mark idea to work i guess he would need at least an x and y property in his cell object and a pointer to each neightbours + a previous and next pointer. In that list you will only have alive cell and their neighbour, creating new one when needed and eventually destroying those that become isolated (or use a secondary list where all isolated cell goes and not get processed but can be switch back to the active one at any time). And for the rendering, during the process you save minimum and maximum of x and y of cells and there you know the needed size of the grid.
I'm not saying this is what Mark was talking about but might be close enough ^^
Anyway i do prefer using 2D array for that (also array can be extended even if it could get messy ^^)
@@SylouCool I found that keeping it simple seemed to work fastest for the 'normal' living/dying rules tho I was working with only cells that fit in the display. I would scan for live cells then increment the neighbor count for the surrounding cells in a neighbor count 2D array.
The starting point for The Game Of Life is always two, two-dimensional arrays. If you make each array two indexes "wider" and "taller" than your display, this simplifies the coding since positions -1 and +1 to the pixel which you are calculating will always exist and so you won't need any "exception processing" to handle the edges of the map.
You flip the "working" array (which is the one to be displayed) between the two arrays, with the other array being the "target" array. The calculations are done on the "working" array and the results are placed in the "target" array. Once all pixels have been calculated, the arrays are switched and the new "working" array is displayed.
If done correctly, the array elements along each edge (beyond the displayed range) are never calculated and so always stay "dead."
Of course, you can always decide to challenge yourself and make the field "wrap around" so that the pixel on the furthest-right of the screen in a particular row is considered to be a neighbour to the furthest-left pixel in the same row, but this requires slightly more complicated logic. Which I now see was actually done in this video, in spite of the fact that by default the game's rules assume that the field does not wrap around.
"Of course you guys are watching this on a television" famous last words
love your energy man ^^
Daniel! Thanks for teaching me the moulus trick :) Glad you're well and of course... Welcome back ;)
A lot of this code is really similar to the framework i used to build my minesweeper clone in python.
An idea i had about updating the grid would be to make a 3D array with the extra nested array being there to hold a value which basically makes sure each cell “remembers” whether it must change or not. After setting that value for each cell, you would then check it for each cell, if it’s a 1, change it, if it’s a 0, leave it alone, set it to 0, and then you have your next grid. I have no idea whether this solution is efficient or not but i personally like it
Or instead of a 1 or 0 you could make it a boolean of course
5:10
no number is less than 2 and greater than 3 at the same time
maybe you can use 'or' instead of 'and'
thank u for this amazing video
These coding challenges are awesome.
Your awesome dude
When you're doing 2D arrays it's WAY better that your "Initial array" is of the rows and inside each row there's the column. Not only is that how it's normally done when doing stuff with Matrices, but also, it's far better to have your outer loop be the Rows (which tends to be less than the columns), and then iterate through each cell in that row.
You actually don't need two grids, since each cell is either on or off, you can use the first bit to represent the current state and the the second bit to represent the previous (or next state) so basically you fill the grids with 0,1,2 and 3
I recently made the game of life in minecraft as a datapack, and I get recommended this.
*_RUclips knows everything. RUclips sees everything. RUclips is everything._*
Nice to see you again
Thanks!
perfect! next video, how to build skynet 🤷♂️👍
Hi Dan, I'd be keen to see how you would tackle this in 3D, and what rules you would pick for the cells, that's version 2 of this coding challenge....
It’s a different game if you play it on a torus. Better to implement it as a list of live cells. Each generation then consists of first generating a list of neighbors by incrementing a counter for each of the eight cells around each live cell. Then generating the next list of live cells by examining the state and count of each entry in that list.
This allows for an arbitrarily large grid, implements the game correctly, and makes it much easier to detect and deal with repeating and traveling patterns.
for anyone that needs the branchless version for calculating next state:
(assuming you are using an array of booleans for handling state)
int counter = sum of all 8 booleans around current[xy];
current[xy] = previous[xy];
current[xy] = current[xy] and (counter == 2);
current[xy] = current[xy] or (counter == 3);
same behaviour as:
if(counter == 3)
{
current[xy] = true;
}
else if(counter != 2)
{
current[xy] = false;
}
else
{
current[xy] = previous[xy];
}
Arrays are mathematical constructs, and there most certainly are two dimensional arrays, regardless of their CS implementation.
This video is amazing. Thanks you, I learned a lot
Love your vids, thank you so much for your service here. Once I heard you started with lingo like myself it all made sense why your methods clicked so well. cheers
I love you videos. It inspired me to code in JavaScript. Keep it up
Another great video 😊
This is awesome! I have a couple of pretty rudimentary ideas that I want to do. I love the idea of being able to "draw" on it, so I'm going to implement that. I also want to make it pretty! So I'm going to cycle through a rainbow of color values and, for every generation, I'm going to change the fill color for live cells. It'll be a rainbow explosion!
I just wrote this in C#, so it's kind of interesting watching someone else tackle it quickly in a different language.
I'm racking my brain trying to figure out where "width" and "height" were defined at 13:49
at line 16 you have: 'cols = width / resolution'
But I don't see width defined anywhere else in the code, what am I missing?
I think it’s the language or environment he’s using, some default variables we don’t see. When he checks for mousePressed(), for instance, he uses mouseX and mouseY values he doesn’t define either.
you're a great teacher
Please do a video on Lenia. Bert Chan’s work on continuous cellular automata is fascinating.
Love your videos man! Very informative and helpful👍
Rest in Peace, John Conway. :'-(
hello i love your videos i watch for 3 years
Thanks for tuning in!
A little late! Thanks for the video(s). I played around with the code. I added some features: 1. I added the 'grid'/'next' array switching, because voila! 2. I added an age for cells (back and white) with a color table for display. It allows to have nice effects 3. I added mouseClicked event, which allows to set pointed cell to "reactivate" some parts of the grid. Bye!
35:29 "Modulus Joe" 😂
your explanation is awesome
I just had the idea of Minesweeper but the mines are living cells and are always changing. After all, both algorithms contain a grid of cells which know how many neighbours they have
I would love to see this!
Challenge: Create a hexagonal (6 sided) version. Hint: the rules need to be simplified to not check 2 living neighbours, only 3. Bonus points: find a glider (I’ve never found one myself)
I have created many, many, initial conditions, aka rules, I can configure them symmetrical, non symmetrical, horizontal, and diagonal. I also have rules that are infinite. They never shrink, and they never die, they only evolve. Conway’s rule is too destructive, on average, it dies off faster than I can toast some bread in a toaster. There’s probably 50 different rules, I have created.
Neat, I've always wanted to try it with different types of cells because the vanilla game of life doesn't have any cell diversity,
Imagine a cell that randomly mutates into stronger version of its self, so it can survive overpopulation and underpopulation better.
or a cell that has greater influence around it so instead of just influencing its direct neighbours it can influence in lets say a 5x5 grid
or destructive cell that just annihilates everything around it
and so on, I believe more diversity in cells can create more complex behaviours compared to having multiple rules with basic cell types, the possibilities are endless really.
@@wlockuz4467 that would be crazy man! And it’s true it would diversify it.
Many thanks Dan and happy new year to you. Really looking forward to your continuation of machine learning.
Great Video Man!
Idea: Make a 2 game where the map is based on the Game of Life. The player will have to move through the map and manipulate the game to make the map behave as intended. Like, the player can have a weapon that shoot the food blocks to certain parts of the map, to start a new event, freeze some parts of the map, something like that ;)
Love your videos!!
I did this cellular automata a while ago! www.openprocessing.org/sketch/437331
Really pleasing to play with :D
Thx ;)
Nice thing, really. But seems like you missed to process left and bottom edges. Anyway, great work
You are awesome man
Would be interesting if you could implement more than one option for each of the cells and form little "tribes" to see which ones take over/fight for survival of the planet. I'm no coder myself so I don't think I could ever accomplish this but it's a nice thought and I think if someone ever did do this it would be pretty fun to watch.
20:57 me who is watching this on a smartphone:😐
Better to make an array with string indexes like x+" "+y ,but it's only a proposition.
well, you could just make a 1D array instead of a 2d one and use that with x * rows + y making an access function if you get confused.
it's as dumb as this:
char _string[] = "hello\0world"; //cursed string?
printf("%s %s",_string,_string+6);
but it works just fine.
Was thinking, if you run through each square and it's association with another, you now have a link with the other active square which means you can store information in an object for the connected square. So each square in the array would have an object of { tl: 0, t: 0, tr: 0, ml: 0, mr: 0, bl: 0, b: 0, br: 0 } if a block finds a square at mr (middle right) it can tell the other square's object (ml) is also 1 which means that following squares can skip anything [tl, t, tr, ml] if you get what I mean :-P
Added if (update == true) {...} at top of rules section of Draw and two functions (below)
function keyPressed () {
update = true;
}
function mouseClicked () {
update = false;
grid[floor (mouseX / resolution)][floor (mouseY / resolution)] = !grid[
floor (mouseX / resolution)
][floor (mouseY / resolution)];
}
This let me start and stop cell updates and toggle individual cells between alive and dead.
2:22 so is advancing a generation a rotation or mirroring? (4x5 -> 5x4)