Topic: Conway's Game of Life (Read 673 times)

  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
right, i have a project, i have to make Conway's game of life into an actual game, the thing is i'm not sure how to go about converting the rules into a number driven algorithm that can drive the basic mechanics of the game, so i thought i'd ask here if some one knew how to go about doing it? Just to be clear, i'm not asking you to tell me what to do, i'm asking how to go about doing it.

here is a link to the rules of the simulation: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
RIP DoktorMartini

My brute!
  • Avatar of EvilDemonCreature
  • i don't like change
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Jul 5, 2002
  • Posts: 1453
so i thought i'd ask here if some one knew how to go about doing it? Just to be clear, i'm not asking you to tell me what to do, i'm asking how to go about doing it.

Man, figuring out how to go about doing it is where all the fun is. Especially when it comes to a game that can only play itself.

Just hearing you ask makes me want to make this game myself. If I find out how soon enough, then I'll be sure to let you know what direction you need to go in. I did do something involving work with 2-d image arrays and their adjacency relationships though.

It looks like you need three things to start off:
#1 A way to express a cell as "alive" and "dead".
#2 An efficient way to check the status of any/all neighboring cells.
#3 A quick, efficient way to seek out and exclusively identify "3-adjacency" cells. (note that this has to be done for dead cells as well, since that's how the game generates new living cells to begin with)

If you make it so that #3 is it's own grid, then you have successfully generated the next state of the automate, and can run everything on a loop from there on out.

Forgive me if I answered with exactly what you didn't need to be told, I'm having a hard time figuring out exactly what you mean when you ask "how can I go about doing it?". That question is different for any person trying to do anything, and my best advice is to go straight into it and try. The worst thing that can happen is that you fail. Even so, that's still a good thing for you because that way you'll at least know a lot more about what you want to ask next time you ask for advice.
Last Edit: February 07, 2010, 07:07:45 pm by EvilDemonCreature
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
what i mean is i don't want instructions like "well to create this, you need to do this and this and this," what i'm looking for is more along the lines of "well you need to research this sort of thing or try looking at this" and so on, but what you've written was actually helpfull, so thanks.
any way. to store the data of the array i was thinking of either doing two 2D arrays, one that represents the current state, and one that represents the next iteration but storing changes in the second array only, then once it's filled with the next iteration the data of the second array is flushed back to the first one and then cleared so the process can start again. the other way was to create a single 3D array, so there are two layers, and when it changes somthing the second layer gets a flag to either switch on or off the block of the layer above it in the same (x,y) position, effectivly copying the second layer to the first layer and then invert it so all 1's become 0's , both arrays wil be bools as it only needs 1's or 0's.

the real problem isn't storing the data but what you put as number 2 and 3. i can think of a way, but it checks each cell one by one and i'm not sure it would be quick enough. if i can work out how to do checks like this then i could make this.
RIP DoktorMartini

My brute!
  • Avatar of Ciox
  • Buttshit.
  • Group: Member
  • Joined: May 21, 2009
  • Posts: 55
checking neighbouring cells should be like:

- left cell: current-1
- right cell: current+1
- top cell: current - the number of cells in a row (so 10 if your table is 10x10)
- bottom cell: same but with +

the diagonals would be combinations of those
valves industrial valves tanks and valves valves and ball valves excess flow valves control valves valves industrial solenoid valves quality valves expansion valves check valves gas valves automatic drain valves gate valves air valves relief valves
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
right, i got the displaythingy to work so now i have a grid with cells that can be switched on and off (display wise, no logic)
so which would be better, a single two layer array where i flag each block to be changed on the second layer and then change acourdingly  or two single layer arrays and check the first array's data and modify the second acourdingly.

EDIT:
[RANT]
i realise this is unrelated but i REALLY need to get this out or i might blow a gasket, I HATE it when game devs say how there helping when all there really doing is repeating the same spew. take my problem, i can't access Star trek online becuase of some error, now aparrantly they've said it's becuase the launcher can't access the server, fair does, i however did 100% point out that all the ports neccessary are unblocked, so if it's not them what else could it be? but instead of giving an idea of what it could be all i get is a dev saying "blah blah blah, we've already gone over this, stop wasting dev time", in other words they really didn't read all the info i've provided, god they piss me off SOOO much.
[/RANT]
Last Edit: February 07, 2010, 10:56:56 pm by Swordfish
RIP DoktorMartini

My brute!
  • Avatar of Ciox
  • Buttshit.
  • Group: Member
  • Joined: May 21, 2009
  • Posts: 55
