0

Note: I've found the issue that's causing it to stop working half way and corrected it (error in the move up code) so I now know it's that I've got the order of the array in reverse, so I'm taking out the bits of this post that are no longer relevant (hope that's the right thing to do!)....Here's the remaining part of my original post: I already had some help on this and really thought I'd cracked it, (though I've no idea if the 'won' function works yet). It does let me play it but I've tried running check50 and it says it's not even passing 'init initialises 3x3 board correctly'. I can now see my problem is that I'm not getting the positions of the elements to match the locations of the elements (e.g. board[0][0] reads as [2][2] when I'm tracking the tile and the blank, so I've written all the 'move' code to fit with the reverse positioning. Could this be the init problem? I've tried using ++ and -- in the loops and whichever way I do it it's reversed. I hope this makes sense, I would so appreciate if anyone can help - I'm seriously questioning my abilities to do any of this right now!!! 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
#define TEST_DIM 9

// board
int board[DIM_MAX][DIM_MAX];
int array2[TEST_DIM][TEST_DIM];
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 dd - 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 >= 0; i--)
        {
            for (int j = (d-1); j >= 0; 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 >= 0; i--)
        {
            for (int j = (d-1); j >= 0; j--)
            {
                if (board[i][j] == 0)
                {
                    blank_row = i;
                    blank_col = j;
                    printf("   _");
                    printf("%i and %i", i,j);

                }
            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 i = (d-1); i >= 0; i--)
        {
            for (int j = (d-1); j >= 0; j--)
            {
              if (board[i][j] == tile)
              {
                tile = board[i][j];
                tile_row = i;
                tile_col = j;
                printf("%i and %i", i,j);
              }
            }
        }

                    //check if it can move left 
                if (tile_col < d-1 && tile_col+1 == blank_col && tile_row == blank_row)
                {
                    temp = board[tile_row][tile_col];
                    board[tile_row][tile_col] = board[blank_row][blank_col];
                    board[blank_row][blank_col] = temp;
                }
                    //check if it can move up 
                if  (tile_row < d-1 && tile_row+1 == blank_col && tile_col == blank_col)
                {
                    temp = board[tile_row][tile_col];
                    board[tile_row][tile_col] = board[blank_row][blank_col];
                    board[blank_row][blank_col] = temp;
                }
                    //check if it can move right and if so, move
                if   (tile_col > 0 && tile_col-1 == blank_col && tile_row == blank_row)
                {
                    temp = board[tile_row][tile_col];
                    board[tile_row][tile_col] = board[blank_row][blank_col];
                    board[blank_row][blank_col] = temp;
                }
                    //check if it can move down and if so, move
                if   (tile_row > 0 && tile_row-1 == blank_row && tile_col == blank_col)
                   {
                    temp = board[tile_row][tile_col];
                    board[tile_row][tile_col] = board[blank_row][blank_col];
                    board[blank_row][blank_col] = temp;
                     }


            return true;

            }
/*
  Returns true if game is won (i.e., board is in winning configuration), 
  else false.
 */
bool won(void)
{ 
   for (int i = 0; i < d-1; i++)
        {
            for (int j = 0; j < d-1; j++)
            {
                //populate the board with numbers from d-1 to 0 
                array2[i][j] = (i * d) + j;

            }
        }

    for(int row = 0; row < d; row++)
        {
            for(int column = 0; column < d; column++)
            {
            if(board[row][column] > array2[row+1][column+1])
                {
                return false;
                }
            }

        }
     return true;    
}
  • I would think of maybe checking pairs in your won function for the final result to be successful. Mind you I am not an expert just thinking it would be easier to do. I hope it helps slightly. – Kamil Kug Jan 8 '17 at 22:02
  • Thanks, but I just realised a better way is to compare j within the board array and confirm that e.g. j is bigger than j-1...that seems more reliable I think...i.e. I don't need the 2nd array to compare at all - is that what you meant?! – CallyB Jan 9 '17 at 6:02
0

Take a look at the way you're initializing board. It looks like you got the ordering confused. In a 3x3 array for example, the top leftmost entry is board[0][0], which takes the value of 8. Instead, you're assigning 8 to board[0][2].

| improve this answer | |
  • Thank you for replying - I definitely can see I've done this, but I'm really stuck on how to remedy it - if I reverse the loop so that it's i=0,i<d then I have to iterate with i++ and it just reverses the position of the numbers so 0 is the top left number, and I just can't see how to make it work!! I'm sure it's obvious and I may kick myself if I can get it but right now I just can't see it...??? – CallyB Jan 9 '17 at 10:33
  • It's usually the simplest things that are not immediately apparent : ) Just declare another variable, call it call it counter, say, and then just increment or decrement it as you go along the array entries. – ronga Jan 9 '17 at 13:22
  • Yay! I got it! I found a reference to populating an array with a counter and that got me going - now it's working and I just have to sort the 'won' function, but that's another story! Thanks all... – CallyB Jan 9 '17 at 14:30
  • Ha! Thank you ronga - my internet went off and I couldn't post my comment until just now - and saw your reply just as my comment went up! So I did try the counter & it worked, but I'm really glad it's what you're suggesting too - I guess int is the right thing to do! Like you say - it's so simple I guess I was overthinking it... – CallyB Jan 9 '17 at 14:33

You must log in to answer this question.

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