Advertisement
Guest User

Untitled

a guest
Jul 14th, 2014
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.37 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <curses.h>
  4. #include <string.h>
  5. #include <time.h>
  6.  
  7. #define max(a, b) ((a) > (b) ? (a) : (b))
  8.  
  9. #define NROWS 4
  10. #define NCOLS NROWS
  11.  
  12. typedef unsigned int tile_t;
  13.  
  14. struct game_t {
  15. int turns, score;
  16. tile_t board[NROWS][NCOLS];
  17. };
  18.  
  19. // place_tile() returns 0 if it did place a tile and -1 if there is no open
  20. // space.
  21. int place_tile(struct game_t *game)
  22. {
  23. // lboard is the "linear board" -- no need to distinguish rows/cols
  24. tile_t *lboard = (tile_t *)game->board;
  25. int i, num_zeros = 0;
  26.  
  27. // Walk the board and count the number of empty tiles
  28. for (i = 0; i < NROWS * NCOLS; i++) {
  29. num_zeros += lboard[i] ? 0 : 1;
  30. }
  31.  
  32. if (!num_zeros) {
  33. return -1;
  34. }
  35.  
  36. // Choose the insertion point
  37. int loc = random() % num_zeros;
  38.  
  39. // Find the insertion point and place the new tile
  40. for (i = 0; i < NROWS * NCOLS; i++) {
  41. if (!lboard[i] && !(loc--)) {
  42. lboard[i] = random() % 10 ? 1 : 2;
  43. return 0;
  44. }
  45. }
  46. return -1;
  47. }
  48.  
  49. void print_tile(int tile)
  50. {
  51. if (tile) {
  52. if (tile < 6)
  53. attron(A_BOLD);
  54. int pair = COLOR_PAIR(1 + (tile % 6));
  55. attron(pair);
  56. printw("%4d", 1 << tile);
  57. attroff(pair);
  58. attroff(A_BOLD);
  59. }
  60. else {
  61. printw(" .");
  62. }
  63. }
  64.  
  65. void print_game(struct game_t *game)
  66. {
  67. int r, c;
  68. move(0, 0);
  69. printw("Score: %6d Turns: %4d", game->score, game->turns);
  70. for (r = 0; r < NROWS; r++) {
  71. for (c = 0; c < NCOLS; c++) {
  72. move(r + 2, 5 * c);
  73. print_tile(game->board[r][c]);
  74. }
  75. }
  76.  
  77. refresh();
  78. }
  79.  
  80. int combine_left(struct game_t *game, tile_t row[NCOLS])
  81. {
  82. int c, did_combine = 0;
  83. for (c = 1; c < NCOLS; c++) {
  84. if (row[c] && row[c-1] == row[c]) {
  85. row[c-1]++;
  86. row[c] = 0;
  87. game->score += 1 << (row[c-1] - 1);
  88. did_combine = 1;
  89. }
  90. }
  91. return did_combine;
  92. }
  93.  
  94. // deflate_left() returns nonzero if it did deflate, and 0 otherwise
  95. int deflate_left(tile_t row[NCOLS])
  96. {
  97. tile_t buf[NCOLS] = {0};
  98. tile_t *out = buf;
  99. int did_deflate = 0;
  100.  
  101. int in;
  102. for (in = 0; in < NCOLS; in++) {
  103. if (row[in] != 0) {
  104. *out++ = row[in];
  105. did_deflate |= buf[in] != row[in];
  106. }
  107. }
  108.  
  109. memcpy(row, buf, sizeof(buf));
  110. return did_deflate;
  111. }
  112.  
  113. void rotate_clockwise(struct game_t *game)
  114. {
  115. tile_t buf[NROWS][NCOLS];
  116. memcpy(buf, game->board, sizeof(game->board));
  117.  
  118. int r, c;
  119. for (r = 0; r < NROWS; r++) {
  120. for (c = 0; c < NCOLS; c++) {
  121. game->board[r][c] = buf[NCOLS - c - 1][r];
  122. }
  123. }
  124. }
  125.  
  126. void move_left(struct game_t *game)
  127. {
  128. int r, ret = 0;
  129. for (r = 0; r < NROWS; r++) {
  130. tile_t *row = &game->board[r][0];
  131. ret |= deflate_left(row);
  132. ret |= combine_left(game, row);
  133. ret |= deflate_left(row);
  134. }
  135.  
  136. game->turns += ret;
  137. }
  138.  
  139. void move_right(struct game_t *game)
  140. {
  141. rotate_clockwise(game);
  142. rotate_clockwise(game);
  143. move_left(game);
  144. rotate_clockwise(game);
  145. rotate_clockwise(game);
  146. }
  147.  
  148. void move_up(struct game_t *game)
  149. {
  150. rotate_clockwise(game);
  151. rotate_clockwise(game);
  152. rotate_clockwise(game);
  153. move_left(game);
  154. rotate_clockwise(game);
  155. }
  156.  
  157. void move_down(struct game_t *game)
  158. {
  159. rotate_clockwise(game);
  160. move_left(game);
  161. rotate_clockwise(game);
  162. rotate_clockwise(game);
  163. rotate_clockwise(game);
  164. }
  165.  
  166. // Pass by value because this function mutates the game
  167. int lose_game(struct game_t test_game)
  168. {
  169. int start_turns = test_game.turns;
  170. move_left(&test_game);
  171. move_up(&test_game);
  172. move_down(&test_game);
  173. move_right(&test_game);
  174. return test_game.turns == start_turns;
  175. }
  176.  
  177. void init_curses()
  178. {
  179. int bg = 0;
  180. initscr(); // curses init
  181. start_color();
  182. cbreak(); // curses don't wait for enter key
  183. noecho(); // curses don't echo the pressed key
  184. keypad(stdscr,TRUE);
  185. clear(); // curses clear screen and send cursor to (0,0)
  186. refresh();
  187. curs_set(0);
  188.  
  189. bg = use_default_colors() == OK ? -1 : 0;
  190. init_pair(1, COLOR_RED, bg);
  191. init_pair(2, COLOR_GREEN, bg);
  192. init_pair(3, COLOR_YELLOW, bg);
  193. init_pair(4, COLOR_BLUE, bg);
  194. init_pair(5, COLOR_MAGENTA, bg);
  195. init_pair(6, COLOR_CYAN, bg);
  196. }
  197.  
  198. /* Clone of the 2048 sliding tile puzzle game. (C) Wes Waugh 2014
  199. *
  200. * This program only works on Unix-like systems with curses. Link against
  201. * the curses library. You can pass the -lcurses flag to gcc at compile
  202. * time.
  203. *
  204. * This program is free software, licensed under the GPLv3. Check the
  205. * LICENSE file for details.
  206. */
  207.  
  208. int max_tile(tile_t *lboard)
  209. {
  210. int i, ret = 0;
  211. for (i = 0; i < NROWS * NCOLS; i++) {
  212. ret = max(ret, lboard[i]);
  213. }
  214. return ret;
  215. }
  216.  
  217. int main()
  218. {
  219. init_curses();
  220.  
  221. const char *exit_msg = "";
  222. srandom(time(NULL));
  223.  
  224. struct game_t game = {0};
  225. int last_turn = game.turns;
  226.  
  227. place_tile(&game);
  228. place_tile(&game);
  229.  
  230. while (1) {
  231. print_game(&game);
  232.  
  233. if (lose_game(game)) {
  234. exit_msg = "lost";
  235. goto lose;
  236. }
  237.  
  238. last_turn = game.turns;
  239.  
  240. switch (getch()) {
  241. case 'h': case KEY_LEFT: move_left(&game); break;
  242. case 'j': case KEY_DOWN: move_down(&game); break;
  243. case 'k': case KEY_UP: move_up(&game); break;
  244. case 'l': case KEY_RIGHT: move_right(&game); break;
  245. case 'q':
  246. exit_msg = "quit";
  247. goto end;
  248. }
  249.  
  250. if (last_turn != game.turns)
  251. place_tile(&game);
  252. }
  253.  
  254. lose:
  255. move(7, 0);
  256. printw("You lose! Press q to quit.");
  257. while (getch() != 'q');
  258. end:
  259. endwin();
  260. printf("You %s after scoring %d points in %d turns, "
  261. "with largest tile %d\n",
  262. exit_msg, game.score, game.turns,
  263. 1 << max_tile((tile_t *)game.board));
  264. return 0;
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement