1

When I play fifteen myself it works with any board size; the 3x3 winning seq also works, but the 4x4 one does not finish and stops while repetitively trying to move tile 2147483647.. GDB did not help for me this time.

This is my move function, which I reckon might be the issue; any help highly appreciated.

bool move(int tile)
{
    int l, m, n, o;

    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++) // move along the board from left to right (j) and top down (i)
        {
            if (board[i][j] == tile) // at position of tile or "_" l, m, n, o are defined
            {
                l = i;
                m = j;
            }
            else if (board[i][j] == d * d)
            {
                n = i;
                o = j;
            }
            else
            {
                continue;
            }

        }
    }

    if ((l == n && m == o + 1) || (l == n && m == o - 1)) // check whether BLANK and tile are next to each other horizontally
    {
        swap2d(board, l, m, n, o); 
        return true;
    }
    else if ((m == o && l == n + 1) || (m == o && l == n - 1)) // check whether BLANK and tile are adjacent vertically
    {
        swap2d(board, l, m, n, o); 
        return true;
    }

    return false;
}

void swap2d(int values[][9], int l, int m, int n, int o) 
{
    int store = values[l][m];
    values[l][m] = values[n][o];
    values[n][o] = store;
}
1

I assume you used d * d to represent the blank tile. Probably you should define a constant to represent the blank tile and you should also store the row and the column of the blank tile in global variables to avoid searching for it every time you make a move then you should break the loops immediately once you find the tile and no need for the else statement in this situation since if non of the conditions above was met, you'd go to the next iteration anyway.

In addition to saving the time of searching for the blank tile, this makes the swapping process as simple as this

board[blankRow][blankCol] = board[tileRow][tileCol];
board[tileRow][tileCol] = BLANK;

The board should be declared as a global variable so that you can access it directly without passing it to every function you wanna access it from.

The main problem is with ... wait for it ... the won() function! Your won() function doesn't return true when the game is won and that's why your program tries to move tile 2147483647 which is probably a garbage value (it's also the maximum value a signed int can take) since no other moves in 4x4.txt.

| improve this answer | |
  • Thanks Kareem, some very helpful points in your answer. However, my won function does return true all the time I play myself and if I run 3x3.txt.. I've increased the usleep parameters and inserted a printf statement in the move function that shows me the sequence of moved tiles, so I can track the winning seq's moves. According to this, it tries to move this sequence of tiles: "4, 5, 6, 1", then it gets stuck the first time because moving the 1 is an illegal move. Is the winning seq hard coded? If so, could it be that the winning seq is wrong? – pat_krat Aug 5 '14 at 8:04
  • Hi, @Patrick! I wan't you to know that I didn't make a single edit on your move() and swap2d() functions. I just made a slight edit on my won() function to fit them and the game worked perfectly with 4x4.txt. And yes, 4x4.txt is hard-coded and no, it's not wrong. You may send me the code for your move function at kareem.mes@gmail.com to see if I can help you identify the bug! – Kareem Aug 5 '14 at 13:08
  • Okay, I did find the bug: I skimmed the part of the problem set that tells you to swap tiles 1 and 2 for equal numbers of single board dimensions.. So, it was my draw function! This is why there where so many illegal moves in the 4x4.txt winning seq! Thank you though, your suggestions improved my style significantly! – pat_krat Aug 6 '14 at 12:37

You must log in to answer this question.

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