5 bool move_possible_north(board *b);
6 bool move_possible_south(board *b);
7 bool move_possible_east(board *b);
8 bool move_possible_west(board *b);
10 void move_north(board *b);
11 void move_south(board *b);
12 void move_east(board *b);
13 void move_west(board *b);
14 void merge(board *b, const int d);
15 void merge_north(board *b);
16 void merge_south(board *b);
17 void merge_east(board *b);
18 void merge_west(board *b);
20 void place_new_piece(board *b);
21 void game_loop(board *b);
24 board *tmp = malloc(sizeof(board));
29 void init_board(board *b) {
30 for(int i = 0; i < 4; ++i) {
31 for(int j = 0; j < 4; ++j)
36 srand((uint)time(NULL));
38 // second piece will be placed in game_loop
43 board *b = new_board();
50 void game_loop(board *b) {
54 while(move_possible_any(b)) {
58 printf("Make a move:\n");
59 fgets(c, sizeof(c), stdin);
77 printf("Invalid move: %c\n", c[0]);
82 if(!move_possible(b, d)) {
83 printf("Move not possible: %c\n", c[0]);
90 void place_new_piece(board *b) {
91 int prob = rand() % 100;
97 for(int i = 0; i < 4; ++i) {
98 for(int j = 0; j < 4; ++j) {
101 possibs[2*cnt+1] = j;
108 rx = possibs[2*pair];
109 ry = possibs[2*pair+1];
110 assert(b->x[rx][ry] == 0);
119 void free_board(board *b) {
123 void make_move(board *b, const int d) {
124 bool ok = (d == south) ||
130 * checked before already
131 * if(!move_possible(b, d))
139 bool move_possible_any(board *b) {
142 if(move_possible_south(b))
144 if(move_possible_east(b))
146 if(move_possible_north(b))
148 if(move_possible_west(b))
153 bool move_possible(board *b, const int d) {
154 bool ok = (d == south) ||
161 return move_possible_north(b);
163 return move_possible_south(b);
165 return move_possible_east(b);
167 return move_possible_west(b);
168 default: // will never execute anyway
173 void move(board *b, const int d) {
174 bool ok = (d == south) ||
192 default: // will never execute anyway
197 void merge(board *b, const int d) {
198 bool ok = (d == south) ||
216 default: // will never execute anyway
221 bool move_possible_south(board *b) {
222 for(int i = 0; i < 4; ++i) {
223 for(int j = 0; j < 3; ++j) {
224 if(b->x[i][j] != 0) {
225 if(b->x[i][j+1] == 0)
227 if(b->x[i][j] == b->x[i][j+1])
235 bool move_possible_north(board *b) {
236 for(int i = 0; i < 4; ++i) {
237 for(int j = 1; j < 4; ++j) {
238 if(b->x[i][j] != 0) {
239 if(b->x[i][j-1] == 0)
241 if(b->x[i][j] == b->x[i][j-1])
249 bool move_possible_east(board *b) {
250 for(int i = 0; i < 3; ++i) {
251 for(int j = 0; j < 4; ++j) {
252 if(b->x[i][j] != 0) {
253 if(b->x[i+1][j] == 0)
255 if(b->x[i+1][j] == b->x[i][j])
263 bool move_possible_west(board *b) {
264 for(int i = 1; i < 4; ++i) {
265 for(int j = 0; j < 4; ++j) {
266 if(b->x[i][j] != 0) {
267 if(b->x[i-1][j] == 0)
269 if(b->x[i-1][j] == b->x[i][j])
277 void move_north(board *b) {
279 for(int i = 0; i < 4; ++i) {
280 for(int j = 1; j < 4; ++j) {
281 if(b->x[i][j] != 0) {
283 while(b->x[i][k-1] == 0) {
284 b->x[i][k-1] = b->x[i][k];
295 void move_south(board *b) {
297 for(int i = 0; i < 4; ++i) {
298 for(int j = 2; j >= 0; --j) {
299 if(b->x[i][j] != 0) {
301 while(b->x[i][k+1] == 0) {
302 b->x[i][k+1] = b->x[i][k];
313 void move_east(board *b) {
315 for(int i = 2; i >= 0; --i) {
316 for(int j = 0; j < 4; ++j) {
317 if(b->x[i][j] != 0) {
319 while(b->x[k+1][j] == 0) {
320 b->x[k+1][j] = b->x[k][j];
331 void move_west(board *b) {
333 for(int i = 1; i < 4; ++i) {
334 for(int j = 0; j < 4; ++j) {
335 if(b->x[i][j] != 0) {
337 while(b->x[k-1][j] == 0) {
338 b->x[k-1][j] = b->x[k][j];
349 void merge_north(board *b) {
350 for(int i = 0; i < 4; ++i) {
351 for(int j = 1; j < 4; ++j) {
352 if(b->x[i][j] != 0 && b->x[i][j] == b->x[i][j-1]) {
356 b->points += b->x[i][j-1];
362 void merge_south(board *b) {
363 for(int i = 0; i < 4; ++i) {
364 for(int j = 2; j >= 0; --j) {
365 if(b->x[i][j] != 0 && b->x[i][j] == b->x[i][j+1]) {
369 b->points += b->x[i][j+1];
375 void merge_east(board *b) {
376 for(int i = 2; i >= 0; --i) {
377 for(int j = 0; j < 4; ++j) {
378 if(b->x[i][j] != 0 && b->x[i+1][j] == b->x[i][j]) {
380 b->points += b->x[i+1][j];
388 void merge_west(board *b) {
389 for(int i = 1; i < 4; ++i) {
390 for(int j = 0; j < 4; ++j) {
391 if(b->x[i][j] != 0 && b->x[i-1][j] == b->x[i][j]) {
393 b->points += b->x[i-1][j];
402 printf("||--------------------------------------------------------------||\n");
405 void print_board_line(board *b, int l) {
406 printf("||\t%u\t|\t%u\t|\t%u\t|\t%u\t||\n", b->x[0][l], b->x[1][l], b->x[2][l], b->x[3][l]);
410 void print_board(board *b) {
411 printf("\e[2J\e[0;0H");
412 printf("Score: %u\n", b->points);
414 for(int i = 0; i < 4; ++i) {
415 print_board_line(b, i);
420 void print_score(board *b) {
421 printf("Game Over\nScore:%u\n", b->points);
425 board *b = new_board();
429 assert(b->x[3][0] == 4);
433 board *b = new_board();
441 assert(b->x[0][0] == 4);
445 board *b = new_board();
451 assert(b->x[0][0] == 4);
455 board *b = new_board();
461 assert(b->x[0][3] == 4);
464 void move_merge_test1() {
465 board *b = new_board();
474 assert(b->x[3][3] == 4);
477 void move_north_test() {
478 board *b = new_board();
494 assert(b->x[2][0] == 8);
495 assert(b->x[0][0] == 2);
498 void move_merge_test2() {
499 board *b = new_board();
509 assert(b->x[3][1] == 4);
512 void move_merge_test3() {
513 board *b = new_board();
535 assert(b->x[3][1] == 4);