the array layer thing strikes me as something that seems important, but really isn't, mainly because the copying will work at practically the same speed and you won't need more than two "layers", so you can just use two 2d arrays for simplicity
valves industrial valves tanks and valves valves and ball valves excess flow valves control valves valves industrial solenoid valves quality valves expansion valves check valves gas valves automatic drain valves gate valves air valves relief valves
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
hmmm after thinking about i've decided to go with the first method becuase in my opnion it will be easier becuase to access either layer there is only one differance between the two, a 0 and 1 so i can use a vairable ot somthing else to controll which layer is being accessed at that moment plus i think it would be easier to deal with just the one array, now to work on the rules.

public void update()
        {
            Point currentCell = new Point(0, 0);
            // phase one checks each square on the current frame layer, if within the rules then it flags that square on the update array
            // rows
            for (int x = 0; x < 10; x++)
            {
                // columbs
                for (int y = 0; y < 10; y++)
                {
                    // tallys up neighbers (and sets the count to zero)
                    int celltally1 = 0;
                    int celltally2 = 0;
                    currentCell.X = x;
                    currentCell.Y = y;
                    // checks all neighbering cells
                    // left
                    if (currentCell.X > 0)
                    {
                        if (pGrid[currentCell.X - 1, currentCell.Y] >= 1)
                        {

                            celltally1++;
                        }
                        if (pGrid[currentCell.X - 1, currentCell.Y] >= 2)
                        {

                            celltally2++;
                        }
                    }
                    // up
                    if (currentCell.Y > 0)
                    {
                        if (pGrid[currentCell.X, currentCell.Y - 1] >= 1)
                        {
                            celltally1++;
                        }

                        if (pGrid[currentCell.X, currentCell.Y - 1] >= 2)
                        {
                            celltally2++;
                        }

                    }
                    // right
                    if (currentCell.X < 100)
                    {
                        if (pGrid[currentCell.X + 1, currentCell.Y] >= 1)
                        {
                            celltally1++;
                        }

                        if (pGrid[currentCell.X + 1, currentCell.Y] >= 2)
                        {
                            celltally2++;
                        }

                    }
                    // down
                    if (currentCell.Y < 100)
                    {
                        if (pGrid[currentCell.X, currentCell.Y + 1] >= 1)
                        {
                            celltally1++;
                        }

                        if (pGrid[currentCell.X, currentCell.Y + 1] >= 2)
                        {
                            celltally2++;
                        }
                    }

                    // up right
                    if (currentCell.Y > 0 && currentCell.X < 100)
                    {
                        if (pGrid[currentCell.X + 1, currentCell.Y - 1] >= 1)
                        {
                            celltally1++;
                        }

                        if (pGrid[currentCell.X + 1, currentCell.Y - 1] >= 2)
                        {
                            celltally2++;
                        }
                    }
                    // up left
                    if (currentCell.Y > 0 && currentCell.X > 0)
                    {
                        if (pGrid[currentCell.X - 1, currentCell.Y - 1] >= 1)
                        {
                            celltally1++;
                        }

                        if (pGrid[currentCell.X - 1, currentCell.Y - 1] >= 2)
                        {
                            celltally2++;
                        }
                    }
                    //down right
                    if (currentCell.Y < 100 && currentCell.X < 100)
                    {
                        if (pGrid[currentCell.X + 1, currentCell.Y + 1] >= 1)
                        {
                            celltally1++;
                        }

                        if (pGrid[currentCell.X + 1, currentCell.Y + 1] >= 2)
                        {
                            celltally2++;
                        }
                    }
                    // down left
                    if (currentCell.Y < 100 && currentCell.X > 0)
                    {
                        if (pGrid[currentCell.X - 1, currentCell.Y + 1] >= 1)
                        {
                            celltally1++;
                        }
                        if (pGrid[currentCell.X - 1, currentCell.Y + 1] >= 2)
                        {
                            celltally2++;
                        }
                    }
                   
                    // rules fo alive cells
                    if (pGrid[currentCell.X, currentCell.Y] != 0)
                    {                     
                       

                        // rule = less then 2 A neighbers then kill cell
                        if (celltally1 < 2)
                        {
                           
                            pGridU[currentCell.X, currentCell.Y] = 0;
                           
                        }
                        // rule = Greater then 3 A neigbers then kill cell
                        if (celltally1 > 3)
                        {
                            pGridU[currentCell.X, currentCell.Y] = 0;
                           
                        }
                        // rule = less then 2 B neighbers then kill cell
                        if (celltally2 < 2)
                        {

                            pGridU[currentCell.X, currentCell.Y] = 0;

                        }
                        // rule = Greater then 3 B neighbers then kill cell
                        if (celltally2 > 3)
                        {
                            pGridU[currentCell.X, currentCell.Y] = 0;

                        }
                        // rule = if more B cells then A, convert cell to B
                        if (celltally2 > celltally1)
                        {

                            pGridU[currentCell.X, currentCell.Y] = 2;

                        }

                        // rule = if more A cells then B convert cell to A
                        if (celltally2 < celltally1)
                        {

                            pGridU[currentCell.X, currentCell.Y] = 1;

                        }


                        //// rule = if enough A cells then keep as A
                        //if (celltally1 > 1 && celltally1 < 4)
                        //{

                        //    pGridU[currentCell.X, currentCell.Y] = 1;

                        //}
                        // //rule = if enough B cells then keep as B
                        //if (celltally2 > 1 && celltally2 < 4)
                        //{

                        //    pGridU[currentCell.X, currentCell.Y] = 2;

                        //}
                    }
                    else
                    {

                        // rules for dead cells
                        // rule = if 3 A neighbers then make cell alive as A
                        if (celltally1 == 3)
                        {
                            pGridU[currentCell.X, currentCell.Y] = 1;
                        }
                         //rule = if 3 B neighbers then make cell alive as B
                        if (celltally2 == 3)
                        {
                            pGridU[currentCell.X, currentCell.Y] = 2;
                        }
                    }
               
                }

            }
            // phase two moves the update array to the current frame array
           
            for (int y = 0; y < 10; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    pGrid[x, y] = pGridU[x, y];


                }
            }
            // Phase three clears the update layer, as in reset
            Clear();


        }

