0

I'm currently getting an error for "make sure game is winnable" but my program works with ./fifteen 3 < ~cs50/unit3/3x3.txt

Here is my error log:

:) fifteen.c exists.
:) fifteen.c compiles.
:) 3x3 board: init initializes board correctly
:) 3x3 board: catches moving 8 an illegal move
:) 3x3 board: catches moving 1 as a legal move
:) 3x3 board: move blank up twice
:) 3x3 board: move blank left twice
:) 3x3 board: move blank left then right
:) 3x3 board: move blank up then down
:) 3x3 board: move up-up-left-down-down-left-up-up-right-down-down-right
:) 3x3 board: make sure none of 2, 4, 5, 6, 7, 8 move tile
:) 3x3 board: move blank left (tile 1) then up (tile 4), then try to move tiles 1, 2, 6, 8
:( 3x3 board: make sure game is winnable
    expected "Tile to move:", not "\x1b[2J\x1b[0;0..."
:( 4x4 board: make sure game is winnable
    timed out while waiting for program to exit

This is my code:

// 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 num = (d * d) - 1;
    for (int i = 0, w = d; i < w; i++)
    {
        for (int ii = 0, ww = d; ii < ww; ii++)
        {
            board[i][ii] = num;
            num--;
            //printf("%i ", board[i][ii]); // For Testing
        }
        //printf("\n"); // For Testing
    }
    if (d == 4 || d == 6 || d == 8)
    {
        int a = board[d - 1][d - 2];
        int b = board[d - 1][d - 3];
        board[d - 1][d - 2] = b;
        board[d - 1][d - 3] = a;
    }
}

// Prints the board in its current state
void draw(void)
{
    for (int i = 0, z = d; i < z; i++)
    {
        for (int f = 0, zz = d; f < zz; f++)
        {
            if (board[i][f] == 0)
            {
                printf("%2c", '_');
            }
            else if (board[i][f] > 9 )
            {
                printf("%i ", board[i][f]);
            }
            else if (board[i][f] == 9 || board[i][f] < 9)
            {
                printf("%2i", board[i][f]);
            }

        }
        printf("\n");
    }
    // TODO
}

// If tile borders empty space, moves tile and returns true, else returns false
bool move(int tile)
{
    for (int i = 0, z = d; i < z; i++)
    {
        for (int ii = 0, zz = d; ii < zz; ii++)
        {
            if (tile == board[i][ii])
            {
                // Testing + YouTube Link
                //printf("%i\n", board[i][ii]);
                //printf("%i\n", board[i - 1][ii]);
                //printf("%i\n", board[i][ii - 1]);
                //printf("%i\n", board[i + 1][ii]);
                //printf("%i\n", board[i][ii + 1]);
                //printf("%i\n", d);
                // https://youtu.be/Rx_FJb3vr9U?t=369
                if (i + 1 != d)
                {
                    if (board[i + 1][ii] == 0)
                    {
                        int f = board[i + 1][ii];
                        int z = board[i][ii];
                        board[i + 1][ii] = z;
                        board[i][ii] = f;
                        return true;
                    }
                }
                //printf("%i\n", i - 1);
                if ((i - 1) > -1)
                {
                    if (board[i - 1][ii] == 0)
                    {
                        int f = board[i - 1][ii];
                        int z = board[i][ii];
                        board[i - 1][ii] = z;
                        board[i][ii] = f;
                        return true;
                    }
                }
                if (ii + 1 != d)
                {
                    if (board[i][ii + 1] == 0)
                    {
                        int f = board[i][ii + 1];
                        int z = board[i][ii];
                        board[i][ii + 1] = z;
                        board[i][ii] = f;
                        return true;
                    }
                }
                if ((ii - 1) > -1)
                {
                    if (board[i][ii - 1] == 0)
                    {
                        int f = board[i][ii - 1];
                        int z = board[i][ii];
                        board[i][ii - 1] = z;
                        board[i][ii] = f;
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

// Returns true if game is won (i.e., board is in winning configuration), else false
bool won(void)
{
    int checker[d][d];
    int max = 1;
    int correct = 0;
    for (int i = 0, z = d; i < z; i++)
    {
        for (int ii = 0, zz = d; ii < zz; ii++)
        {
            checker[i][ii] = max;
            if (checker[i][ii] == ((d * d) - 1))
            {
                checker[i][ii] = 0;
            }
            max++;
        }
    }

    for (int i = 0, z = d; i < z; i++)
    {
        for (int ii = 0, zz = d; ii < zz; ii++)
        {
            if (checker[i][ii] == board[i][ii])
            {
                correct++;
            }
        }
    }

    if (correct == (d*d) - 1)
    {
        return true;
    }

    // TODO
    return false;
}

Thanks in Advance

1

The won() function won't return a true win. Look at the following code:

for (int i = 0, z = d; i < z; i++)
{
    for (int ii = 0, zz = d; ii < zz; ii++)
    {
        if (checker[i][ii] == board[i][ii])
        {
            correct++;
        }
    }
}

if (correct == (d*d) - 1)
{
    return true;
}

Now, say that d=3. The loop will increment correct to 9. The test checks whether correct is 8. Thus, it'll never find a true win. Remember, d*d - 1 is the number of non-zero or non-blank tiles, not the total number of spaces in the matrix.

Hmmm.... how did you get a win notification when you tested your code? I'm sure that you didn't just run check50 to do the testing, right?

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

| improve this answer | |

You must log in to answer this question.

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