# Game of life: Initializing a struct with two 2D arrays

Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last
• 12-02-2008
Brafil
Game of life: Initializing a struct with two 2D arrays
Hi! After working on a python version, I'm writing another Game of life. I use a struct with two 2D arrays, each representing the current and the next grid. But I don't wan't to loop over each element and setting it to zero, because, the item array[56][62] is always 2089869164. how can that be? Here is my code (it doesn't work):

Code:

```#define GRID_SIZE 64 typedef struct {         unsigned int states[GRID_SIZE][GRID_SIZE];         unsigned int next_states[GRID_SIZE][GRID_SIZE]; } Cells; Cells *Cells_New() {         Cells cells;         unsigned int states[GRID_SIZE][GRID_SIZE] = {0};         unsigned int next_states[GRID_SIZE][GRID_SIZE] = {0};         cells.states = states;         cells.next_states = next_states;         return &cells; }```
Why can't I just use:
Code:

```typedef struct {         unsigned int states[GRID_SIZE][GRID_SIZE] = {0};         unsigned int next_states[GRID_SIZE][GRID_SIZE] = {0}; } Cells;```
???
• 12-02-2008
QuantumPete
That's because this part:
Code:

```typedef struct {         unsigned int states[GRID_SIZE][GRID_SIZE];         unsigned int next_states[GRID_SIZE][GRID_SIZE];```
is a declaration. It basically says what the struct contains.
This part:
Code:

`} Cells;`
actually creates an instance. I hope you'll agree that only instances can have values assigned? So you cannot assign 0 to the declaration. But you can do the following:
Code:

```Cells cells; memset (&cells, 0, sizeof (Cells);```
QuantumPete
• 12-02-2008
Brafil
What does memset do? Set all the memory there to zero? That's a good Idea! Thanks. And What is the difference between
Code:

`typedef struct {...} Cells`
and

Code:

`typedef struct Cells{...} Cells`
?
• 12-02-2008
tabstop
Quote:

Originally Posted by Brafil
What does memset do? Set all the memory there to zero? That's a good Idea! Thanks. And What is the difference between
Code:

`typedef struct {...} Cells`
and

Code:

`typedef struct Cells{...} Cells`
?

The second creates a named struct ("struct Cells") and then sets the alias to be Cells, while the first creates an unnamed struct and then sets the alias. The second version would be necessary if you needed a pointer to struct inside the struct itself, as the typedef alias doesn't get set until the end.
• 12-02-2008
King Mir
Quote:

Originally Posted by Brafil
Hi! After working on a python version, I'm writing another Game of life. I use a struct with two 2D arrays, each representing the current and the next grid. But I don't wan't to loop over each element and setting it to zero, because, the item array[56][62] is always 2089869164. how can that be? Here is my code (it doesn't work):

Code:

```#define GRID_SIZE 64 typedef struct {         unsigned int states[GRID_SIZE][GRID_SIZE];         unsigned int next_states[GRID_SIZE][GRID_SIZE]; } Cells; Cells *Cells_New() {         Cells cells;         unsigned int states[GRID_SIZE][GRID_SIZE] = {0};         unsigned int next_states[GRID_SIZE][GRID_SIZE] = {0};         cells.states = states;         cells.next_states = next_states;         return &cells; }```

You can't assign arrays to one another. You would have to copy each member over one by one.

In this case you could loop through each element, setting the value to 0. Or as QuantumPete suggests use a more primitive function to zero out each byte.

Quote:

Why can't I just use:
Code:

```typedef struct {         unsigned int states[GRID_SIZE][GRID_SIZE] = {0};         unsigned int next_states[GRID_SIZE][GRID_SIZE] = {0}; } Cells;```
???
Because C does not support default values for structs using this or any other syntax.
• 12-02-2008
QuantumPete
Quote:

Originally Posted by Brafil
What does memset do? Set all the memory there to zero?

First argument is the first byte of the variable to be changed, second the bitmask you want, third the number of bytes from the start of the first argument.
You can also memset things to 1 or 8 or 'F'. Whatever you want, but most of the time it is used to zero out memory.

[QUOTE=King Mir;812949]
Quote:

Originally Posted by King Mir
Or as QuantumPete suggests use a more primitive function to zero out each element.

Oi! Primitive it might be, but it saves you the overhead of repeated (in this case nested) loops and the associated iteration variables. For something as simple as zero'ing out large amounts of memory I would always use memset over a loop.

