#include "2048.h" #include #include #include void game_add_block(Game *game) { bool is_full = true; for (int i = 0; i < game->field_size_x; i++) { for (int j = 0; j < game->field_size_y; j++) { if (game->field[j][i] == 0) { is_full = false; break; } } } if (is_full) { game->game_over = true; return; } size_t x, y; int value; do { x = rand() % game->field_size_x; y = rand() % game->field_size_y; value = (rand() % 2) + 1; } while (game->field[y][x] != 0); game->field[y][x] = value * 2; } Game game_init(size_t field_size_x, size_t field_size_y) { Game game; game.game_over = false; game.won = false; game.field_size_x = field_size_x; game.field_size_y = field_size_y; game.score = 0; game.field = malloc(sizeof(uint16_t *) * field_size_y); for (size_t i = 0; i < field_size_x; i++) { game.field[i] = calloc(field_size_y, sizeof(uint16_t) * field_size_y); } time_t t; srand((unsigned)time(&t)); game_add_block(&game); return game; } void game_destroy(Game *game) { for (size_t i = 0; i < game->field_size_x; i++) { free(game->field[i]); } free(game->field); game->field = NULL; } void game_move(Game *game, Direction direction) { if (game->game_over || game->won) { return; } // I have few chained for loops that do a lot of similar stuff so I call them in a for loop for better clarity and readability for (int u = 0; u < 3; u++) { for (int i = 0; i < game->field_size_x; i++) { uint16_t **field = game->field; // move everything on one side for (int j = 0; j < game->field_size_y - 1; j++) { // a, b is the same as i and j. It is just flipped when // it does not go horizontally so I can access stuff vertically int a = i; int b = j; if (direction == Up || direction == Down) { a = j; b = i; } // make it so it can work with different directions int directionality = b; if (direction == Down) { directionality = a; } int movement = 1; if (direction == Left || direction == Up) { if (direction == Left) { directionality = game->field_size_x - b - 1; } else { directionality = game->field_size_y - a - 1; } movement = -1; } // the similar stuff switch (u) { case 0: case 2: if (direction == Left || direction == Right) { if (field[a][directionality + movement] == 0) { field[a][directionality + movement] = field[a][directionality]; field[a][directionality] = 0; } } else { if (field[directionality + movement][b] == 0) { field[directionality + movement][b] = field[directionality][b]; field[directionality][b] = 0; } } break; case 1: // TODO: fix 444 <- 48, should be 84 if (direction == Left || direction == Right) { if (field[a][directionality + movement] == field[a][directionality]) { field[a][directionality + movement] = field[a][directionality] * 2; game->score += field[a][directionality + movement]; if (field[a][directionality + movement] == 2048) { game->won = true; } field[a][directionality] = 0; j++; } } else { if (field[directionality + movement][b] == field[directionality][b]) { field[directionality + movement][b] = field[directionality][b] * 2; game->score += field[directionality + movement][b]; if (field[directionality + movement][b] == 2048) { game->won = true; } field[directionality][b] = 0; j++; } } break; } } } } game_add_block(game); }