YTread Logo
YTread Logo

Coding Challenge 180: Falling Sand

Mar 18, 2024
Sorry, I'm still recording a video here. A

coding

challenge

idea that's been suggested to me many times is a Falling Sand simulation and today is the day I'm going to tackle it. I have to confess that this is not the It's the first time I've tried to make a Falling Sand simulation. If you're familiar with the initiative called January, which is a generative art month in January, it's probably happening right now because I think it's January 2024. In 2022 I did a drop. Stand uh simulation for uh for January. I don't remember how I did it, but I hope there's some muscle memory or memory deep in my brain to get me through today.
coding challenge 180 falling sand
A really great and wonderful reference if you're like, what are you? I'm even talking about the NOA game, which is built on the engine that drops everything, which is this amazing game engine where every pixel is simulated. I would also love to highlight Max Bit's

sand

speech, it may not be how it is pronounced, but I choose to do so. pronounce it

sand

Spiel um, where you could create this world of sand, water, fire, smoke and mushrooms, all from pixels. My previous

coding

challenge

, if you look at it, was about cellular automata and actually this Falling Sand simulation, this idea of ​​any pixel that has a state is sand, is water, is fire and changes its state based on what what their neighbors do.
coding challenge 180 falling sand

More Interesting Facts About,

coding challenge 180 falling sand...

