0

My game of fifteen is somehow still not working. here is the code for move()

bool move(int tile)
{

// TODO
// find location of specified tile using linear search
//find tile location in nice iterative manner. 
//nested for loop

int swappy;
for (int i =0; i < d; i++)
{
    for (int j = 0; j < d; j++)
    {
        if (board[i][j] == tile) {
            //edit the board array only if move is legal
           // if tile is above blank{
           if (i2 != 0) {
                if (tile == board[i2 - 1][j2]) {
                //swap them
                swappy = tile;
                tile = board[i2 - 1][j2];
                board[i2 -1][j2] = tile;

                //keep track of where blank is using two
                //variables
                i2 = i;
                j2 = j;
                return true;
            }   
           }
             if (i2 != d -1){
                 if (tile == board[i2 + 1][j2]) {
                //swap them
                swappy = tile;
                tile = board[i2 + 1][j2];
                board[i2 + 1][j2] = tile;

                //keep track of where blank is using two
                //variables
                i2 = i;
                j2 = j;
                return true;
            }   
            }
            //else if tile is on the left {
             if (j2 != 0){
                 if (tile == board[i2][j2 - 1]) {
                //swap them
                swappy = tile;
                tile = board[i2][j2 - 1];
                board[i2 ][j2 -1] = tile;
                //keep track of where blank is using two
                //variables
                i2 = i;
                j2 = j; 
                return true;
            }
            }

             if (j2 != d -1){
              if (tile == board[i2][j2 + 1]) {
                //swap them
                swappy = tile;
                tile = board[i2][j2+1];
                board[i2][j2+1] = tile;
                //keep track of where blank is using two variables
                i2 = i;
                j2 = j;
                return true;
            }   
            }
            // BUG: THE TIL LOCATIONS DONT MOVE
            else {
            //    illegal move!
                return false;
            }
        }
        }
}
return false;
}

and here is the code for my whole fifteen.c

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

// dimensions
int d;
int i2;
int j2;

// 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;
}
i2 = d-1;
j2 = d-1;
// 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 = get_int();

    // 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(50000);
    }

    // sleep thread for animation's sake
    usleep(50000);
}

// 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)
{
// TODO
int counter = d * d - 1;
for (int i =0; i < d; i++)
{
    for (int j = 0; j < d; j++)
    {
        // set title's value
        board[i][j] = counter;
        counter--;

    }
        board[d][d] = 0;
        if (d % 2 == 0){
          board[d][d-1] = 2;
          board[d][d-2] = 1;
        }
}
}

/**
 * Prints the board in its current state.
 */
void draw(void)
{
    // TODO
for (int i =0; i < d; i++)
{
    for (int j = 0; j < d; j++)
    {
        // print title's value
        //printf("%2i", board[i][j]);
        if (j == d-1){
            if (i == d-1){
                printf("  _");
            }
            else {
                printf(" %2i", board[i][j]);
            }
        }
        else {
            printf(" %2i", board[i][j]);
        }
    }

    // print new line    
    printf("\n");
    printf("\n");

}
}

/**
 * If tile borders empty space, moves tile and returns true, else
 * returns false. 
 */


bool move(int tile)
{

// TODO
// find location of specified tile using linear search
//find tile location in nice iterative manner. 
//nested for loop

int swappy;
for (int i =0; i < d; i++)
{
    for (int j = 0; j < d; j++)
    {
        if (board[i][j] == tile) {
            //edit the board array only if move is legal
           // if tile is above blank{
           if (i2 != 0) {
                if (tile == board[i2 - 1][j2]) {
                //swap them
                swappy = tile;
                tile = board[i2 - 1][j2];
                board[i2 -1][j2] = tile;

                //keep track of where blank is using two
                //variables
                i2 = i;
                j2 = j;
                return true;
            }   
           }
             if (i2 != d -1){
                 if (tile == board[i2 + 1][j2]) {
                //swap them
                swappy = tile;
                tile = board[i2 + 1][j2];
                board[i2 + 1][j2] = tile;

                //keep track of where blank is using two
                //variables
                i2 = i;
                j2 = j;
                return true;
            }   
            }
            //else if tile is on the left {
             if (j2 != 0){
                 if (tile == board[i2][j2 - 1]) {
                //swap them
                swappy = tile;
                tile = board[i2][j2 - 1];
                board[i2 ][j2 -1] = tile;
                //keep track of where blank is using two
                //variables
                i2 = i;
                j2 = j; 
                return true;
            }
            }

             if (j2 != d -1){
              if (tile == board[i2][j2 + 1]) {
                //swap them
                swappy = tile;
                tile = board[i2][j2+1];
                board[i2][j2+1] = tile;
                //keep track of where blank is using two variables
                i2 = i;
                j2 = j;
                return true;
            }   
            }
            // BUG: THE TIL LOCATIONS DONT MOVE
            else {
            //    illegal move!
                return false;
            }
        }
        }
}
return false;
}


/**
 * Returns true if game is won (i.e., board is in winning configuration), 
 * else false.
 */
bool won(void)
{
for (int i =0; i < d; i++)
{
    for (int j = 0; j < d; j++)
    {
        int smaller = board[i][j];
        int counter =0;
        if (board[i][j]== board[0][0]){
        smaller = board[i][j];
            counter++;
    }
    else if (counter == d*d){
            return true;
        }
        else if (smaller < board[i][j]){
            if (smaller < board[i][j])
                counter++;
                smaller = board[i][j];
        }
        else {
                return false;
            }

    }

}


// Game is won if tiles are in increasing order left to right and top to bottom
// if game won..
// return true;
// else...
// return false;
return true;
}

1 Answer 1

1

Well, now you correctly check if the move tile and the blank tile are next to each other. It's not the shortest and not the most stylish way to do it, but OK. Then, in theory, you need to swap these two tiles, that is to assign board[i][j] = 0 and board[i2][j2] = tile, as simple as that, but instead:

swappy = tile;
tile = board[i2 - 1][j2];
board[i2 -1][j2] = tile;

No comments as I have no clue what you try to do.

In general, neither of your functions init(), draw(), move(), won() works properly, so it is not "Almost DONE". I would leave it to you to sort it out. And please, watch this nice video about style and read this nice post.

6
  • Hmm Okay, I will see that video and read that link. I will do the ideas proposed, thanks! But my question now is, what shortcomings do my init, draw, and won have? I feel that they are doing their job correctly, right? Could you please explain the errors I am coding into my init(), draw(), and won()? thank you! Jul 30, 2017 at 9:52
  • Okay! My GoF works now! Kind of. Instead of any numeral at the bottom right corner, there is the underscore, and instead of where the underscore should be, is the 0! Jul 30, 2017 at 10:06
  • Well, try to find errors by yourself. Try init() for d=3,4 is it OK? (check log.txt). Now when you've corrected move() see what draw() does. Is it what you expect? And finally win the game and see if you get won message.
    – obesman
    Jul 30, 2017 at 10:13
  • Ok. Thanks again! I see my Won function isn't working properly... hmm. I have a question though! Is Draw called only once in the game or is it called many times, like move()? Jul 30, 2017 at 10:19
  • of course it is called after each move. Otherwise, how would you see you move?
    – obesman
    Jul 30, 2017 at 10:23

You must log in to answer this question.

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