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
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.
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.
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!!!
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
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
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😂
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 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.
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!
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!!!
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.
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.
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.
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 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 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 :-)
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
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.
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.
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
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.
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.
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
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
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.
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.
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
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]; }
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!
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!
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
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.
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.
I recently made the game of life in minecraft as a datapack, and I get recommended this. *_UA-cam knows everything. UA-cam sees everything. UA-cam is everything._*
Did it in Python using Pygame and numpy and it was a bit faster because while I create the new grid, I also add to a list the cells that changed value, and the value... then I just need to redraw that small list and not all the cells. Then I used Raylib instead of Pygame (wanted to compare speed) and Pygame (2.0) i s a bit faster. With a cell size of 20x20 (3200 cells) I get 50fps with python. 10x10 cells (12800 cells) is still fast watching: 15 fps, seems faster than the posted video, which has 600 cells only. Python can take care of it up to a certain number of cells... but when it's a ton (used 1600x800 canvas with 4x4 cell, so 80k cells) it suffers 2 FPS lol SO I decided to port the exact same code to C (using Raylib as well) and my face melted for 80k cells (1600x800 and 4x4 cell) the fps count is around 70 fps in the same 6gen i7 laptop. 30 faster, incredible! SO I decided to use Nuitka to compile the Python code (not jit, but compile to exe, first it converts to a mess C code) and see how it compares, if it would gain any speed: Well, exe size went from 1MB compiling the C code, to 127MB using Nuitka.... and performance compared to Python code is not seen... still around 2fps... so no, Nuika was useless to improve speed. So, if you need lot's of cells and speed, use C, C++, Rust, whatever. But Python and JS seem very capable medium sized grids. Also numba and jit would make it faster... tried once, falled back to regular to types issues, but I had no time to dig it. Could not make pypy work with pygame or raylibe as well...
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
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.
This is one of if not the best examples of how random and interesting an idea can be with such simple rules
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
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?
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
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.
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.
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
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
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.
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
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😂
You are one of the best teachers of my life. Thanks for all the videos and all the inspiration.
Great! I really hope I will remember the modulus 'trick' if I ever need it. Awesome.
Thanks for watching!
Every now and again Dan will check his super special ceiling notes.
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 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.
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 only know python but goddamn this guy can teach javascript
I only know javascript but goddamn this guy can teach me more
@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!!!
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 admire your teaching. Thanks for all the videos you make
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.
Thanks for uploading, and showing. This is helping me understand the fun aspects of coding. Trying to land a job, no luck yet.
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.
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.
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! :)
Wonderfull 35:46, the final music note just when the game fall into a stable state !!!! That was written ;)
Nice job, Dan !!
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.
perfect! next video, how to build skynet 🤷♂️👍
I finally made my own on C#!
Thank you so much! You're the best!
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 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.
This is very helpful because i personally use p5js for JavaScript stuff, that's awesome
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
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.
These coding challenges are awesome.
I just wrote this in C#, so it's kind of interesting watching someone else tackle it quickly in a different language.
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.
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
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.
Got a real mad scientist vibe goin on
I enjoyed watching; thanks
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
Arrays are mathematical constructs, and there most certainly are two dimensional arrays, regardless of their CS implementation.
dude you're so awsome, thx a lot for this
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.
This is the best solution for leetcode 289 I have seen,thank you !
The wrap around is a torus.
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??
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!
love your energy man ^^
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
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.
your explanation is awesome
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.
Python wrap around is easy cos
Grid[-1] is last element.
Rest in Peace, John Conway. :'-(
Please do a video on Lenia. Bert Chan’s work on continuous cellular automata is fascinating.
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??
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];
}
Your awesome dude
thank u for this amazing video
Better to make an array with string indexes like x+" "+y ,but it's only a proposition.
YES! I've been wanting this, thank you Dan!
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!
23:54 I love how when he's thinking it's like he's being touched by demons 😂😂
I actually made this in Java myself, but in a console command window, it was one of my first projects I was really proud of haha.
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....
This video is amazing. Thanks you, I learned a lot
you're a great teacher
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!
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
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
5:10
no number is less than 2 and greater than 3 at the same time
maybe you can use 'or' instead of 'and'
To compute or not compute that is the question
Daniel! Thanks for teaching me the moulus trick :) Glad you're well and of course... Welcome back ;)
Ha. Made this last week. Game of life is so fun to look at it's better than watching a movie or something.
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.
Another great video 😊
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.
Nice to see you again
Thanks!
Checkout the typeof function and the indexof would make this coding so much easier
I recently made the game of life in minecraft as a datapack, and I get recommended this.
*_UA-cam knows everything. UA-cam sees everything. UA-cam is everything._*
Nice one, Subscribed. Please keep'em comin....
I made a map generator with Conway's Game of Life. I actually plan to do some more with too. The maps are so satisfying most the time too xD
hello i love your videos i watch for 3 years
Thanks for tuning in!
Did it in Python using Pygame and numpy and it was a bit faster because while I create the new grid, I also add to a list the cells that changed value, and the value... then I just need to redraw that small list and not all the cells.
Then I used Raylib instead of Pygame (wanted to compare speed) and Pygame (2.0) i s a bit faster.
With a cell size of 20x20 (3200 cells) I get 50fps with python.
10x10 cells (12800 cells) is still fast watching: 15 fps, seems faster than the posted video, which has 600 cells only.
Python can take care of it up to a certain number of cells... but when it's a ton (used 1600x800 canvas with 4x4 cell, so 80k cells) it suffers 2 FPS lol
SO I decided to port the exact same code to C (using Raylib as well) and my face melted for 80k cells (1600x800 and 4x4 cell) the fps count is around 70 fps in the same 6gen i7 laptop. 30 faster, incredible!
SO I decided to use Nuitka to compile the Python code (not jit, but compile to exe, first it converts to a mess C code) and see how it compares, if it would gain any speed:
Well, exe size went from 1MB compiling the C code, to 127MB using Nuitka.... and performance compared to Python code is not seen... still around 2fps... so no, Nuika was useless to improve speed.
So, if you need lot's of cells and speed, use C, C++, Rust, whatever. But Python and JS seem very capable medium sized grids.
Also numba and jit would make it faster... tried once, falled back to regular to types issues, but I had no time to dig it.
Could not make pypy work with pygame or raylibe as well...
@ the coding train - would love to see a game of life based on a particle system!
Here you are: ua-cam.com/video/-c5XaC5-DXg/v-deo.html
Love your videos man! Very informative and helpful👍
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
"Of course you guys are watching this on a television" famous last words
Many thanks Dan and happy new year to you. Really looking forward to your continuation of machine learning.