I think this can be done with CA. I like the rules now, you might want to continue watching this video, but I just want to mention that there is this wonderful online tutorial from Jason at Jason. It talks about how to make a crash simulator with p5js, so we'll see, compare and contrast maybe in the end we'll see how my version works, how Jason's version works, but you can also check it out and make your own. Send it to the passenger exhibit and we'll see what kind of awesome projects this community can make out of the Falling Sand simulation.
coding challenge 180 falling sand
Let's first establish the world I intend to create, so that the elemental AC wolf was a one-dimensional AC where each cell had a state coding challenge of zero or one 105 I think it was the game of life, which is a two-dimensional AC, meaning that the grid lives in two dimensions and each cell has a state of zero or one for the Falling Sand simulation, a state of zero or one. dimensional grid makes more sense, let's say this is my p5js canvas and I decide that I'm going to place a grain of sand on the canvas, which means that maybe the state of this particular cell is one and all other states are zero .
coding challenge 180 falling sand
I want the sand to fall, which means the rule will be that if there is a cell with a state of one that has a cell with a state of zero below it, then that piece of sand will move from its current location to the location below if it happens that there is already a cell with a state of one below it, then it can't move, it stops that way, the sand will accumulate. Let's start by implementing just that to make my life a little easier. I'm going to take this 2D array creation function from The Game of Life Coding Challenge, so let's call the space I'm going to create a grid and set the resolution of each grain of sand.
Now, at some point, it might be fun to try to make a grain of sand a single pixel. for now we have a 10x10 rectangle so I need to set the number of columns and rows the number of columns is the width of the canvas divided by the width of one of those little squares so in this case 40 divided by 10 400/10 would be 40, like this I'm going to have a 40x40 grid, so that's what I need to size my two dimensional array, so I'm using a nested loop to set each position, each column, and each row J to zero.
Then I can use that same thing. Nested loop to draw each square maybe if it's zero it's black if it's one it's white and so we can see it let me give it a stroke of 255 oh and the X position would be the column multiplied by the width of that square there we go a grid of squares blacks that's exactly what I was hoping to see what happens now if I set a particular cell in this grid to have a state at a glance that column 20 row 10 is now white. I'm ready to implement this logic. I need to run a loop over each of these cells and look for any one and then check what the environment is for that particular one.
While doing this analysis, I can't change the values ​​in the original grid, so I need another two-dimensional grid. which can act as the next grid, the Next Generation, the next animation frame of this Falling Sand simulation, let's get the state of the current cell that we're looking at, if the state is one, I need to look down and see what's there. not the row of K, this is i j the state of the current cell i am in and the cell below is J + one if the state below has a value of zero then the cell i j should now have a state of zero in Next Generation and Next should have a state of one and now the current grid is as follows.
I've missed a few steps here, but let's see how far we got, so everything turned white, so why is it a problem when I make this new 2D array? it doesn't have any value and I'm just assigning the value zero or one if I find one in the previous grid I need to set all the values ​​of the next grid however if I'm checking all the cells and I get here and say oh in the next generation, this should be a zero and this should be a one. I'm going to keep checking and eventually I'll get here and find out that it was a zero and it probably says it should stay at zero, so what I think would work.
I'm not 100% sure about this is that if I start with the new grid the Next Generation will have all zeros and I'm just setting the one values ​​based on where the ones are in the previous generation, one way to address this is by making the 2D array creation function just fill everything with zeros, that way I'm just moving the ones and the zeros will be there by default, I should mention that the way I'm doing this, where the first index grid I is the column and the second index J is the row, maybe it's a little bit backwards depending on your point of view and your experience if you are used to Matrix Math, a 2D matrix, you would often say row column instead of row column, but that's how I did it in the Game of Life, as long as it's consistent it will work and that's fine, that's fine.
Okay, now what I'm going to do is add another little J here, oh look, now it works. Amazing, it disappeared when it hit the bottom so I need to take into account the edge if down equals zero or if J+1 is greater than the number of rows if J+1 is greater than the number of rows minus one oh l or no less than if down is zero and J is not the bottom row I have an o there and I said and if down is why I'm I'm wrong so many times, oh oh, otherwise it should stay as one.
I could have gotten it right all those times otherwise the next grid should remain as one and in fact if everything is going to be initially set to zero I don't do it. I don't have to explicitly set it to zero, so I'm basically deciding if I should move it down or leave it where it is. Let's add some mouse interaction. When I click the mouse, I will add a grain of sand, so if I take the mouse. position divided by the size of each cell the width of each cell each cell is a square that should give me the column and row index in my grid look, I'm stacking sand, let's change this to Mouse Drag, that's fine though, we're cooking I want to add a little more sophistication here.
What if I have a grain of sand and there is one underneath so it can't move down? However, there is an open space to the left or right, you could move to one of those empty spots. the sand would fall to the right and to the left forming a small hill so let's look at bottom right and bottom left now I should say do I need this because it wouldn't be undefined otherwise yeah it works I don't even need it . I need better error checking, yes, well, but H, why not? Otherwise you could check if bottom right is zero and then if that's the case next grid I + 1 J = 1, otherwise if bottom left is equal to z i minus a child that's fine , I did it.
It's kind of sliding around there. I need to ignore the bottom row so I just want to check if J is equal to the row minus one, keep it the same, if the statement has really gotten out of hand I will refactor this later so if it gets to the bottom don't do anything oh wow let's continue go wait oh I have to go down one oh I'm just going to the right I also have to go down a well of course so I don't really have this problem, welcome to a coding challenge where I didn't plan this in advance, okay, let's get back to this, it's better, okay, let's see my Falling Sand simulation, now we have a little problem, watch how it always goes.
To go right first, what would be a good way to make it random. I'll call it under a and under B plus diir minus di dir is negative 1 or positive, how do I know what di is? one and if the chance of one is less than 0.5 then multiply di*negative 1 oh I can't wait to hear your best way to do it in the comments so a will be roughly B will be the opposite of that and then if below a is zero we say plusd and if below B is zero we say minus di, then now it should randomly go left or right, oh oh no, I need to handle the left and right edges, as?
I do that? Oh wow, I forgot the plus one here. I need the plus one here. Also okay, this is more like Falling Sand, now it doesn't bounce like before, but why am I getting an error here? I'm accessing a nested array so it's ok if this is undefined if the first part is undefined I can't get the second part it will throw an error well I guess I could check if I'm in a lead let's do that alright I'll to say let under a and under B, let them be undefined. I just need to check the left and the right and I just need to check.
I'm fine only if I'm greater than zero and I'm less than the columns. minus one, then try to get a real value. I still get an error whenever plus diir is greater than or equal to zero and plus Dr is less than or equal to the number of columns minus one, so I can do it below a this is me double checking that that's a valid place oh, it's oh just because my mouse went off the screen this is correct now, as clumsy and terrible as it is, but my mouse is going off the screen, okay, let's get this initial molehill out of the way. fix I want to add sand grains but only if my mouse is inside the canvas then I want the sand grains to move down or left or right if down is full but not if it is at the bottom edge or to the left or to the right.
Edge, cannot leave the canvas. Let's improve some things about this one. We can make it more efficient because I don't need to draw all the black squares. Now this is much faster because I'm just drawing the white squares. I'm skipping the drawing and just filling the background with black, let's give ourselves a little more space and instead of just dropping a grain of sand, what if I dropped a small collection of sand particles around the area where the mouse to have the column in a row and we could make a little Matrix, how about 5x five so I can write another little loop where I want to go from -2 to two, which would be 5 times five, so I have to say to what extent I know that is it a good word? to use would be to divide the Matrix by two, so I'm going to pass I to a negative degree I is less than or equal to a positive degree i++ j j j and I'm going to call this the mouse column and the mouse row because the column is now the mouse column plus I and the actual row is the mouse row plus J and then here I can take this and put it here, so as long as this 5x5 area any of those cells are inside the canvas, I should drop it. sand and you could see that I'm dropping a much larger amount of sand now, a nice little stripe effect, now this is what I actually don't want to do 5x five, firstly it was a lot bigger than I thought, so let's make this like three for example, but also maybe they shouldn't always all drop, so what if I actually introduced some randomness here only if a random one like maybe there's a 75% chance I'll drop that one. small grain of sand there?
It goes back to five, so it's a little more amorphous. Okay, now let's drop some sand. This is lovely. How about you add a little color? One thing I've done here is that everything is based on whether the state is zero or a. one, but what if I think the state is zero or anything that is not zero as long as it is greater than zero? Draw, what happens if I use its color? Oh, I have an idea, what if I have a tone value equal to zero and let's go? Let's say this is a bit of a crazy color mode because I have to make everything clear as a rainbow.
HSB 360 is the default 255 255, so this is a huge saturation brightness, so what I'm going to do is set the grid to a hue value, then I'm going to fill it with that hue value and a brightness and full saturation, alwaysand when the state is greater than zero, everything else must be equal, it is not equal to one, but to the current state, so I am passing the color. let's see what happens, you don't see anything, oh, the tone value is zero. I forgot, I can't use a hue value of zero, oh my gosh, let's give it a hue value of 200, okay, it's blue, the reason I was doing this.
I was thinking, what if the hue changed over time so that the Hue Plus value equaled 0.1 while I dragged the mouse? Well, I guess I should change it a little quicker. Oh, I love this. Well it will stop at 360, so if the H value is greater than 360 it sets it back equal to a full coding challenge, however I don't know if I can post this code without fixing it a bit. Let's write a function to help with this logic. here is a function that returns true or false if a column is in bounds or not, how should I call this within the columns I return?
I is greater than or equal to zero and I is less than equal to the columns minus one, so now I can check in here calls the column and let's do one for the rows so it cleans up this code a little bit. Now I can also clear this code, the state of the current cell, ah, look at this, I have that state variable, so I can use it here. It will make things a little more pleasant. Also, I'm checking a random address, that's fine. I don't love just making them indefinite. Let's start with them as -1 and if it's in, I'll give it the actual value and then they win.
They do not activate unless they are zero, which is not negative. I don't know if that's better, a little better, maybe I'll put some comments in the code that will help a little. Just hold that thought for a moment. second, I don't need this anymore, I dare to try this now with the smaller sand, it is divided in half, so it is beautiful, but it is missing something critical, notice how the sand falls at a constant speed, it just so happens. I've written this whole book called Nature of Code, all about physics simulation and chapter 2 is about velocity and acceleration and what is a force if not a vector that causes an object with mass to accelerate.
Is there a way to apply a gravitational acceleration to these little pieces of sand as they fall would be a bit tricky because the sand would have to fall more than one cell at a time. This is a challenge I will leave you with. I'll address it maybe on a live stream. and show any of you who submit your Falling Sand simulations to the passenger showcase. I also want to remind you to read Jason today, well, that's not his last name, but that's his URL, Jason. Today's blog post is about how to make a Falling Sand simulator and you can see here that there is a grid class ooh with a higher order function like Phil o and this swap function that allows you to swap two particles oh they're just using one. dimensional array, you might like this strategy, oh you can see there are different colors, so there are some other things you could learn by following this post, but I hope you enjoyed this coding challenge, this was technically another cellular automaton, although it's really stochastic because the way I randomly move the sand left or right as it falls and I can't wait to see what you do, have a great day oh.

If you have any copyright issue, please Contact