Thread: stuck : conways game of life (lots of code)

  1. #31
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Quote Originally Posted by anduril462 View Post
    I'm with Quzah here. Unless you can show me the specs from your assignment that say empty rows have to be null, then they don't. And they shouldn't be. It just complicates things. You can have a column with all 0's down it if there are no creatures living anywhere in that column. Why can't you have a row with all 0 elements if nothing lives there?
    Fine :


    And I've been posting the code which has a description of what the functions should do on this forum since the beginning which all clearly state:
    Quote Originally Posted by anduril462 View Post

    So compile that for me, with debugging symbols (gcc -g life.c). Then, run it in gdb and find the exact line where it fails. If you need a gdb tutorial, check here: Cprogramming.com - Tutorials - An Introduction to GDB

    Actually, we're really close with the rotate code. We somehow managed to rotate -90 degrees (1/4 turn counter-clockwise) instead.
    Sorry, but I don't think it will be particularly useful for me to compile that as it needs to work with nulls as I keep saying. I know how to use GDB, I've been using it for this thing for ages, its how I know about nulls via print(blah) etc. and back trace (bt).. etc. though it doesn't take much to see where it fails.. every time the same line. new[blah]=old[blah]

    Thanks for doing the above though it is interesting looking at how you're trying to rotate it.
    Last edited by play_fetch; 03-25-2011 at 12:19 PM.

  2. #32
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You have an entirely different problem then.
    When your evolve() and rotate() functions return, any unoccupied columns should be represented by NULLs in the arena array rather than by arrays of characters.
    Actually, you have TWO new problems with this horrible design.

    1. If I have this:

    A C

    E G

    When I rotate that 90 degrees, I now have a new column that is null.

    E A

    G C


    2. He's telling you to null out COLUMNS, not rows. That means he wants column-major, not row-major arrays. That's completely ass backwards.

    Anyway, fix both of these problems at the same time, by doing what I suggested first, except flip X and Y since your professor is an idiot, and pretend rows are columns instead of rows.

    Build yourself a function that allocates rows (columns) first, and then each length of columns (rows). Now copy all of the contents of the old one into its place. Now run through each row (column) and if there are no values in it, free that row (column) and set that pointer to NULL.


    90 degree clockwise rotation should be easy then: new[ MAXY - 1 - Y ][ X ] = old[ X ][ Y ]
    I think that's right. I had it figured out until your professor didn't know what a row and a column was anymore.


    Quzah.
    Last edited by quzah; 03-24-2011 at 03:58 PM.
    Hope is the first step on the road to disappointment.

  3. #33
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Quote Originally Posted by quzah View Post
    2. He's telling you to null out COLUMNS, not rows. That means he wants column-major, not row-major arrays. That's completely ass backwards.
    yes, I tell me about it...lol you can see why I'm getting so confused with it all
    Quote Originally Posted by quzah View Post
    Anyway, fix both of these problems at the same time, by doing what I suggested first, except flip X and Y since your professor is an idiot, and pretend rows are columns instead of rows.
    Is this what you mean by this:
    Code:
    	for(y = 0; y < *pheight; y++)
    	{
    		for(x =0; x < *pwidth; x++)
    		{
    			...
    		}
    		
    	}
    Or is that what you meant by the bit below? Or did you mean by the below you were talkiing about changing:
    Code:
    newarena = malloc((*pheight) * sizeof(char*));
    	for(x = 0; x < *pwidth; x++)
    	{
    			newarena[x] = malloc((*pwidth) * sizeof(*newarena[x]));
    	}
    Quote Originally Posted by quzah View Post
    Build yourself a function that allocates rows (columns) first, and then each length of columns (rows). Now copy all of the contents of the old one into its place.

    I understand this bit: Now run through each row (column) and if there are no values in it, free that row (column) and set that pointer to NULL. <<Actually, should we really free(arena[y]) before we have returned the newarena or are you suggesting I do that after the function has been called in the main function?
    I think your wording may be confusing me on this. Build a function... allocates rows first and then length of columns...

    Quote Originally Posted by quzah View Post

    90 degree clockwise rotation should be easy then: new[ MAXY - 1 - Y ][ X ] = old[ X ][ Y ]
    I think that's right. I had it figured out until your professor didn't know what a row and a column was anymore.
    this also makes sense to me, although I'm not entirely sure whether it will work.. will try
    Quzah.
    Sorry the wording is confusing me a little and my brain is a bit fried and worried whether I'll manage this project or not.
    Last edited by play_fetch; 03-24-2011 at 04:26 PM.

  4. #34
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Make a function that allocates a new grid:
    Code:
    char**newgrid( int cols, int rows )
    {
        char **g = NULL;
        int c = 0;
        g = malloc( y * sizeof *g );
        for( c = 0; c < cols; c++ )
            g[ c ] = malloc( r * sizeof **g );
        return g;
    }
    I did no error checking there, normally you would. Anyway, now that you can make grids that you want of any size, after you've copied the new contents over top of it:
    Code:
    void foo( char **g, int c, int r )
    {
        for each column
            for each row
                if( g[ c ][ r ] == notempty ) break;
            if r == max rows
                we made it to the end of a column without encountering anything valid
                free( g[ c ] )
                g[ c ] = NULL
    }

    Quzah.
    }
    Hope is the first step on the road to disappointment.

  5. #35
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Quote Originally Posted by quzah View Post
    Make a function that allocates a new grid:
    Code:
    char**newgrid( int cols, int rows )
    {
        char **g = NULL;
        int c = 0;
        g = malloc( y * sizeof *g );
        for( c = 0; c < cols; c++ )
            g[ c ] = malloc( r * sizeof **g );
        return g;
    }
    I did no error checking there, normally you would. Anyway, now that you can make grids that you want of any size, after you've copied the new contents over top of it:
    Code:
    void foo( char **g, int c, int r )
    {
        for each column
            for each row
                if( g[ c ][ r ] == notempty ) break;
            if r == max rows
                we made it to the end of a column without encountering anything valid
                free( g[ c ] )
                g[ c ] = NULL
    }

    Quzah.
    }
    Is there a way we could do this in one function as I'm not sure we can make our own functions... I can see how todo the first bit maybe
    Code:
    char** newarena = NULL;
    	int i = 0;
        	newarena = malloc( *pwidth * sizeof(*newarena));
        	for( i = 0; i < cols; c++ )
            newarena[ i ] = malloc( *pheight * sizeof(**newarena));
    perhaps
    Last edited by play_fetch; 03-24-2011 at 04:47 PM.

  6. #36
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Sure. Just attach the loops in the bottom function to the portion of that function after you have copied the contents over.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #37
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Quote Originally Posted by quzah View Post
    Sure. Just attach the loops in the bottom function to the portion of that function after you have copied the contents over.


    Quzah.
    Oh okay well I didn't try to do it because I couldn't get my head around how to deal with the break bit etc.

    Is this OK in theory?

    Code:
    code removed..
    Last edited by play_fetch; 03-25-2011 at 12:17 PM.

  8. #38
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You can't just free(arena) there. You have to free each column (since you're doing it backwards) first. You need one free call for every associated *alloc call you have made.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #39
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Quote Originally Posted by quzah View Post
    You can't just free(arena) there. You have to free each column (since you're doing it backwards) first. You need one free call for every associated *alloc call you have made.


    Quzah.
    The freeing arena is the old arena passed to the rotate method so surely that is okay as it isn't needed any more? I can't free anything (relating to newarena) until I return it anyway can I?

  10. #40
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by play_fetch View Post
    The freeing arena is the old arena passed to the rotate method so surely that is okay as it isn't needed any more? I can't free anything (relating to newarena) until I return it anyway can I?
    You aren't understanding:
    Code:
    char**r;
    r = malloc( 3 * sizeof *r ); /*1*/
    for( x = 0; x < 3; x++ )
        r[x] = malloc( 4 * sizeof **r ); / 3 more */
    You need four free calls to properly free that:
    Code:
    for( x = 0; x < 3; x++ )
        free( r[x] );
    free( r );
    You can't just free( r ), you have to free each column r contains first.


    Quzah.
    Hope is the first step on the road to disappointment.

  11. #41
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Quote Originally Posted by quzah View Post
    You aren't understanding:
    Code:
    char**r;
    r = malloc( 3 * sizeof *r ); /*1*/
    for( x = 0; x < 3; x++ )
        r[x] = malloc( 4 * sizeof **r ); / 3 more */
    You need four free calls to properly free that:
    Code:
    for( x = 0; x < 3; x++ )
        free( r[x] );
    free( r );
    You can't just free( r ), you have to free each column r contains first.


    Quzah.
    So you're saying I need to loop through each x < *pwidth for arena[x] and free it? In the main code and then free(arena)?

    I'm sorry I don't catch on so quick but I get confused easily with all the rows and cols being different etc.

    Code:
    code removed
    Last edited by play_fetch; 03-25-2011 at 12:17 PM.

  12. #42
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Yes. Each time you call malloc, it grabs a separate chunk of memory. You call malloc once for the major dimension, then call it *pwidth times inside the loop, once for each column. Assuming *pwidth was 5, you actually call malloc 6 times. The first call is stored in arena. The second through sixth calls are stored in arena[0]..arena[4]. Thus, you need 6 calls to free. You have to do it in reverse order, so first you loop and free arena[0]..arena[4] (that's 5 calls so far), then call free(arena). That way you have a corresponding call to free for each call to malloc and don't have a memory leak.

    If you just call free(arena), you only free the memory allocated by the first call to malloc. That memory becomes invalid and you don't have access to arena[0]..arena[4], so you can't free that memory. Do this enough times, and you've allocated all your memory, but can't actually use any of it because you lost the pointers to it.

  13. #43
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    That's why I was advocating separate functions to allocate and free your grids. You could then just do:
    Code:
    newgrid = getgrid( newcols, newrows );
    ... do rotate ...
    freegrid( oldgrid, oldsize );
    For one, your code looks cleaner. Plus you know that once you have the function that works correctly, you can just use it without having to recheck all your new code, and make sure you didn't forget anything.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #44
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Considering the assignment didn't say "don't create additional functions", I would say it's safe. You could always ask your prof to find out for sure.

  15. #45
    Registered User
    Join Date
    Mar 2011
    Posts
    57
    Well I'm going to be doing similar things for evolve I imagine, so a separate function is good to have around.. I may need to move it to another c file. They said it was OK to create another .c file, so, I assume functions are OK too.

    So this code below looks OK (except I know it isn't perfect due to lots of error messages)? I'm getting errors about implicit function calls and such.. not sure what it means by that I'm not familiar with that error.
    Last edited by play_fetch; 03-25-2011 at 12:18 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A Simple Life Game Code - Near the end ?
    By apolochaves in forum C Programming
    Replies: 6
    Last Post: 08-05-2010, 03:32 AM
  2. Conways Game using Pointers
    By NewUser in forum C Programming
    Replies: 10
    Last Post: 03-22-2010, 04:15 PM
  3. 'Business code' vs 'Game code'
    By VirtualAce in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-09-2007, 03:33 AM
  4. Game of life
    By JoshR in forum C++ Programming
    Replies: 30
    Last Post: 04-03-2005, 02:17 PM
  5. game code
    By The WaRped OnE in forum Game Programming
    Replies: 1
    Last Post: 02-28-2002, 08:46 PM