Well, this one has got me good - I just don't see a way round it! I think I've got the init and draw functions working - they work for the first draw anyway, but I've been working on 'move' for days and just can't get my head round it....it seems to need pointers but I don't understand them - we haven't covered them yet (to my knowledge!?)but I've tried to read up on them and have tried to use them as best I can because if I don't then I get the 'incompatible pointer' type errors... I added the '*' s to all of the variables because when I printed out the blank-col variable to check it, it only worked if I added the star. My main problem (I think - though I may have missed other errors) is that I can't seem to identify the positions of the blank and the tile properly. So...the board seems to draw, and you can enter the tile you want to move, but when you press enter it just goes back to a blank space instead of the tile number and nothing happens...can anyone help please? I did originally use a temp variable to change over the blank and tile but then I read because the blank was '0' it simplified the exchange so I thought maybe I could do it as I now have. I would so appreciate some pointers (no pun intended!) as I'm totally at the end of my tether with this one....thank you!
/**
* fifteen.c
*
* Computer Science 50
* Problem Set 3
*
* 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];
int *blank_row;
int *blank_col;
int *tile_row;
int *tile_col;
// dimensions
int d;
// 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, "%i", 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)
//initiate the board to hold between 3 and 9 spaces on each side of the board
{
for (int i = (d-1); i > -1; i--)
{
for (int j = (d-1); j > -1; j--)
{
//populate the board with numbers from d-1 to 0 (zero being the blank space)
board[i][j] = (i * d) + j;
//calculate if d is an odd number, and if so swap 2 & 1
if ( d % 2 == 0 )
{
board[0][1] = 2;
board [0][2] = 1;
}
}
}
}
/**
* Prints the board in its current state.
*/
void draw(void)
{
//repeat initialisation loop and print results
for (int i = (d-1); i > -1; i--)
{
for (int j = (d-1); j > -1; j--)
{
if (board[i][j] == 0)
{
blank_row = board[i];
blank_col = board[j];
printf(" _");
}
else
{
printf( "%4d", board[i][j]);
}
}
printf("\n\n");
}
}
/**
* If tile borders empty space, moves tile and returns true, else
* returns false.
*/
bool move(int tile)
{ //declare temp int
int temp;
// Search for position of tile
for (int row = 0; row < d; row++)
{
for (int col = 0; col < d; col++)
{
if (board[row][col] == tile)
{
tile_row = board[row];
tile_col = board[col];
//check if it can move up and if so, move
if (*tile_row > 0)
{
if (board[*tile_row-1][*tile_col] == 0)
{
board[*blank_row][*blank_col] = board[*tile_row][*tile_col];
board[*tile_row][*tile_col] = 0;
}
}
//check if it can move left and if so, move
if (*tile_col > 0)
{
if (board [*tile_row][*tile_col-1] == 0)
{
board[*blank_row][*blank_col] = board[*tile_row][*tile_col];
board[*tile_row][*tile_col] = 0;
}
}
//check if it can move right and if so, move
if (*tile_col < (d-2))
{
if (board [*tile_row][*tile_col+1] == 0)
{
board[*blank_row][*blank_col] = board[*tile_row][*tile_col];
board[*tile_row][*tile_col] = 0;
}
}
//check if it can move down and if so, move
if (*tile_row < d-2)
{
if (board[*tile_row+1][*tile_col] == 0)
{
board[*blank_row][*blank_col] = board[*tile_row][*tile_col];
board[*tile_row][*tile_col] = 0;
}
}
}
return true;
}
}
return false;
}
/**
* Returns true if game is won (i.e., board is in winning configuration),
* else false.
*/
bool won(void)
{
// TODO
return false;
}