tsuweiquan

CS50_pset3_fifteen

Mar 9th, 2017
94
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * fifteen.c
  3.  *
  4.  * Implements Game of Fifteen (generalized to d x d).
  5.  *
  6.  * Usage: fifteen d
  7.  *
  8.  * whereby the board's dimensions are to be d x d,
  9.  * where d must be in [DIM_MIN,DIM_MAX]
  10.  *
  11.  * Note that usleep is obsolete, but it offers more granularity than
  12.  * sleep and is simpler to use than nanosleep; `man usleep` for more.
  13.  */
  14.  
  15. #define _XOPEN_SOURCE 500
  16.  
  17. #include <cs50.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <unistd.h>
  21.  
  22. // constants
  23. #define DIM_MIN 3
  24. #define DIM_MAX 9
  25.  
  26. // board
  27. int board[DIM_MAX][DIM_MAX];
  28.  
  29. // dimensions
  30. int d;
  31.  
  32. // prototypes
  33. void clear(void);
  34. void greet(void);
  35. void init(void);
  36. void draw(void);
  37. bool move(int tile);
  38. bool won(void);
  39.  
  40. int main(int argc, string argv[])
  41. {
  42.     // ensure proper usage
  43.     if (argc != 2)
  44.     {
  45.         printf("Usage: fifteen d\n");
  46.         return 1;
  47.     }
  48.  
  49.     // ensure valid dimensions
  50.     d = atoi(argv[1]);
  51.     if (d < DIM_MIN || d > DIM_MAX)
  52.     {
  53.         printf("Board must be between %i x %i and %i x %i, inclusive.\n",
  54.             DIM_MIN, DIM_MIN, DIM_MAX, DIM_MAX);
  55.         return 2;
  56.     }
  57.  
  58.     // open log
  59.     FILE *file = fopen("log.txt", "w");
  60.     if (file == NULL)
  61.     {
  62.         return 3;
  63.     }
  64.  
  65.     // greet user with instructions
  66.     greet();
  67.  
  68.     // initialize the board
  69.     init();
  70.  
  71.     // accept moves until game is won
  72.     while (true)
  73.     {
  74.         // clear the screen
  75.         clear();
  76.  
  77.         // draw the current state of the board
  78.         draw();
  79.  
  80.         // log the current state of the board (for testing)
  81.         for (int i = 0; i < d; i++)
  82.         {
  83.             for (int j = 0; j < d; j++)
  84.             {
  85.                 if(board[i][j] == 0 )
  86.                 {
  87.                     fprintf(file, " _");
  88.                    
  89.                 }else if(board[i][j] != 0)
  90.                 {
  91.                     fprintf(file, "%2i", board[i][j]);
  92.                    
  93.                 }
  94.                
  95.                 if (j < d - 1)
  96.                 {
  97.                     fprintf(file, "|");
  98.                 }
  99.                
  100.             }
  101.             fprintf(file, "\n");
  102.         }
  103.         fflush(file);
  104.  
  105.         // check for win
  106.         if (won())
  107.         {
  108.             printf("ftw!\n");
  109.             break;
  110.         }
  111.  
  112.         // prompt for move
  113.         printf("Tile to move: ");
  114.         int tile = get_int();
  115.        
  116.         // quit if user inputs 0 (for testing)
  117.         if (tile == 0)
  118.         {
  119.             break;
  120.         }
  121.  
  122.         // log move (for testing)
  123.         fprintf(file, "%i\n", tile);
  124.         fflush(file);
  125.  
  126.         // move if possible, else report illegality
  127.         if (!move(tile))
  128.         {
  129.             printf("\nIllegal move.\n");
  130.             usleep(500000);
  131.         }
  132.  
  133.         // sleep thread for animation's sake
  134.         usleep(500000);
  135.     }
  136.    
  137.     // close log
  138.     fclose(file);
  139.  
  140.     // success
  141.     return 0;
  142. }
  143.  
  144. /**
  145.  * Clears screen using ANSI escape sequences.
  146.  */
  147. void clear(void)
  148. {
  149.     printf("\033[2J");
  150.     printf("\033[%d;%dH", 0, 0);
  151. }
  152.  
  153. /**
  154.  * Greets player.
  155.  */
  156. void greet(void)
  157. {
  158.     clear();
  159.     printf("WELCOME TO GAME OF FIFTEEN\n");
  160.     usleep(2000000);
  161. }
  162.  
  163. /**
  164.  * Initializes the game's board with tiles numbered 1 through d*d - 1
  165.  * (i.e., fills 2D array with values but does not actually print them).  
  166.  */
  167. void init(void)
  168. {
  169.         int init_value = (d*d)-1;
  170.        
  171.         for (int i = 0; i < d; i++) // d is dimention, this for loop affect row
  172.             {
  173.                 for (int j = 0; j < d; j++) // d is dimention, this for loop affect coloumn
  174.                 {
  175.                     board[i][j] = init_value;
  176.                     init_value--;
  177.                 }
  178.             }
  179.            
  180.         if (d%2==0){ // if modulo 2 gives a 0, means it's even, time to swap
  181.             //swapping [3][1] and [3][2] if even
  182.             int x = board[d-1][d-3];
  183.             int y = board[d-1][d-2];
  184.             board[d-1][d-3] = y;
  185.             board[d-1][d-2] = x;
  186.         }
  187.        
  188. }
  189.        
  190.  
  191. /**
  192.  * Prints the board in its current state.
  193.  */
  194. void draw(void)
  195. {
  196.     for (int i = 0; i < d; i++)
  197.     {
  198.         for (int j = 0; j < d; j++)
  199.         {
  200.             if(board[i][j] == 0)
  201.             {
  202.                 printf(" _");
  203.                
  204.             }else if(board[i][j] != 0)
  205.             {
  206.                 printf("%2i", board[i][j]);
  207.                
  208.             }
  209.  
  210.             if (j < d - 1)
  211.             {
  212.                 printf("|");
  213.             }
  214.            
  215.            
  216.         }
  217.         printf("\n");
  218.     }
  219.        
  220. }
  221.  
  222. /**
  223.  * If tile borders empty space, moves tile and returns true, else
  224.  * returns false.
  225.  */
  226. bool move(int tile)
  227. {
  228.     // user will key in a number
  229.     //use this int to match with the board location
  230.     //once found
  231.     //program the number keyed in to swap position
  232.     //BUT ONLY CAN SWAP IF ITS LEGAL Eg, up down left right
  233.    
  234.     int loc_x;
  235.     int loc_y;
  236.    
  237.     if(tile > (d*d)-1 || tile < 1){
  238.         return false;
  239.     }
  240.    
  241.    
  242.     for (int x=0; x < d; x++){
  243.         for (int y=0; y < d; y++){
  244.            
  245.             if (board[x][y] == tile){ // finds the tile to move location                          
  246.                 // tile_select = board[x][y]; aka tile.
  247.                 // now, need to check if legal to swap.
  248.                 loc_x = x;
  249.                 loc_y = y;
  250.             }                        
  251.         }
  252.     }
  253.    
  254.     if (board[loc_x+1][loc_y] == 0 && (loc_x+1 < d)){      // check below
  255.         board[loc_x+1][loc_y] = board[loc_x][loc_y];        // value above 0 is replaced with non-0
  256.         board[loc_x][loc_y] = 0;    // value above 0 is now 0
  257.         return true;
  258.     }else if (board[loc_x-1][loc_y] == 0 && (loc_x-1 >= 0)){      // check above
  259.         board[loc_x-1][loc_y] = board[loc_x][loc_y];        // value above 0 is replaced with non-0
  260.         board[loc_x][loc_y] = 0;    // value above 0 is now 0
  261.         return true;
  262.     }else if (board[loc_x][loc_y+1] == 0 && (loc_y+1 < d)){      //check right
  263.         board[loc_x][loc_y+1] = board[loc_x][loc_y];        // value above 0 is replaced with non-0
  264.         board[loc_x][loc_y] = 0;    // value above 0 is now 0
  265.         return true;
  266.     }else if (board[loc_x][loc_y-1] == 0 && (loc_y-1 >= 0)){      //check left
  267.         board[loc_x][loc_y-1] = board[loc_x][loc_y];        // value above 0 is replaced with non-0
  268.         board[loc_x][loc_y] = 0;    // value above 0 is now 0
  269.         return true;
  270.     }
  271.     return false;
  272. }
  273.  
  274. /**
  275.  * Returns true if game is won (i.e., board is in winning configuration),
  276.  * else false.
  277.  */
  278. bool won(void)
  279. {
  280.  
  281.     int count_up =1;
  282.     for (int i=0; i<d;i++)
  283.     {
  284.        
  285.         for (int j=0;j<d;j++)
  286.         {
  287.        
  288.             if(board[i][j] == count_up) //if equal to 1 starting
  289.             {
  290.                 count_up ++;
  291.                 if(count_up == (d*d)-1){ //if count_up successfully adds up to the max value, means all is correct.
  292.                     return true;
  293.                 }
  294.             }
  295.         }
  296.     }
  297.    
  298.     return false;
  299.    
  300. }
RAW Paste Data