*sigh* i'm not sure what to do, i've changed the grid to int so i can have two seprate cell types, (player 1 and 2) now the thing is, type 1 (or A) doesn't die off and type 2 (or B) doesn't last past the first update phase, i really don't know what's cuasing it. any ideas?
Last Edit: February 08, 2010, 02:39:58 pm by Swordfish
RIP DoktorMartini

My brute!
  • Avatar of EvilDemonCreature
  • i don't like change
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Jul 5, 2002
  • Posts: 1453
right, i got the displaythingy to work so now i have a grid with cells that can be switched on and off (display wise, no logic)
so which would be better, a single two layer array where i flag each block to be changed on the second layer and then change acourdingly  or two single layer arrays and check the first array's data and modify the second acourdingly.

Really any organization method can work for your two arrays, as long as you have a distinct method of accessing each one. I would assume having two distinct 2d arrays for your grid would be easier to track than a single 3d array that accounts for both stages of your grid, but that's my personal preference, and exactly why you can do it either way to suit whichever method feels simplest to you.

In fact, if you are familiar with using pointers for accessing/modifying your variables, you can simplify the act of converting the first array to the second one. Since the second array is going to have it's values filled in for the next step of your algorithm, instead of copying the entire set of values into your first array, you just switch the pointers. The main array will now point to what is generated by the second array, and represent the game in it's next step. Now the array used for generating the new step is pointing to the data from the previous step, so you can already go and start writing over it.

It might make more sense if you look up pointers. I'm just going from here on out assuming it's easy enough for you to find out things you don't already know about, based on the fact you do indeed want to make something like this in the first place. (is this C++? Because array indices of 0 can always work as pointers if I'm not mistaken)
Last Edit: February 09, 2010, 03:10:12 pm by EvilDemonCreature
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
A) this is c#
b) i've got it working now, i mucked up some checks that wern't limiting the checking area correctly, now the rules are applied peroperly and yeah it works, now i'm working on input, UI and level structure, once that's done i'm gonna add a third type with slightly differant rules (slower spread, harder to kill and goes against both sides).
RIP DoktorMartini

My brute!
  • Avatar of EvilDemonCreature
  • i don't like change
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Jul 5, 2002
  • Posts: 1453
I was thinking about this game a lot since you brought it up. I might end up making my own system.

I was thinking not just other "types" of spreading cells, but a system for developing your own cells with completely customized rule sets, using the paradigm set by Conway as a template and from there see just how far things can be taken without making any rules that are too hard to keep track of.

I am literally on the fence about perusing this idea on my own regardless. (It'd be a good enough excuse to get really familiar with C# since you have already proven the basic system can be set up in a relatively short amount of time. Are you using XNA for displaying the graphics or something else?)

EDIT: Saw your screenshots (which makes things obvious now), about how long did it take for you to get things that far along?
Last Edit: February 09, 2010, 10:42:22 pm by EvilDemonCreature
  • Avatar of JohnnyCasil
  • Comrade!
  • PipPipPipPip
  • Group: Premium Member
  • Joined: Jan 5, 2005
  • Posts: 453
A) this is c#

