document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /**
  2.  * fifteen.c
  3.  *
  4.  * Computer Science 50
  5.  * Problem Set 3
  6.  *
  7.  * Implements the Game of Fifteen (generalized to d x d).
  8.  *
  9.  * Usage: ./fifteen d
  10.  *
  11.  * whereby the board\'s dimensions are to be d x d,
  12.  * where d must be in [MIN,MAX]
  13.  *
  14.  * Note that usleep is obsolete, but it offers more granularity than
  15.  * sleep and is simpler to use than nanosleep; `man usleep` for more.
  16.  */
  17.  
  18. #define _XOPEN_SOURCE 500
  19.  
  20. #include <cs50.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24.  
  25. // board\'s minimal dimension
  26. #define MIN 3
  27.  
  28. // board\'s maximal dimension
  29. #define MAX 9
  30.  
  31. // board, whereby board[i][j] represents row i and column j
  32. int board[MAX][MAX];
  33.  
  34. // board\'s dimension
  35. int d;
  36.  
  37. // prototypes
  38. void clear(void);
  39. void greet(void);
  40. void init(void);
  41. void draw(void);
  42. bool move(int tile);
  43. bool won(void);
  44. void save(void);
  45.  
  46. int main(int argc, string argv[])
  47. {
  48.     // greet player
  49.     greet();
  50.  
  51.     // ensure proper usage
  52.     if (argc != 2)
  53.     {
  54.         printf("Usage: ./fifteen d\\n");
  55.         return 1;
  56.     }
  57.  
  58.     // ensure valid dimensions
  59.     d = atoi(argv[1]);
  60.     if (d < MIN || d > MAX)
  61.     {
  62.         printf("Board must be between %i x %i and %i x %i, inclusive.\\n",
  63.             MIN, MIN, MAX, MAX);
  64.         return 2;
  65.     }
  66.  
  67.     // initialize the board
  68.     init();
  69.  
  70.     // accept moves until game is won
  71.     while (true)
  72.     {
  73.         // clear the screen
  74.         clear();
  75.  
  76.         // draw the current state of the board
  77.         draw();
  78.  
  79.         // saves the current state of the board (for testing)
  80.         save();
  81.  
  82.         // check for win
  83.         if (won())
  84.         {
  85.             printf("ftw!\\n");
  86.             break;
  87.         }
  88.  
  89.         // prompt for move
  90.         printf("Tile to move: ");
  91.         int tile = GetInt();
  92.  
  93.         // move if possible, else report illegality
  94.         if (!move(tile))
  95.         {
  96.             printf("\\nIllegal move.\\n");
  97.             usleep(500000);
  98.         }
  99.  
  100.         // sleep for animation\'s sake
  101.         usleep(500000);
  102.     }
  103.  
  104.     // that\'s all folks
  105.     return 0;
  106. }
  107.  
  108. /**
  109.  * Clears screen using ANSI escape sequences.
  110.  */
  111. void clear(void)
  112. {
  113.     printf("\\033[2J");
  114.     printf("\\033[%d;%dH", 0, 0);
  115. }
  116.  
  117. /**
  118.  * Greets player.
  119.  */
  120. void greet(void)
  121. {
  122.     clear();
  123.     printf("GAME OF FIFTEEN\\n");
  124.     usleep(2000000);
  125. }
  126.  
  127. /**
  128.  * Initializes the game\'s board with tiles numbered 1 through d*d - 1,
  129.  * (i.e., fills board with values but does not actually print them),
  130.  * whereby board[i][j] represents row i and column j.
  131.  */
  132. void init(void)
  133. {
  134.     // TODO
  135.     for(int i = 0; i < d; i++){
  136.         for(int j = 0; j < d; j++){
  137.             if(d % 2 == 0){
  138.                 if(d * d - 1 - j - i * d == 1) board[i][j] = 2;
  139.                 else if(d * d - 1 - j - i * d == 2) board[i][j] = 1;
  140.                 else board[i][j] = d * d - 1 - j - i * d;
  141.             }
  142.             else board[i][j] = d * d - 1 - j - i * d;
  143.         }
  144.     }
  145. }
  146.  
  147. /**
  148.  * Prints the board in its current state.
  149.  */
  150. void draw(void)
  151. {
  152.     // TODO
  153.     for(int i = 0; i < d; i++){
  154.         printf("\\n");
  155.         printf("  ");
  156.         for(int j = 0; j < d; j++){
  157.             if(board[i][j] == 0) printf("%2c ", \'_\');
  158.             else printf("%2d ", board[i][j]);
  159.         }
  160.         printf("\\n");
  161.     }
  162.     printf("\\n");
  163. }
  164.  
  165. /**
  166.  * If tile borders empty space, moves tile and returns true, else
  167.  * returns false.
  168.  */
  169. bool move(int tile)
  170. {
  171.     // TODO
  172.     int tmp;
  173.     for(int i = 0; i < d; i++){
  174.         for(int j = 0; j < d; j++){
  175.             if(board[i][j] == 0){
  176.                 if(board[i][j-1] == tile){
  177.                     tmp = board[i][j-1];
  178.                     board[i][j-1] = board[i][j];
  179.                     board[i][j] = tmp;
  180.                     return true;
  181.                 }
  182.                 else if(board[i-1][j] == tile){
  183.                     tmp = board[i-1][j];
  184.                     board[i-1][j] = board[i][j];
  185.                     board[i][j] = tmp;
  186.                     return true;
  187.                 }
  188.                 else if(board[i+1][j] == tile){
  189.                     tmp = board[i+1][j];
  190.                     board[i+1][j] = board[i][j];
  191.                     board[i][j] = tmp;
  192.                     return true;
  193.                 }
  194.                 else if(board[i][j+1] == tile){
  195.                     tmp = board[i][j+1];
  196.                     board[i][j+1] = board[i][j];
  197.                     board[i][j] = tmp;
  198.                     return true;
  199.                 }
  200.             }
  201.         }
  202.     }
  203.     return false;
  204. }
  205.  
  206. /**
  207.  * Returns true if game is won (i.e., board is in winning configuration),
  208.  * else false.
  209.  */
  210. bool won(void)
  211. {
  212.     // TODO
  213.     int winCount = 0;
  214.    
  215.     for(int i = 0; i < d; i++){
  216.         for(int j = 0; j < d; j++){
  217.             if(board[i][j] == 1 + j + d * i) winCount++;
  218.         }
  219.     }
  220.    
  221.     if(winCount == d * d - 1) return true;
  222.     else return false;
  223. }
  224.  
  225. /**
  226.  * Saves the current state of the board to disk (for testing).
  227.  */
  228. void save(void)
  229. {
  230.     // log
  231.     const string log = "log.txt";
  232.  
  233.     // delete existing log, if any, before first save
  234.     static bool saved = false;
  235.     if (!saved)
  236.     {
  237.         unlink(log);
  238.         saved = true;
  239.     }
  240.  
  241.     // open log
  242.     FILE* p = fopen(log, "a");
  243.     if (p == NULL)
  244.     {
  245.         return;
  246.     }
  247.  
  248.     // log board
  249.     fprintf(p, "{");
  250.     for (int i = 0; i < d; i++)
  251.     {
  252.         fprintf(p, "{");
  253.         for (int j = 0; j < d; j++)
  254.         {
  255.             fprintf(p, "%i", board[i][j]);
  256.             if (j < d - 1)
  257.             {
  258.                 fprintf(p, ",");
  259.             }
  260.         }
  261.         fprintf(p, "}");
  262.         if (i < d - 1)
  263.         {
  264.             fprintf(p, ",");
  265.         }
  266.     }
  267.     fprintf(p, "}\\n");
  268.  
  269.     // close log
  270.     fclose(p);
  271. }
');