QuantumPete
• 12-02-2008
Brafil
but it's a weird BUG! It still says that array[55][62] is 2089869164! What's that? I have 512 MB of RAM, and 64 * 64 * 4 = 16 MB!

PS: It was at [55], not at [56]!
• 12-02-2008
slingerland3g
What is actually stating this 2d array is 2089869164? Are you trying to simply print out the size of each element within the array or the whole size of this 2D array?
• 12-02-2008
King Mir
@QuantumPete
I totally agree that memcpy is the best solution in this case. It is however not a generic solution to this problem, and so I left it as an aside.
• 12-03-2008
Brafil
It's simply a
Code:

`printf("... &#37;d\n", array[x][y]);`
operation. It ALWAYS says 280... (i don't remember, look for my previous post)

And wth does SDL change stdout to stdout.txt so it writes everything into this file rather than on the screen?
• 12-03-2008
Salem
Show us the code containing the printf statement.
My guess is you forgot arrays begin at 0 and not 1.

> And wth does SDL change stdout to stdout.txt so it writes everything into this file rather than on the screen?
Because SDL is a window, and there is no console.
Maybe if you call AllocConsole() before initialising SDL, it will use that instead?
Maybe this as well - http://clusty.com/search?query=SDL+s...Mozilla-search
• 12-03-2008
Brafil
Well, now Im using pointers rather than 2D arrays... It still says the SAME with malloc()!
(And maybe the stdout text file is better as a log file)

cells.h
Code:

```#include <SDL\SDL.h> #include <stdio.h> #define GRID_SIZE 64 typedef struct {         int *states;         int *next_states; } Cells; int Array_Get(int *array, int position) {         return *(array + position); } void Array_Set(int *array, int position, int value) {         *(array + position) = value; } Cells *Cells_New() {         Cells *cells;         cells->states = malloc(GRID_SIZE * GRID_SIZE * sizeof(int));         cells->next_states = malloc(GRID_SIZE * GRID_SIZE * sizeof(int));         memset(cells, 0, sizeof(*cells));         return cells; } int Cells_Get(Cells *cells, int x, int y) {         return *(cells->states + x * GRID_SIZE + y); } int Cells_GetNext(Cells *cells, int x, int y) {         return *(cells->next_states + x * GRID_SIZE + y); } void Cells_Set(Cells* cells, int x, int y, int value) {         *(cells->states + x * GRID_SIZE + y) = value; } void Cells_SetNext(Cells *cells, int x, int y, int value) {         *(cells->next_states + x * GRID_SIZE + y) = value; } int *Cells_GetRow(Cells *cells, int x) {         return cells->states + x * GRID_SIZE; } int *Cells_GetNextRow(Cells *cells, int x) {         return cells->next_states + x * GRID_SIZE; }```
PS: I'm very Python-oriented, but I want to make it fast, so there is room for optimizations later, f.e. macros instead of Set, Get(Next) etc...
• 12-03-2008
matsp
Code:

`*(cells->states + (x * GRID_SIZE + y) * sizeof(int)`
Unless you only want every fourth cell to actually contain soemthing, you should remvoe the sizeof(int) - you are after all dealing with a int*, and C will automatically scale your pointer addition or subtraction by the size of the pointer element.

--
Mats
• 12-03-2008
Brafil
Oh! Thanks! So I remove all sizeofs except those in malloc, but it still doesnt work. Wait! It doesnt go till there. Im looking now...

PS: Are you sure? Because it now hangs at the first loop! It seems like there is no pointer to array[0][0]?

Well, here the whole code:

gof.h:
Code:

```#include <SDL\SDL.h> #include <stdio.h> SDL_Surface *screen; SDL_Event *event; SDL_Color *color; SDL_Rect *rect; int init() {         int red, green, blue;         if (SDL_Init(SDL_INIT_EVERYTHING)) {                 fprintf(stderr, "Couldn't initialize SDL: &#37;s\n", SDL_GetError());                 return 1;         }         atexit(SDL_Quit);         screen = SDL_SetVideoMode(512, 512, 0, SDL_SWSURFACE);         if (!screen) {                 fprintf(stderr, "Couldn't initialize the screen: %s\n", SDL_GetError());                 return 1;         }         red = 0;         green = 255;         blue = 255;         color = SDL_MapRGB(screen->format, red, green, blue);         return 0; } #define Screen_Update(screen) SDL_UpdateRect((screen), 0, 0, 0, 0); #define Draw_Cell(x, y) rect->x = (x) * 8; rect->y = (y) * 8; rect->w = 8; rect->h = 8; SDL_FillRect(screen, rect, color)```
cells.h (like above)
Code:

```#include <SDL\SDL.h> #include <stdio.h> #define GRID_SIZE 64 typedef struct {         int *states;         int *next_states; } Cells; int Array_Get(int *array, int position) {         return *(array + position); } void Array_Set(int *array, int position, int value) {         *(array + position) = value; } Cells *Cells_New() {         Cells *cells;         cells->states = malloc(GRID_SIZE * GRID_SIZE * sizeof(int));         cells->next_states = malloc(GRID_SIZE * GRID_SIZE * sizeof(int));         memset(cells, 0, sizeof(*cells));         return cells; } int Cells_Get(Cells *cells, int x, int y) {         return *(cells->states + x * GRID_SIZE + y); } int Cells_GetNext(Cells *cells, int x, int y) {         return *(cells->next_states + x * GRID_SIZE + y); } void Cells_Set(Cells* cells, int x, int y, int value) {         *(cells->states + x * GRID_SIZE + y) = value; } void Cells_SetNext(Cells *cells, int x, int y, int value) {         *(cells->next_states + x * GRID_SIZE + y) = value; } int *Cells_GetRow(Cells *cells, int x) {         return cells->states + x * GRID_SIZE; } int *Cells_GetNextRow(Cells *cells, int x) {         return cells->next_states + x * GRID_SIZE; }```
gof.c:

Code:

```#include <SDL\SDL.h> #include <stdio.h> #include "gof.h" #include "cells.h" Cells *Cells_Calculate(Cells *cells) {         int x, y;         for (x = 0; x < GRID_SIZE; x++) {                 printf("New Row %d\n", x);                 int *prev_row = Cells_GetRow(cells, (GRID_SIZE + x - 1) % GRID_SIZE);                 int *current_row = Cells_GetRow(cells, x);                 int *next_row = Cells_GetRow(cells, (x + 1) % GRID_SIZE);                 printf("Calculating row...\n");                 for (y = 0; y < GRID_SIZE; y++) {                         //printf("\tNew Cell (%d, %d) is \t%d\n", x, y, Cells_Get(cells, x, y));                         printf("\tNew Cell (%d, %d)\n", x, y);                         int prev_item = (GRID_SIZE + y - 1) % GRID_SIZE;                         int next_item = (y + 1) % GRID_SIZE;                         int neighbours = 0;                       /* Ignore this fprintf please for now */                         fprintf(stderr, "\n");                         neighbours += Array_Get(prev_row, prev_item);                         neighbours += Array_Get(prev_row, y);                         neighbours += Array_Get(prev_row, next_item);                         neighbours += Array_Get(current_row, prev_item);                         neighbours += Array_Get(current_row, next_item);                         neighbours += Array_Get(next_row, prev_item);                         neighbours += Array_Get(next_row, y);                         neighbours += Array_Get(next_row, next_item);                         if (neighbours == 3) Cells_SetNext(cells, x, y, 1);                         else if (neighbours != 2 && !Cells_Get(cells, x, y)) Cells_SetNext(cells, x, y, 0);                 }         }         return cells; } Cells *Cells_Draw(Cells *cells) {         int x, y;         for (x = 0; x < GRID_SIZE; x++) {                 printf("NewRow %d\n", x);                 for (y = 0; y < GRID_SIZE; y++) {                         printf("\tNewCol (%d, %d) is \t%d\n", x, y, Cells_GetNext(cells, x, y));                         if (Cells_GetNext(cells, x, y)) {                                 Cells_Set(cells, x, y, 1);                                 Draw_Cell(x, y);                         }                         else {                                 Cells_Set(cells, x, y, 0);                         }                 }         } } int main(int argc, char **argv) {         int x, y;         Cells *cells = Cells_New(64, 64);         if (init()) {                 printf("Error initializing the game. Press any key to quit...\n");                 getchar();                 return 1;         }         printf("Initialized\n");         cells = Cells_Draw(Cells_Calculate(cells));         printf("Calculated\n");         Screen_Update(screen);         return 0; }```
• 12-03-2008
matsp
Quote:

Originally Posted by Brafil
Oh! Thanks! So I remove all sizeofs except those in malloc

Yes, they are obviously needed in malloc, since you are giving a size of something, which is in bytes. But ptr + n will give the nth element of whatever the pointer points at, no matter what size the type the pointer points at is.

--
Mats
Show 80 post(s) from this thread on one page
Page 1 of 2 12 Last