diff --git a/src/examples/2048.c b/src/examples/2048.c index 9915437..9a06621 100644 --- a/src/examples/2048.c +++ b/src/examples/2048.c @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,7 @@ typedef struct { typedef struct { uint32_t area[SIZE][SIZE]; dir_e direction; + uint32_t score; } game_t; static game_t game; @@ -63,7 +65,7 @@ move() case RIGHT: for (int i = 0; i < SIZE; i++) { uint32_t *row = game.area[i]; - for (int j = SIZE - 1; j >= 0; j--) { + for (int j = 0; j < SIZE; j++) { for (int k = SIZE - 1; k > 0; k--) { if (game.area[i][k] == 0 && game.area[i][k - 1] != 0) { game.area[i][k] = game.area[i][k - 1]; @@ -89,9 +91,9 @@ move() break; case DOWN: for (int i = 0; i < SIZE; i++) { - for (int j = SIZE - 1; j >= 0; j--) { + for (int j = 0; j < SIZE; j++) { for (int k = SIZE - 1; k > 0; k--) { - if (game.area[k][i] == 0 && game.area[k][i - 1] != 0) { + if (game.area[k][i] == 0 && game.area[k - 1][i] != 0) { game.area[k][i] = game.area[k - 1][i]; game.area[k - 1][i] = 0; retval = true; @@ -141,6 +143,7 @@ combine_horizontal( if (row[i] == row[i - direction]) { retval = true; row[i] *= 2; + game.score += row[i]; row[i - direction] = 0; for (int j = i - direction; (game.direction == LEFT) ? j < end : j > end; j -= direction) { row[j] = row[j - direction]; @@ -185,6 +188,7 @@ combine_vertical( if (game.area[i][col_index] == game.area[i - direction][col_index]) { retval = true; game.area[i][col_index] *= 2; + game.score += game.area[i][col_index]; game.area[i - direction][col_index] = 0; for (int j = i - direction; (game.direction == UP) ? j < end : j > end; j -= direction) { game.area[j][col_index] = game.area[j - direction][col_index]; @@ -230,13 +234,17 @@ slide() // 2. then combine them and shift the potential rest by one in the given direction bool has_combined = combine(has_moved); - - printf("moved? %s, combined? %s\n", (has_moved) ? "true" : "false", (has_combined) ? "true" : "false"); + + // printf("moved? %s, combined? %s\n", (has_moved) ? "true" : "false", (has_combined) ? "true" : "false"); // 3. generate a new 2 if (has_moved || has_combined) { new_2(); } + + // printf("score: %d\n", game.score); + + // print_area(); } // polling events every frame @@ -279,6 +287,68 @@ client_poll_event() #define CHR(ord) ((ord) + 48) #define ORD(chr) ((chr) - 48) +uint32_t +colors( + uint32_t number +) { + switch (number) { + case 0: + return 0xFFFFFF; + case 2: + return 0x00FF00; + case 4: + return 0xFF0000; + case 8: + return 0x0000FF; + default: + return 0xFFFFFF; + } +} + +uint32_t +numlen( + uint32_t n +) { + uint32_t len = 0; + + while (n > 0) { + len++; + n /= 10; + } + + return len; +} + +uint32_t +power( + uint32_t x, + uint32_t n +) { + // x ^ n + uint32_t acc = 1; + for (int i = 0; i < n; i++) { + acc *= x; + } + + return acc; +} + +uint32_t +numrev( + uint32_t n +) { + uint32_t len = numlen(n); + uint32_t new = 0; + int i = 0; + + while (n > 0) { + new += (n % 10) * power(10, len - (++i)); + n /= 10; + } + + return new; +} + // performed every frame void client_update_framebuffer() @@ -289,25 +359,55 @@ client_update_framebuffer() // ); clear_framebuffer(0x000000); - + uint32_t tile_size = game_state->width / SIZE; uint8_t border_width = 10; + char *n_str; + bool alloced = false; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { + alloced = true; // background uint32_t x = (border_width / 2) + i * tile_size; - uint32_t y = (border_width / 2)+ j * tile_size; + uint32_t y = (border_width / 2) + j * tile_size; uint32_t w = tile_size - border_width; uint32_t h = tile_size - border_width; - uint32_t background_color = 0xFFFFFF; + uint32_t background_color = colors(game.area[j][i]); put_rect(x, y, w, h, background_color); // number in foreground uint32_t foreground_color = 0x000000; - uint8_t font_size = 7; - put_char(CHR(game.area[j][i]), x + border_width, y + border_width, font_size, foreground_color, background_color); + uint8_t font_size = 3; + + uint32_t n = game.area[j][i]; + uint32_t n_len = numlen(n); + n_str = calloc(n_len, sizeof(char)); + if (n_str == NULL) { + game_state->is_running = false; + } + sprintf(n_str, "%d", n); + uint32_t n_rev = numrev(n); + uint32_t digit_offset = 1; + if (n != 0) { + put_string(n_str, x + border_width, y + border_width, font_size, digit_offset, 12, foreground_color, background_color); + } } } + + // score display line (single line) + char *score_text = calloc(numlen(game.score), sizeof(char)); + if (score_text == NULL) { + game_state->is_running = false; + } + alloced = true; + + sprintf(score_text, "score: %6d", game.score); + put_string(score_text, border_width / 2, tile_size * SIZE + border_width / 2, 6, 1, 12, 0xFFFFFF, 0x000000); + + if (alloced) { + free(n_str); + free(score_text); + } } bool @@ -372,64 +472,20 @@ game_init() } game.direction = RIGHT; -} - -void -tests() -{ - puts("---------- TEST SHIFT LEFT <- -------------\n"); - for (int i = 0; i < SIZE; i++) { - memset(game.area[i], 0, sizeof game.area[i]); - } - game.area[0][2] = 2; - game.area[0][3] = 2; - game.area[2][2] = 4; - game.direction = LEFT; - - slide(); - - puts("---------- TEST SHIFT RIGHT -> ------------\n"); - for (int i = 0; i < SIZE; i++) { - memset(game.area[i], 0, sizeof game.area[i]); - } - game.area[0][0] = 2; - game.area[0][1] = 2; - game.area[2][0] = 4; - game.direction = RIGHT; - - slide(); - - puts("---------- TEST SHIFT UP ^^ ---------------\n"); - for (int i = 0; i < SIZE; i++) { - memset(game.area[i], 0, sizeof game.area[i]); - } - game.area[2][0] = 2; - game.area[3][0] = 2; - game.area[2][2] = 4; - game.direction = UP; - - slide(); - - puts("---------- TEST SHIFT DOWN vv -------------\n"); - for (int i = 0; i < SIZE; i++) { - memset(game.area[i], 0, sizeof game.area[i]); - } - game.area[0][0] = 2; - game.area[1][0] = 2; - game.area[0][2] = 4; - game.direction = DOWN; - - slide(); + game.score = 0; } int main() { + uint32_t window_width = 500; + uint32_t window_height = window_width * 1.12f; + game_init(); // initialize the engine if (engine_init( - 500, 500, + window_width, window_height, "Dangerous 2048", client_poll_event, client_update_framebuffer