I've gotten pretty much everything working in fifteen. The tiles move correctly, the redraw works with a board of any size, et cetera. So I pasted in the ./fifteen 3 < ~cs50/pset3/3x3.txt
the pset tells us to. The tiles all move and get sorted perfectly... except rather than printing "ftw," it tells me "Illegal move" and the game breaks (user can't enter any more tile numbers, and no exit back to command line).
The puzzle is solved, but something in the code isn't passing that correctly. The only thing that can print "Illegal move" is this pre-written bit in main:
// move if possible, else report illegality
if (!move(tile))
{
printf("\nIllegal move.\n");
usleep(500000);
}
That tells me that the problem must be in my implementation of the move function, but I can't for the life of me figure out what it is. My move and won functions are pasted below. (EMPTY is a constant set to 0, and blankX/blankY are global variables set to track the blank tile in init.) Like I said, everything is working except for literally the last move. Could anyone point me to what I might be overlooking? Thanks in advance!
/**
* If tile borders empty space, moves tile and returns true, else
* returns false.
*/
bool move(int tile)
{
//rows
for (int i = 0; i < d; i++)
{
//columns
for (int j = 0; j < d; j++)
{
//find tile to move
if (board[i][j] == tile)
{
//make sure move is legal
if (board[i+1][j] == EMPTY || board[i-1][j] == EMPTY || board[i][j+1] == EMPTY || board[i][j-1] == EMPTY)
{
//swap tiles
int temp = board[i][j];
board[i][j] = EMPTY;
board[blankX][blankY] = temp;
blankX = i;
blankY =j;
return true;
}
}
}
}
//I put in this part to try and fix the broken-winning-move problem, which ended up not working.
if(won())
return true;
return false;
}
/**
* Returns true if game is won (i.e., board is in winning configuration),
* else false.
*/
bool won(void)
{
//if this remains unchanged, "sorted" will be true
bool sorted = true;
//check all values in array except for the last one, which should be blank tile
for (int i = 0; i < (d*d) - 2; i++)
{
//if any tiles are out of order, set sorted to false
if (board[i] < board[i+1])
sorted = false;
}
//if all the tiles are sorted, the game is won
if (sorted == true)
return true;
else
return false;
}
EDIT: After poking around these forums, I tried writing a different implementation of the won function, this time by creating a "winning board" and comparing the user's board against that (code below). Now when I run ./fifteen 3 < ~cs50/pset3/3x3.txt
in my terminal, it immediately says "ftw" but the board is in its initial, unsolved position. This doesn't make any sense to me either. Advice on how to fix either one of these implementations would be greatly appreciated.
bool won(void)
{
int winningboard[DIM_MAX][DIM_MAX];
int populate = 1;
//rows
for (int i = 0; i < d; i++)
{
//columns
for (int j = 0; j < d; j++)
{
//populate winning board with ascending values
winningboard[i][j] = populate;
populate ++;
}
}
//set final spot of winning board to blank tile
winningboard[d - 1][d - 1] = EMPTY;
//compare user board with winning board
//rows
for (int i = 0; i < d; i++)
{
//columns
for (int j = 0; j < d; j++)
{
if (board[i][j] == winningboard[i][j])
return true;
}
}
return false;
}