1

I am stuck on the move function in Pset3 Fifteen. My code correctly identifies legal and illegal moves, but does not update the board. I tried calling draw() into my function for legal moves (but I think that's not the right thing to do). I'm just looking for hints or suggestions as to where I should be focusing attention next, as I've been scratching my head for some time. Much appreciated!

Here's my Code:

 #define _XOPEN_SOURCE 500

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// constants
#define DIM_MIN 3
#define DIM_MAX 9

// board
int board[DIM_MAX][DIM_MAX];

// dimensions
int d;

// rows and columns
int row;
int col;

// prototypes
void clear(void);
void greet(void);
void init(void);
void draw(void);
bool move(int tile);
bool won(void);

int main(int argc, string argv[])
{
    // ensure proper usage
    if (argc != 2)
    {
        printf("Usage: fifteen d\n");
        return 1;
    }

    // ensure valid dimensions
    d = atoi(argv[1]);
    if (d < DIM_MIN || d > DIM_MAX)
    {
        printf("Board must be between %i x %i and %i x %i, inclusive.\n",
            DIM_MIN, DIM_MIN, DIM_MAX, DIM_MAX);
        return 2;
    }

    // open log
    FILE* file = fopen("log.txt", "w");
    if (file == NULL)
    {
        return 3;
    }

    // greet user with instructions
    greet();

    // initialize the board
    init();

    // accept moves until game is won
    while (true)
    {
        // clear the screen
        clear();

        // draw the current state of the board
        draw();

        // log the current state of the board (for testing)
        for (int i = 0; i < d; i++)
        {
            for (int j = 0; j < d; j++)
            {
                fprintf(file, "%2i", board[i][j]);
                if (j < d - 1)
                {
                    fprintf(file, "|");
                }
            }
            fprintf(file, "\n");
        }
        fflush(file);

        // check for win
        if (won())
        {
            printf("ftw!\n");
            break;
        }

        // prompt for move
        printf("Tile to move: ");
        int tile = GetInt();

        // quit if user inputs 0 (for testing)
        if (tile == 0)
        {
            break;
        }

        // log move (for testing)
        fprintf(file, "%i\n", tile);
        fflush(file);

        // move if possible, else report illegality
        if (!move(tile))
        {
            printf("\nIllegal move.\n");
            usleep(500000);
        }

        // sleep thread for animation's sake
        usleep(500000);
    }

    // close log
    fclose(file);

    // success
    return 0;
}

/**
 * Clears screen using ANSI escape sequences.
 */
void clear(void)
{
    printf("\033[2J");
    printf("\033[%d;%dH", 0, 0);
}

/**
 * Greets player.
 */
void greet(void)
{
    clear();
    printf("WELCOME TO GAME OF FIFTEEN\n");
    usleep(2000000);
}

/**
 * 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)
{
    int tiles = d*d - 1;
    int k = 0;

    //fill board
    for (row = 0; row < d; row++)
    {
        for (col = 0; col < d; col++)
        {
            board[row][col] = tiles - k;
            k++;
        }
    }

    // for even dimensions
    if ((d % 2) == 0)
    {
        int m = d - 2;
        int n = d - 3; 

    // switch last two non-blank integers in bottom row
        int x = board[d-1][m];
        board[d-1][m] = board[d-1][n];
        board[d-1][n] = x;    
    }
}

/**
 * Prints the board in its current state.
 */
void draw(void)
{
   for (row = 0; row < d; row++)
   {
       for (col = 0; col < d; col++)
       {

        // change last int to "_"   
           if (board[row][col] == 0)
           {
               printf("   _");
           }
           else
           {
               printf("  %2d", board[row][col]);
           }
       }
       printf("\n");
   }
}

/**
 * If tile borders empty space, moves tile and returns true, else
 * returns false. 
 */
int search_row (int x);
int search_col (int y);

bool move(int tile)
{
    int row = search_row (tile);
    int col = search_col (tile);

    int up = board[row - 1][col];
    int down = board[row + 1][col];
    int left = board [row][col + 1];
    int right = board [row][col - 1];


    if ((0 == up) && (row - 1) >= 0)
    {
        int swap = up;
        up = tile;
        tile = swap;
        draw ();
        return true;
    }
    else if ((0 == down) && (row + 1) < d)
    {
        int swap = down;
        down = tile;
        tile = swap;
        draw();
        return true;
    }
    else if ((0 == left) && (col + 1) < d)
    {
        int swap = left;
        left = tile;
        tile = swap;
        draw();
        return true;
    }
    else if ((0 == right) && (col - 1) >= 0)
    {
        int swap = right;
        right = tile;
        tile = swap;
        draw();
        return true;
    }
    else
    {
        return false;
    }
}    


int search_row (int x)
{
    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++)
        {
            int numbers = board[i][j];

            if (x == numbers)
            {
                return i; 
            }
        }
    }
    return 0;
}

int search_col (int y)
{
    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++)
        {
            int numbers = board[i][j];

            if (y == numbers)
            {
                return j;
            }
        }
    }
    return 0;
}
0

OK, here's a big push in the right direction. ;-)

Your code creates 4 local vars and copies the values of the corresponding board array positions to those values. It then finds the one that is 0, the blank tile, and then does a wonderful job of swapping the values of that local var (up, down, left or right) with the value of tile. Unfortunately, this does nothing to the vales actually stored in the board array itself. Remember, you are copying the values stored in the board array, and storing copies in those local vars. Changing the value of those vars does not change the values in the board array itself.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

| improve this answer | |
  • Thanks so much. I still had a hard time conceptually understanding why my code did not work, but now having watched Week 4 lectures on pointers, it makes much more sense. Someone on here said once that if you're having problems on a Pset, peek at the following week's lectures for hints....will have to keep that in mind. – shepmasta Sep 12 '16 at 4:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .