0

My code for fifteen.c works and solves the test inputs of the 3x3.txt file and the 4x4.txt file. However the check50 fails for the following.

:) fifteen.c exists :) fifteen.c compiles :( init initializes 3x3 board correctly \ expected "5" character 1 of line 2, not "0" :( init initializes 4x4 board correctly \ expected file to be of length 38, not 36

What I have found is that the log.txt file is not matching the my actual board array and that is why check50 is saying my 3x3 doesn't initialize correctly. Here is my code.

Can someone please help me understand why log.txt is not matching my board array?

/**
 * fifteen.c
 *
 * Implements Game of Fifteen (generalized to d x d).
 *
 * Usage: fifteen d
 *
 * whereby the board's dimensions are to be d x d,
 * where d must be in [DIM_MIN,DIM_MAX]
 *
 * Note that usleep is obsolete, but it offers more granularity than
 * sleep and is simpler to use than nanosleep; `man usleep` for more.
 */

#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];

// Zero (space) location
int zero[2];

// dimensions
int d;

// Functions for Game Play
void clear(void);
void greet(void);
void init(int d, int board[d][d], int zero[2]);
void draw(int d, int board[d][d]);
bool move(int tile, int d, int board[d][d], int zero[2]);
bool won(int d, int board[d][d]);

// Functions to find zero
void zerofind(int d, int board[d][d], int zero[2]);


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(d, board, zero);

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

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

        // 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, "%i", board[i][j]);
                if (j < d - 1)
                {
                    fprintf(file, "|");
                }
            }
            fprintf(file, "\n");
        }
        fflush(file);

        // check for win
        if (won(d, board))
        {
            printf("\e[7;4;32;47mCongratulations! You Solved the Puzzle! \e[0m\n");
            break;
        }

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

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

        // move if possible, else report illegality
        if (!move(tile, d, board, zero) || tile == 0)
        {
            printf("\nIllegal move.\n");
            usleep(250000); //0.25sec pause
        }

        // sleep thread for animation's sake
        usleep(250000); //0.25sec pause
    }

    // 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); //2sec pause
}


/**
 * Initializes the game's board with tiles numbered 1 through d*d - 1
 */
void init(int d, int board[d][d], int zero[2])
{
    // Identifying largest number
    int x = d * d - 1;

    // Identifying Zero (space) location
    zero[0] = d - 1;
    zero[1] = d - 1;

    // Assigning values to board
    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++)
        {
            board[i][j] = x;
            x--;
        }
    }

    // If d is even, switch 1 and 2 to make game solvable
    if (d % 2 == 0)
    {
        board[d - 1][d - 2] = 2;
        board[d - 1][d - 3] = 1;
    }

}

/**
 * Prints the board in its current state.
 */
void draw(int d, int board[d][d])
{
    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++)
        {
            if (board[i][j] == 0)
            {
                printf("|__");
            } else
            {
                printf("|\e[4m%2i\e[0m", board[i][j]);
            }
        }
        printf("|\n");
    }
}

/**
 * If tile borders empty space, moves tile and returns true, else
 * returns false. 
 */
bool move(int tile, int d, int board[d][d], int zero[2])
{
    // Finds zero
    zerofind(d, board, zero);

    // Checks tiles around zero
   // Checking space above
    if (board[zero[0] - 1][zero[1]] == tile)
    {
        board[zero[0]][zero[1]] = board[zero[0] - 1][zero[1]];
        board[zero[0] - 1][zero[1]] = 0;
        return true;
    }

    // Checking space below
    if (board[zero[0] + 1][zero[1]] == tile)
    {
        board[zero[0]][zero[1]] = board[zero[0] + 1][zero[1]];
        board[zero[0] + 1][zero[1]] = 0;
        return true;
    }

    // Checking space right
    if (board[zero[0]][zero[1] + 1] == tile)
    {
        board[zero[0]][zero[1]] = board[zero[0]][zero[1] + 1];
        board[zero[0]][zero[1] + 1] = 0;
        return true;
    }

    // Checking space left
    if (board[zero[0]][zero[1] - 1] == tile)
    {
        board[zero[0]][zero[1]] = board[zero[0]][zero[1] - 1];
        board[zero[0]][zero[1] - 1] = 0;
        return true;
    }

    // Not Found
    return false;

}

/**
 * Returns true if game is won (i.e., board is in winning configuration), 
 * else false.
 */
bool won(int d, int board[d][d])
{
    if (board[d - 1][d - 1] != 0)
    {
        return false;
    }

    int e = 1;

    // Evaluates each element to make sure they are in ascending order.
    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++)
        {
            if (board[i][j] == e)
            {
                e++;
            }
        }
    }

    if (e == d * d)
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
 * identifying location of the Zero or Space
 */
void zerofind(int d, int board[d][d], int zero[2])
{
    for (int i = 0; i < d; i++)
    {
        for (int j = 0; j < d; j++)
        {
            if (board[i][j] == 0)
            {
                zero[0] = i;
                zero[1] = j;
            }
        }
    }
}
1
  • A pattern that i have noticed in log.txt is that it seems to be printing the dxd section of the original 9x9 board array. Even though I can print and show that the board array i created in my init function has the correct (i,j) 2d array structure, when it is output to log.txt, i seems to reassign my init board array to a 9x9 array. Hopefully that makes sense.
    – MSevey
    Commented Feb 21, 2017 at 18:06

1 Answer 1

0

I figured it out. I changed int board[dim_max][din_max] to int board[d][d] and moved it into main. This solved my previous error.

You must log in to answer this question.

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