There is nothing stopping you from using pointers in C# BTW.  You just need to enable unsafe code in your project.  It will even work on the 360.
  • Avatar of EvilDemonCreature
  • i don't like change
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Jul 5, 2002
  • Posts: 1453
There is nothing stopping you from using pointers in C# BTW.  You just need to enable unsafe code in your project.  It will even work on the 360.

My recommendation would be to just go with what you have already working. No sense in the chance of mussing things up because things can get confusing real quick when it comes to pointer references.

I'm probably going to use pointers for the design I'm imagining for implementing this algorithm since I know this now. If only to see whether or not it can actually work out the way I imagine. I'm a risk-taker myself, so I don't mind a little trial by fire here or there.

Although I have other affairs that need my current attention. I really want to be taking whatever class you're taking!
Last Edit: February 10, 2010, 04:21:38 am by EvilDemonCreature
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
i'm doing computer games programming at derby university. Any way i was replying to his question as to if this was in C++ or C# and the beauty of XNA is that it has a pointer class built in (x,y) which is PERFECT for pointing to the current cell, or even in game so i'm using that and you don't need to turn unsafe code on.
any way, once i've got input working poperly (and a ui, i'm going to work on the next iteration which is to include an extra side that has slightly differant rules. high score will be calculated on time it takes to win the round, this third side will affect it it's harder to beat (slower but takes more squares around it to win, like maybe at least 4? either that or a puzzle game, you place down shapes (or make them yourself) that can clear the board, like a gun or a spaceship :)
RIP DoktorMartini

My brute!
  • Avatar of JohnnyCasil
  • Comrade!
  • PipPipPipPip
  • Group: Premium Member
  • Joined: Jan 5, 2005
  • Posts: 453
I don't think you understand what a pointer is in reference to programming.
Pointer
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
I know what a pointer is, it, points to the place in memory that a variable is(in other words, it stores the memmory address of that variable), then you can use the pointer to manipulate that variable or the objects properties. But there is no point using a pointer for somthing like this, it's far more then what's needed. still thanks for the sugestion.
EDIT: wow, i intended to start working on it more, but that was 2 hours ago :P.
RIP DoktorMartini

My brute!
  • Avatar of EvilDemonCreature
  • i don't like change
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Jul 5, 2002
  • Posts: 1453
EDIT: wow, i intended to start working on it more, but that was 2 hours ago :P.

The story of my life.
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
right, well that's it, times up i won't be uploading it since i kind of didn't get it working adaquatly, i might come back to it in the furture if i do ill post it then, thanks for the help.  Still, i learnt alot about XNA and game implimentation so it served it's perpose, i think the main reason i failed wasn't becuase of bad code (well yeah but that's not it) but sloppy coding style (which in turn cuased the bad code, see wasn't just bad code), in the future i won't be so sloppy so problems that occur will be easier to deal with.
I wonder what the next game we have to make will be?
RIP DoktorMartini

My brute!
  • Avatar of EvilDemonCreature
  • i don't like change
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Jul 5, 2002
  • Posts: 1453
right, well that's it, times up i won't be uploading it since i kind of didn't get it working adaquatly, i might come back to it in the furture if i do ill post it then, thanks for the help.  Still, i learnt alot about XNA and game implimentation so it served it's perpose, i think the main reason i failed wasn't becuase of bad code (well yeah but that's not it) but sloppy coding style (which in turn cuased the bad code, see wasn't just bad code), in the future i won't be so sloppy so problems that occur will be easier to deal with.
I wonder what the next game we have to make will be?

If you got at least that much working, then at least post that part. That way, I won't have to figure it out over again on my own if I do try making one myself.

I don't like copying bad code so I'll write it again from scratch, but seeing some working code will help me get the gist of XNA implementation architecture a lot more quickly, especially in the context of displaying colored squares on a grid.
  • Avatar of Swordfish
  • Comrade!?! I AM NOT A FUCKING RUSSIAN
  • PipPipPipPipPipPipPip
  • Group: Premium Member
  • Joined: Sep 12, 2003
  • Posts: 1074
you want the code? ok, but there isn't much XNA implimentation in the grid class beyond points, tell you what, ill zip up the .cs files and you can look at them, if you use any of it i don't mind, just credit what you used.
clicky
out next one is battleships, i actually had a really good idea, but this time we have to as a team change somthing then impliment it solo, luckly all they did was add a new atack type that you can use every so often, once that's done i'm going to impliment my idea (this time i will finish it as it's somthning that will be fun, imho).
RIP DoktorMartini

My brute!