0

This is my first stackoverflow post.

I am doing the CS50 course on edx and currently I am stuck at problem set 3. I am implementing the game of fifteen. The init() function initizalizes the board and the draw function should draw it but there is a problem.

The draw function does not get the values from the init() function. I experimented with it, in the init() function the values are correct, but in the draw function all of them are 0's.

What's the problem?

/**
 * Initializes the game's board with tiles numbered 1 through d*d - 1
 * (i.e., fills 2D array with values but does not actually print them).  
 */
void init(void)
{
    //initializing the board
    int board[d][d];
    int x = (d*d) -1;
    //this loop goes trough each row
    for(int i = 0; i < d; i++){
        //this goes trough each column
        for(int j = 0; j < d ; j++){
            //this condition handles the case of swapping the 2 and 1 when the grid is even
            if( (d % 2) == 0 && (x == 2) ){
                //assigning the number 1
                board[i][j] = x-1;

                //going to the next column
                j++;

                //assigning the number 2
                board[i][j] = x;

                //setting the x = 0 so the loop can end
                x=0;
            }
            //this happens if the above conditions are not met
            else {
                //assigning the value to the grid
                board[i][j]= x;

                //decrementing the value
                x--;
            }
            //ending the loop
            if(x == 0){
                break;
            }
        }
        //ending the loop after the last tile is initialized
        if(x == 0){
            break;
        }
    }
}
/**
 * Prints the board in its current state.
 */
void draw(void)
{
    for(int i = 0; i < d; i++){
        for(int j = 0; j < d; j++){
            if(board[i][j] != 0){
                printf("%2i", board[i][j]);
            } else {
                printf("_");
            }
        }

    printf("\n");    

    }  
Morteza Asadi
  • 1,819
  • 2
  • 22
  • 39

2 Answers2

2

This might help you: https://www.tutorialspoint.com/cprogramming/c_scope_rules.htm

Basically everything what you do in your init function (variable names & values) are only valid in this function or block.

To solve this you can either make int board[d][d]; a global variable by declairing it above the main function like so (highly discouraged!):

int board[d][d];

int main(int argc, char** argv){ ... }

OR you could give the varibale board[d][d] as a reference to your function draw. This works but is inefficient because the whole variable will be copied.

void draw(int board[][]){...}

OR you can allocate memory for board[d][d] on the heap by using the c command malloc see man malloc. Then your code should look something like this.

void *ptr = malloc(sizeof(board));    //you need to error check this. See man malloc

If you do that you only need to pass the Pointer to the Data in your function. This is more efficient because the data stays on the heap memory.

bitflip-at
  • 149
  • 2
  • 14
  • Arays decay to pointers when passed to functions, so the board will not be copied when passed. Passing a multidimensional arrays has caveats, see http://stackoverflow.com/questions/2828648/how-to-pass-a-multidimensional-array-to-a-function-in-c-and-c – Klas Lindbäck Jan 23 '17 at 10:00
  • Ok i did not know that. Thanks! But also in his case? I thought everything you do on the function stack is lost as soon as the function terminates, so C needs to copy the data anyway. – bitflip-at Jan 23 '17 at 10:09
2

Your board[][] is a local variable and thus only work inside the init() environment.

I'm taking the CS50x course as well, and the fifteen.c file they handle us actually already have a board[][] variable declared in line 27: int board[DIM_MAX][DIM_MAX];, which is already global.

So you don't need to create another board, just use the one they handle to us.