Advertisement
Guest User

2048

a guest
Jan 2nd, 2018
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.32 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <unistd.h>
  3. #include <termios.h>
  4. #include <string.h>
  5. #include <time.h>
  6.  
  7. #define BOARDSIZE 4
  8. #define CELL(board, x, y) ((board)[(x) * BOARDSIZE + (y)])
  9.  
  10. enum direction {UP, LEFT, DOWN, RIGHT};
  11. typedef enum direction dir_t;
  12.  
  13. int *init_board() {
  14.     int *board = calloc(BOARDSIZE * BOARDSIZE, sizeof(int));
  15.     return board;
  16. }
  17.  
  18. int disable_newline(struct termios *oldt) {
  19.     struct termios newt;
  20.  
  21.     tcgetattr(STDIN_FILENO, oldt);
  22.     memcpy(&newt, oldt, sizeof(struct termios));
  23.     newt.c_lflag &= ~(ICANON | ECHO);
  24.     tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  25.  
  26.     // Actual error checking some day.
  27.     return 0;
  28. }
  29.  
  30. void redraw_board(int *board) {
  31.     int i, j;
  32.     for (i = 0; i < BOARDSIZE; i++) {
  33.         for (j = 0; j < BOARDSIZE; j++) {
  34.             printf(" %4d ", CELL(board, i, j));
  35.         }
  36.         putchar('\n');
  37.     }
  38.     putchar('\n');
  39. }
  40.  
  41. void add_random(int *board) {
  42.     int x, y;
  43.     do {
  44.         x = rand() % BOARDSIZE;
  45.         y = rand() % BOARDSIZE;
  46.     } while (CELL(board, x, y) != 0);
  47.     CELL(board, x, y) = 2;
  48. }
  49.  
  50. int move(int *board, dir_t where) {
  51.     int target = -1;
  52.     int moved = 0;
  53.     switch(where) {
  54.         case RIGHT:
  55.             for (int i = 0; i < BOARDSIZE; i++) {
  56.                 target = BOARDSIZE - 1;
  57.                 for (int j = BOARDSIZE - 1; j >= 0; j--) {
  58.                     if (CELL(board, i, j) == 0) {
  59.                         ;
  60.                     } else if (target == j) {
  61.                        target--;
  62.                     } else {
  63.                         CELL(board, i, target) = CELL(board, i, j);
  64.                         CELL(board, i, j) = 0;
  65.                         target--;
  66.                         moved = 1;
  67.                     }
  68.                 }
  69.             }
  70.             break;
  71.         case LEFT:
  72.             for (int i = 0; i < BOARDSIZE; i++) {
  73.                 target = 0;
  74.                 for (int j = 0; j < BOARDSIZE; j++) {
  75.                     if (CELL(board, i, j) == 0) {
  76.                         ;
  77.                     } else if (target == j) {
  78.                         target++;
  79.                     } else {
  80.                         CELL(board, i, target) = CELL(board, i, j);
  81.                         CELL(board, i, j) = 0;
  82.                         target++;
  83.                         moved = 1;
  84.                     }
  85.                 }
  86.             }
  87.             break;
  88.         case DOWN:
  89.             for (int j = 0; j < BOARDSIZE; j++) {
  90.                 target = BOARDSIZE - 1;
  91.                 for (int i = BOARDSIZE - 1; i >= 0; i--) {
  92.                     if (CELL(board, i, j) == 0) {
  93.                         ;
  94.                     } else if (target == i) {
  95.                         target--;
  96.                     } else {
  97.                         CELL(board, target, j) = CELL(board, i, j);
  98.                         CELL(board, i, j) = 0;
  99.                         target--;
  100.                         moved = 1;
  101.                     }
  102.                 }
  103.             }
  104.             break;
  105.         case UP:
  106.             for (int j = 0; j < BOARDSIZE; j++) {
  107.                 target = 0;
  108.                 for (int i = 0; i < BOARDSIZE; i++) {
  109.                     if (CELL(board, i, j) == 0) {
  110.                         ;
  111.                     } else if (target == i) {
  112.                         target++;
  113.                     } else {
  114.                         CELL(board, target, j) = CELL(board, i, j);
  115.                         CELL(board, i, j) = 0;
  116.                         target++;
  117.                         moved = 1;
  118.                     }
  119.                 }
  120.             }
  121.             break;
  122.  
  123.         default:
  124.             break;
  125.     }
  126.     return moved;
  127. }
  128.  
  129.  
  130. int merge(int *board, dir_t where) {
  131.     int merged = 0;
  132.     switch(where) {
  133.         case RIGHT:
  134.             for (int i = 0; i < BOARDSIZE; i++) {
  135.                 for (int j = BOARDSIZE - 1; j >= 0 + 1; j--) {
  136.                     if (CELL(board, i, j) == 0) {
  137.                         ;
  138.                     } else if (CELL(board, i, j) == CELL(board, i, j - 1)) {
  139.                         CELL(board, i, j) *= 2;
  140.                         CELL(board, i, j - 1) = 0;
  141.                         /* Skip over next cell (one we just merged into) to
  142.                          * prevent unexpected double merging) */
  143.                         j--;
  144.                         merged = 1;
  145.                     }
  146.                 }
  147.             }
  148.             break;
  149.         case LEFT:
  150.             for (int i = 0; i < BOARDSIZE; i++) {
  151.                 for (int j = 0; j <= BOARDSIZE - 1 - 1; j++) {
  152.                     if (CELL(board, i, j) == 0) {
  153.                         ;
  154.                     } else if (CELL(board, i, j) == CELL(board, i, j + 1)) {
  155.                         CELL(board, i, j) *= 2;
  156.                         CELL(board, i, j + 1) = 0;
  157.                         j++;
  158.                         merged = 1;
  159.                     }
  160.                 }
  161.             }
  162.             break;
  163.         case DOWN:
  164.             for (int j = 0; j < BOARDSIZE; j++) {
  165.                 for (int i = BOARDSIZE - 1; i >= 0 + 1; i--) {
  166.                     if (CELL(board, i, j) == 0) {
  167.                         ;
  168.                     } else if (CELL(board, i, j) == CELL(board, i - 1, j)) {
  169.                         CELL(board, i, j) *= 2;
  170.                         CELL(board, i - 1, j) = 0;
  171.                         i++;
  172.                         merged = 1;
  173.                     }
  174.                 }
  175.             }
  176.             break;
  177.         case UP:
  178.             for (int j = 0; j < BOARDSIZE; j++) {
  179.                 for (int i = 0; i <= BOARDSIZE - 1 - 1; i++) {
  180.                     if (CELL(board, i, j) == 0) {
  181.                         ;
  182.                     } else if (CELL(board, i, j) == CELL(board, i + 1, j)) {
  183.                         CELL(board, i, j) *= 2;
  184.                         CELL(board, i + 1, j) = 0;
  185.                         i--;
  186.                         merged = 1;
  187.                     }
  188.                 }
  189.             }
  190.             break;
  191.                    
  192.         default:
  193.             break;
  194.     }
  195.     return merged;
  196. }
  197.  
  198. int move_possible(int *board) {
  199.     // Check if there's a 0 on the board that allows a move
  200.     for (int i = 0; i < BOARDSIZE * BOARDSIZE; i++) {
  201.         if (!board[i]) {
  202.             return 1;
  203.         }
  204.     }
  205.  
  206.     // Check if there's a horizontal merge possible
  207.     for (int i = 0; i < BOARDSIZE; i++) {
  208.         for (int j = 0; j < BOARDSIZE - 1; j++) {
  209.             if (CELL(board, i, j) == CELL(board, i, j + 1)) {
  210.                 return 1;
  211.             }
  212.         }
  213.     }
  214.  
  215.     // Check if there's a vertical merge possible
  216.     for (int j = 0; j < BOARDSIZE; j++) {
  217.         for (int i = 0; i < BOARDSIZE - 1; i++) {
  218.             if (CELL(board, i, j) == CELL(board, i + 1, j)) {
  219.                 return 1;
  220.             }
  221.         }
  222.     }
  223.  
  224.     return 0;
  225. }
  226.  
  227. int main(int argc, char *argv[]) {
  228.     srand(time(NULL));
  229.     int *board = init_board();
  230.     if (board == NULL) {
  231.         printf("Something went wrong allocating board space.\n");
  232.         return 1;
  233.     }
  234.  
  235.     struct termios oldt;
  236.     disable_newline(&oldt);
  237.  
  238.     add_random(board);
  239.     board[0] = 2;
  240.     board[4] = 2;
  241.     board[8] = 4;
  242.     board[12] = 8;
  243.  
  244.     while (1) {
  245.         redraw_board(board);
  246.         char ch = getchar();
  247.         int merged, moved1, moved2 = 0;
  248.         dir_t where;
  249.  
  250.         switch(ch) {
  251.             case 'q':
  252.                 tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  253.                 exit(0);
  254.                 break;
  255.             case 'w':
  256.                 where = UP;
  257.                 break;
  258.             case 'a':
  259.                 where = LEFT;
  260.                 break;
  261.             case 'd':
  262.                 where = RIGHT;
  263.                 break;
  264.             case 's':
  265.                 where = DOWN;
  266.                 break;
  267.             default:
  268.                 printf("WASD to move tiles, q to quit.\n");
  269.         }
  270.         moved1 = move(board, where);
  271.         merged = merge(board, where);
  272.         moved2 = move(board, where);
  273.         if (moved1 || moved2 || merged) {
  274.             add_random(board);
  275.         } else {
  276.             if (!move_possible(board)) {
  277.                 printf("No move possible! :(\n");
  278.                 break;
  279.             }
  280.             printf("state hasn't changed, not adding new tile\n");
  281.         }
  282.     }
  283.  
  284.     return 0;
  285. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement