CS50 Pset3 function "Won"

1.9k views Asked by At

I am at the last part of the pset, and whenever I check my answer using ./fifteen 3 < ~cs50/pset3/3x3.txt , the program doesn't seem to be comparing my solved puzzle with my win[][] array . End result is that I have made an illegal move.

Could this be a problem that board[i][j]==win[i][j] are comparing addresses instead of the values? All help are appreciated

         /**
         * fifteen.c
         *
         * Computer Science 50
         * Problem Set 3
         *
         * Implements the 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 [MIN,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>

        // board's minimal dimension
        #define MIN 3

        // board's maximal dimension
        #define MAX 9

        // board, whereby board[i][j] represents row i and column j
        int board[MAX][MAX];

        // board's dimension
        int d;

        // prototypes
        void clear(void);
        void greet(void);
        void init(void);
        void draw(void);
        bool move(int tile);
        bool won(void);
        void save(void);

        int main(int argc, string argv[])
        {
            // greet player
            greet();

            // ensure proper usage
            if (argc != 2)
            {
                printf("Usage: ./fifteen d\n");
                return 1;
            }

            // ensure valid dimensions
            d = atoi(argv[1]);
            if (d < MIN || d > MAX)
            {
                printf("Board must be between %i x %i and %i x %i, inclusive.\n",
                    MIN, MIN, MAX, MAX);
                return 2;
            }

            // initialize the board
            init();

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

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

                // saves the current state of the board (for testing)
                save();

                // check for win
                if (won())
                {
                    printf("ftw!\n");
                    break;
                }

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

                // move if possible, else report illegality
                if (!move(tile))
                {
                    printf("\nIllegal move.\n");
                    usleep(500000);
                }

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

            // that's all folks
            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("GAME OF FIFTEEN\n");
            usleep(2000000);
        }

        /**
         * Initializes the game's board with tiles numbered 1 through d*d - 1,
         * (i.e., fills board with values but does not actually print them),
         * whereby board[i][j] represents row i and column j.
         */
        void init(void)
        {
            // TODO


            //populates the board with all the numbers and the blank space being 0
            for(int i=0; i<d; i++)
            {
                for(int j=0;j<d;j++)
                {
                  board[i][j]= (d*d)-(i*d)-j-1;
                        //Swap 2 & 1 if number of tiles are even)

                        if( (d*d)%2 == 0 )
                        {
                        //Assign value for original value of 2 to become 1 (swapping)
                        board[d-1][d-3] = 1;
                        //Assign value for original value of 1 to become 2 (swapping)
                        board[d-1][d-2] = 2;

                        // printf(" %d ",board[i][j]);

                    }
                }   
            }
        }

        /**
         * 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++)
                {
                    if(board[i][j]>=10)
                    {    
                    printf(" %d", board[i][j]);
                    }

                    if(board[i][j]<10 && board[i][j]>0)
                    {    
                    printf(" %2d", board[i][j]);
                    }

                    if(board[i][j]== 0)
                    {
                    printf("  _");
                    }

               } 

                printf(" \n");            
            } 
        }  


        /**
         * If tile borders empty space, moves tile and returns true, else
         * returns false. 
         */
        bool move(int tile)
        {

               // TODO

                    //Find the tile player entered
                    for(int i=0;i<d;i++)
                    {
                        for(int j=0;j<d;j++)
                        {
                            //If tile entered is valid
                             if(tile==board[i][j])
                             {  
                                   // temp value to store tile player wants to move

                                   //check if empty is right of tile | if valid, swap
                                    if(board[i][j+1]==0 && (j+1<d))
                                    {                          
                                        board[i][j+1]=tile;
                                        board[i][j]=0;
                                        return true;
                                    }

                                     //check if empty is left of tile | if valid, swap
                                    if(board[i][j-1]==0&& (j-1>=0))
                                    {
                                        board[i][j-1]=tile;
                                        board[i][j]=0;
                                        return true;
                                    }

                                    //check if empty is top of tile | if valid, swap
                                    if(board[i-1][j]==0 && (i-1>=0))
                                    {
                                        board[i-1][j]=tile;
                                        board[i][j]=0;
                                         return true;
                                    }

                                    //check if empty is bottom of tile | if valid, swap
                                    if(board[i+1][j]==0 && (i+1<d))
                                    {
                                        board[i+1][j]=tile;
                                        board[i][j]=0;
                                         return true;
                                    }

                                    else
                                    return false;

                              }

                         }  

                      }  
                    return false; 

        }         


        /**
         * Returns true if game is won (i.e., board is in winning configuration), 
         * else false.
         */
        bool won(void)
        {
        // TODO
        int win[MAX][MAX];


            for(int i=0;i<d;i++)
                {
                for(int j=0; j<d; j++)
                    {        
                         win[i][j]= (i*d)+(j+1);

                         if(win[i][j]==d*d)
                         win[i][j]=0; 

                         if(board[i][j]== win[i][j])
                         return 0;     
                    }

                }        
              return false;
        }

        /**
         * Saves the current state of the board to disk (for testing).
         */
        void save(void)
        {
            // log
            const string log = "log.txt";

            // delete existing log, if any, before first save
            static bool saved = false;
            if (!saved)
            {
                unlink(log);
                saved = true;
            }

            // open log
            FILE* p = fopen(log, "a");
            if (p == NULL)
            {
                return;
            }

            // log board
            fprintf(p, "{");
            for (int i = 0; i < d; i++)
            {
                fprintf(p, "{");
                for (int j = 0; j < d; j++)
                {
                    fprintf(p, "%i", board[i][j]);
                    if (j < d - 1)
                    {
                        fprintf(p, ",");
                    }
                }
                fprintf(p, "}");
                if (i < d - 1)
                {
                    fprintf(p, ",");
                }
            }
            fprintf(p, "}\n");

            // close log
            fclose(p);
        }
1

There are 1 answers

0
Armali On BEST ANSWER

Could this be a problem that board[i][j]==win[i][j] are comparing addresses instead of the values?

No, you just got the comparison and the return value in the winning configuration wrong (1 is true, 0 is false; to not get confused, just use 1 and 0), so change in won()

                         if(board[i][j]== win[i][j])

to

                         if (board[i][j] != win[i][j])

and

              return false;

to

            return 1;

then it works.