diff options
| author | turnipgod | 2025-03-04 17:14:20 -0500 | 
|---|---|---|
| committer | turnipgod | 2025-03-04 17:14:20 -0500 | 
| commit | 359c47fa7573ba214f3b2e00a19fe2fd4c90e0d2 (patch) | |
| tree | a2a45cefe6352031242d9b2e2fb0754b3ea1f87a | |
| parent | 5e08a05586a62e7da5acf07a2ea511fff948b142 (diff) | |
some clean-up
| -rw-r--r-- | src/main.c | 390 | 
1 files changed, 221 insertions, 169 deletions
| @@ -15,19 +15,6 @@  #define SOFT_DROP_MULT 4.0  #define LOCK_TICK 0.5 -enum Phases { -    GENERATION, -    FALL, -    LOCK, -    PATTERN, -    //MARK, -    //ITERATE, -    //ANIMATE, -    //ELIMINATE, -    //COMPLETE, -    GAME_OVER, -} game_phase; -  enum InputResult {      NONE = 0,      MOVED, @@ -37,21 +24,32 @@ enum InputResult {  #include "tetromino.h"  struct { -    int pos_x; -    int pos_y; -    int rotation; -    int type; -} current_piece; - -struct Color matrix[MATRIX_WIDTH][MATRIX_HEIGHT]; -int piece_queue[TETROMINO_COUNT*2]; -int current_bag = 0; -int current_piece_index = 0; -int hold = 7; -int held = 0; -int game_over = 0; -double phase_time; -double fall_tick; +    enum { +        GENERATION, +        FALL, +        LOCK, +        PATTERN, +        //MARK, +        //ITERATE, +        //ANIMATE, +        //ELIMINATE, +        //COMPLETE, +        GAME_OVER, +    } phase; +    struct Color matrix[MATRIX_WIDTH][MATRIX_HEIGHT]; +    struct { +        int pos_x; +        int pos_y; +        int rotation; +        int type; +    } current_piece; +    int piece_queue[TETROMINO_COUNT*2]; +    int current_piece_index; +    int hold_piece; +    int held; +    double phase_time; +    double fall_tick; +} game_state;  void draw_block(int x, int y, int width, int height, struct Color color)  { @@ -60,14 +58,25 @@ void draw_block(int x, int y, int width, int height, struct Color color)  int is_overlap(int x, int y)  { -    for (int i = 0; i < tetrominos[current_piece.type].size; i++) { -        for (int j = 0; j < tetrominos[current_piece.type].size; j++) { -            if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { -                if (current_piece.pos_x + i - 1 + x >= MATRIX_WIDTH -                        || current_piece.pos_x + i - 1 + x < 0 -                        || current_piece.pos_y + j - 1 + y < 0 -                        || (!ColorIsEqual(BLACK, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y]) -                         && !ColorIsEqual(WHITE, matrix[current_piece.pos_x + i - 1 + x][current_piece.pos_y + j - 1 + y]))) { +    int piece = game_state.current_piece.type; +    int p_x = game_state.current_piece.pos_x; +    int p_y = game_state.current_piece.pos_y; +    int rot = game_state.current_piece.rotation; +    int c_x; +    int c_y; +    int i; +    int j; + +    for (i = 0; i < tetrominos[piece].size; i++) { +        for (j = 0; j < tetrominos[piece].size; j++) { +            if (tetrominos[piece].directions[rot][j][i] == 1) { +                c_x = p_x + i - 1 + x; +                c_y = p_y + j - 1 + y; +                if (p_x + i - 1 + x >= MATRIX_WIDTH +                    || p_x + i - 1 + x < 0 +                    || p_y + j - 1 + y < 0 +                    || (!ColorIsEqual(BLACK, game_state.matrix[c_x][c_y]) +                        && !ColorIsEqual(WHITE, game_state.matrix[c_x][c_y]))) {                      return 1;                  }              } @@ -98,31 +107,31 @@ void render_matrix(void)                  ,matrix_origin_y + j * BLOCK_SIZE + 1                  ,BLOCK_SIZE - 2                  ,BLOCK_SIZE - 2 -                ,matrix[i][j] +                ,game_state.matrix[i][j]              );          }      }      int ghost_y = 0; -    if (game_phase == FALL || game_phase == LOCK) { +    if (game_state.phase == FALL || game_state.phase == LOCK) {          /* draw ghost piece */          while(!is_overlap(0, ghost_y)) {              ghost_y--;          } -        for (int i = 0; i < tetrominos[current_piece.type].size; i++) { -            for (int j = 0; j < tetrominos[current_piece.type].size; j++) { -                if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { +        for (int i = 0; i < tetrominos[game_state.current_piece.type].size; i++) { +            for (int j = 0; j < tetrominos[game_state.current_piece.type].size; j++) { +                if (tetrominos[game_state.current_piece.type].directions[game_state.current_piece.rotation][j][i] == 1) {                      draw_block( -                        (matrix_origin_x + ((current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 3 -                        ,(matrix_origin_y + ((current_piece.pos_y + j + ghost_y) * BLOCK_SIZE)) + 3 +                        (matrix_origin_x + ((game_state.current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 3 +                        ,(matrix_origin_y + ((game_state.current_piece.pos_y + j + ghost_y) * BLOCK_SIZE)) + 3                          ,BLOCK_SIZE - 6                          ,BLOCK_SIZE - 6 -                        ,tetrominos[current_piece.type].color +                        ,tetrominos[game_state.current_piece.type].color                      );                      draw_block( -                        (matrix_origin_x + ((current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 4 -                        ,(matrix_origin_y + ((current_piece.pos_y + j + ghost_y) * BLOCK_SIZE)) + 4 +                        (matrix_origin_x + ((game_state.current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 4 +                        ,(matrix_origin_y + ((game_state.current_piece.pos_y + j + ghost_y) * BLOCK_SIZE)) + 4                          ,BLOCK_SIZE - 8                          ,BLOCK_SIZE - 8                          ,BLACK @@ -131,15 +140,15 @@ void render_matrix(void)              }          }          /* draw current piece */ -        for (int i = 0; i < tetrominos[current_piece.type].size; i++) { -            for (int j = 0; j < tetrominos[current_piece.type].size; j++) { -                if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { +        for (int i = 0; i < tetrominos[game_state.current_piece.type].size; i++) { +            for (int j = 0; j < tetrominos[game_state.current_piece.type].size; j++) { +                if (tetrominos[game_state.current_piece.type].directions[game_state.current_piece.rotation][j][i] == 1) {                      draw_block( -                        (matrix_origin_x + ((current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 1 -                        ,(matrix_origin_y + ((current_piece.pos_y + j - 1) * BLOCK_SIZE)) + 1 +                        (matrix_origin_x + ((game_state.current_piece.pos_x + i - 1) * BLOCK_SIZE)) + 1 +                        ,(matrix_origin_y + ((game_state.current_piece.pos_y + j - 1) * BLOCK_SIZE)) + 1                          ,BLOCK_SIZE - 2                          ,BLOCK_SIZE - 2 -                        ,tetrominos[current_piece.type].color +                        ,tetrominos[game_state.current_piece.type].color                      );                  }              } @@ -155,18 +164,18 @@ void render_matrix(void)          4*BLOCK_SIZE,          BLACK      ); -    if (hold != 7) { -        for (int i = 0; i < tetrominos[hold].size; i++) { -            for (int j = 0; j < tetrominos[hold].size; j++) { -                if (tetrominos[hold].directions[NORTH][j][i] == 1) { +    if (game_state.hold_piece != 7) { +        for (int i = 0; i < tetrominos[game_state.hold_piece].size; i++) { +            for (int j = 0; j < tetrominos[game_state.hold_piece].size; j++) { +                if (tetrominos[game_state.hold_piece].directions[NORTH][j][i] == 1) {                      draw_block(                          ((matrix_origin_x - BLOCK_SIZE * 5) + (i * BLOCK_SIZE)) + 1 -                               + ((hold != I && hold != O)?(BLOCK_SIZE/2):0) +                               + ((game_state.hold_piece != I && game_state.hold_piece != O)?(BLOCK_SIZE/2):0)                          ,matrix_origin_y + (MATRIX_HEIGHT/2 * BLOCK_SIZE) + ((j-4) * BLOCK_SIZE) -                               - ((hold == I)?BLOCK_SIZE/2:0) +                               - ((game_state.hold_piece == I)?BLOCK_SIZE/2:0)                          ,BLOCK_SIZE - 2                          ,BLOCK_SIZE - 2 -                        ,tetrominos[hold].color +                        ,tetrominos[game_state.hold_piece].color                      );                  }              } @@ -182,16 +191,17 @@ void render_matrix(void)          BLACK      );      for (int y = 0; y < 5; y++) { -        for (int i = 0; i < tetrominos[piece_queue[(y+current_piece_index)%14]].size; i++) { -            for (int j = 0; j < tetrominos[piece_queue[(y+current_piece_index)%14]].size; j++) { -                if (tetrominos[piece_queue[(y+current_piece_index)%14]].directions[NORTH][j][i] == 1) { +        for (int i = 0; i < tetrominos[game_state.piece_queue[(y+game_state.current_piece_index)%14]].size; i++) { +            for (int j = 0; j < tetrominos[game_state.piece_queue[(y+game_state.current_piece_index)%14]].size; j++) { +                if (tetrominos[game_state.piece_queue[(y+game_state.current_piece_index)%14]].directions[NORTH][j][i] == 1) {                      draw_block(                          (((SCREEN_WIDTH/2 + 1 - (BLOCK_SIZE)) + (i * BLOCK_SIZE)) + 1) + (BLOCK_SIZE * 4) -                           + ((piece_queue[(y+current_piece_index)%14] != I && piece_queue[(y+current_piece_index)%14] != O)?(BLOCK_SIZE/2):0) -                        ,((matrix_origin_y + MATRIX_HEIGHT/2 * BLOCK_SIZE - 15 * BLOCK_SIZE) + ((j - 1) * BLOCK_SIZE)) + 1 + ((3 - y) * BLOCK_SIZE * 4) - ((piece_queue[(y+current_piece_index)%14] == I)?BLOCK_SIZE/2:0) +                           + ((game_state.piece_queue[(y+game_state.current_piece_index)%14] != I && game_state.piece_queue[(y+game_state.current_piece_index)%14] != O)?(BLOCK_SIZE/2):0) +                        ,((matrix_origin_y + MATRIX_HEIGHT/2 * BLOCK_SIZE - 15 * BLOCK_SIZE) + ((j - 1) * BLOCK_SIZE)) + 1 + ((3 - y) * BLOCK_SIZE * 4) +                           - ((game_state.piece_queue[(y+game_state.current_piece_index)%14] == I)?BLOCK_SIZE/2:0)                          ,BLOCK_SIZE - 2                          ,BLOCK_SIZE - 2 -                        ,tetrominos[piece_queue[(y+current_piece_index)%14]].color +                        ,tetrominos[game_state.piece_queue[(y+game_state.current_piece_index)%14]].color                      );                  }              } @@ -201,12 +211,17 @@ void render_matrix(void)  void shuffle_bag(int *bag)  { -    for (int i = 0; i < TETROMINO_COUNT; i++) { +    int i; +    int r; +    int t; + +    for (i = 0; i < TETROMINO_COUNT; i++) {          bag[i] = i;      } -    for (int i = 0; i < TETROMINO_COUNT; i++) { -        int r = i + rand() / (RAND_MAX / (TETROMINO_COUNT - i) + 1); -        int t = bag[r]; + +    for (i = 0; i < TETROMINO_COUNT; i++) { +        r = i + rand() / (RAND_MAX / (TETROMINO_COUNT - i) + 1); +        t = bag[r];          bag[r] = bag[i];          bag[i] = t;      } @@ -214,31 +229,32 @@ void shuffle_bag(int *bag)  void generation_phase(void)  { -    if (phase_time < 0.2) { +    if (game_state.phase_time < 0.2) {          return;      }      // bag generation -    if (current_piece_index == 14) { -        shuffle_bag(&(piece_queue[7])); -        current_piece_index = 0; +    if (game_state.current_piece_index == 14) { +        shuffle_bag(&(game_state.piece_queue[7])); +        game_state.current_piece_index = 0;      } -    if (current_piece_index == 7) { -        shuffle_bag(piece_queue); +    if (game_state.current_piece_index == 7) { +        shuffle_bag(game_state.piece_queue);      }      // set current piece -    current_piece.type = piece_queue[current_piece_index++]; -    current_piece.rotation = NORTH; -    current_piece.pos_x = 4; -    current_piece.pos_y = 20; -    held = 0; -    phase_time = 0.0; +    game_state.current_piece.type = +        game_state.piece_queue[game_state.current_piece_index++]; +    game_state.current_piece.rotation = NORTH; +    game_state.current_piece.pos_x = 4; +    game_state.current_piece.pos_y = 20; +    game_state.held = 0; +    game_state.phase_time = 0.0;      // blockout lose condition      if (is_overlap(0, 0)) { -        game_phase = GAME_OVER; +        game_state.phase = GAME_OVER;      } else { -        game_phase = FALL; +        game_state.phase = FALL;      }  } @@ -247,35 +263,34 @@ int rotate_piece(int dir)      int *kick_table;      int i;      int can_rotate = 0; +    int piece = game_state.current_piece.type; +    int rot = game_state.current_piece.rotation; +    int init_rot = game_state.current_piece.rotation;      if (dir == 1) { -        kick_table = tetrominos[current_piece.type].cw_kick_table[current_piece.rotation]; +        kick_table = tetrominos[piece].cw_kick_table[rot];      } else if (dir == -1) { -        kick_table = tetrominos[current_piece.type].ccw_kick_table[current_piece.rotation]; +        kick_table = tetrominos[piece].ccw_kick_table[rot];      } -    current_piece.rotation += dir; -    if (current_piece.rotation < 0) { -        current_piece.rotation = 3; +    rot += dir; +    if (rot < 0) { +        rot = 3;      } else { -        current_piece.rotation = current_piece.rotation % 4; +        rot = rot % 4;      } +    game_state.current_piece.rotation = rot;      for (i = 0; i < 10 && !can_rotate; i += 2) {          if (!is_overlap(kick_table[i], kick_table[i+1])) { -            current_piece.pos_x += kick_table[i]; -            current_piece.pos_y += kick_table[i+1]; +            game_state.current_piece.pos_x += kick_table[i]; +            game_state.current_piece.pos_y += kick_table[i+1];              can_rotate = 1;          }      }      if (!can_rotate) { -        current_piece.rotation -= dir; -        if (current_piece.rotation < 0) { -            current_piece.rotation = 3; -        } else { -            current_piece.rotation = current_piece.rotation % 4; -        } +        game_state.current_piece.rotation = init_rot;      }      return can_rotate; @@ -286,16 +301,24 @@ int move_piece(int dir)      if (is_overlap(dir, 0)) {          return 0;      } -    current_piece.pos_x += dir; +    game_state.current_piece.pos_x += dir;      return 1;  }  void move_piece_to_matrix(void)  { -    for (int i = 0; i < tetrominos[current_piece.type].size; i++) { -        for (int j = 0; j < tetrominos[current_piece.type].size; j++) { -            if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { -                matrix[current_piece.pos_x + i - 1][current_piece.pos_y + j - 1] = tetrominos[current_piece.type].color; +    int piece = game_state.current_piece.type; +    int rot = game_state.current_piece.rotation; +    int x = game_state.current_piece.pos_x; +    int y = game_state.current_piece.pos_y; +    int i; +    int j; + +    for (i = 0; i < tetrominos[piece].size; i++) { +        for (j = 0; j < tetrominos[piece].size; j++) { +            if (tetrominos[piece].directions[rot][j][i] == 1) { +                game_state.matrix[x + i - 1][y + j - 1] = +                    tetrominos[piece].color;              }          }      } @@ -303,26 +326,30 @@ void move_piece_to_matrix(void)  void hold_piece(void)  { -    if (!held) { -        if (hold == 7) { -            hold = current_piece.type; -            current_piece.type = piece_queue[current_piece_index]; -            current_piece_index++; -            current_piece_index = current_piece_index % 14; +    int temp; + +    if (!game_state.held) { +        if (game_state.hold_piece == 7) { +            game_state.hold_piece = game_state.current_piece.type; +            game_state.current_piece.type = +                game_state.piece_queue[game_state.current_piece_index]; +            game_state.current_piece_index++; +            game_state.current_piece_index = +                game_state.current_piece_index % 14;          } else { -            int temp = current_piece.type; -            current_piece.type = hold; -            hold = temp; +            temp = game_state.current_piece.type; +            game_state.current_piece.type = game_state.hold_piece; +            game_state.hold_piece = temp;          } -        phase_time = 0.0; -        game_phase = FALL; -        current_piece.rotation = NORTH; -        current_piece.pos_x = 4; -        current_piece.pos_y = 20; +        game_state.phase_time = 0.0; +        game_state.phase = FALL; +        game_state.current_piece.rotation = NORTH; +        game_state.current_piece.pos_x = 4; +        game_state.current_piece.pos_y = 20;          if (is_overlap(0,0)) {              CloseWindow();          } -        held = 1; +        game_state.held = 1;      }  } @@ -373,7 +400,7 @@ int handle_input(void) {          if (!hard_dropped) {              hard_dropped = 1;              while (!is_overlap(0, -1)) { -                current_piece.pos_y--; +                game_state.current_piece.pos_y--;              }              return HARD_DROPPED;          } @@ -382,9 +409,9 @@ int handle_input(void) {      }      if (IsKeyDown(KEY_S)) { -        fall_tick = FALL_TICK / SOFT_DROP_MULT; +        game_state.fall_tick = FALL_TICK / SOFT_DROP_MULT;      } else { -        fall_tick = FALL_TICK; +        game_state.fall_tick = FALL_TICK;      }      if (IsKeyDown(KEY_SPACE)) { @@ -397,15 +424,15 @@ int handle_input(void) {  void lock_phase(void) {      enum InputResult action = handle_input();      if (action == MOVED) { -        phase_time = 0.0; +        game_state.phase_time = 0.0;      }      if (!is_overlap(0, -1)) { -        phase_time = 0.0; -        game_phase = FALL; -    } else if (phase_time >= LOCK_TICK || action == HARD_DROPPED) { +        game_state.phase_time = 0.0; +        game_state.phase = FALL; +    } else if (game_state.phase_time >= LOCK_TICK || action == HARD_DROPPED) {          move_piece_to_matrix(); -        phase_time = 0.0; -        game_phase = PATTERN; +        game_state.phase_time = 0.0; +        game_state.phase = PATTERN;      }  } @@ -413,26 +440,30 @@ void fall_phase(void)  {      enum InputResult action = handle_input();      if (action == HARD_DROPPED) { -        phase_time = 0.0; -        game_phase = PATTERN; +        game_state.phase_time = 0.0; +        game_state.phase = PATTERN;      } else {          if (is_overlap(0, -1)) { -            phase_time = 0.0; -            game_phase = LOCK; -        } else if (phase_time >= fall_tick || action == HARD_DROPPED) { -            phase_time = 0.0; -            current_piece.pos_y--; +            game_state.phase_time = 0.0; +            game_state.phase = LOCK; +        } else if (game_state.phase_time >= game_state.fall_tick +                    || action == HARD_DROPPED) { +            game_state.phase_time = 0.0; +            game_state.current_piece.pos_y--;          }      }  }  void clear_line(int line)  { -    for (int y = line; y < MATRIX_HEIGHT - 1; y++) { -        for (int x = 0; x < MATRIX_WIDTH; x++) { -            matrix[x][y] = matrix[x][y+1]; -            if (ColorIsEqual(matrix[x][y], WHITE) && y < 20) { -                matrix[x][y] = BLACK; +    int y; +    int x; + +    for (y = line; y < MATRIX_HEIGHT - 1; y++) { +        for (x = 0; x < MATRIX_WIDTH; x++) { +            game_state.matrix[x][y] = game_state.matrix[x][y+1]; +            if (ColorIsEqual(game_state.matrix[x][y], WHITE) && y < 20) { +                game_state.matrix[x][y] = BLACK;              }          }      } @@ -440,13 +471,17 @@ void clear_line(int line)  int check_lockout(void)  { +    int piece = game_state.current_piece.type; +    int rot = game_state.current_piece.rotation; +    int y = game_state.current_piece.pos_y;      int fully_above = 1; -    for (int i = 0; i < tetrominos[current_piece.type].size; i++) { -        for (int j = 0; j < tetrominos[current_piece.type].size; j++) { -            if (tetrominos[current_piece.type].directions[current_piece.rotation][j][i] == 1) { -                if (current_piece.pos_y + j - 1 < 20) { -                    fully_above = 0; -                } +    int i; +    int j; + +    for (i = 0; i < tetrominos[piece].size; i++) { +        for (j = 0; j < tetrominos[piece].size; j++) { +            if (tetrominos[piece].directions[rot][j][i] == 1) { +                if (y + j - 1 < 20) fully_above = 0;              }          }      } @@ -455,17 +490,22 @@ int check_lockout(void)  void pattern_phase(void)  { +    int y; +    int x; +    int line_full; +      if (check_lockout()) { -        phase_time = 0.0; -        game_phase = GAME_OVER; +        game_state.phase_time = 0.0; +        game_state.phase = GAME_OVER;          return;      }      move_piece_to_matrix(); -    for (int y = 0; y < MATRIX_HEIGHT; y++) { -        int line_full = 1; -        for (int x = 0; x < MATRIX_WIDTH; x++) { -            if (ColorIsEqual(matrix[x][y], BLACK) || ColorIsEqual(matrix[x][y], WHITE)) { +    for (y = 0; y < MATRIX_HEIGHT; y++) { +        line_full = 1; +        for (x = 0; x < MATRIX_WIDTH; x++) { +            if (ColorIsEqual(game_state.matrix[x][y], BLACK) +                || ColorIsEqual(game_state.matrix[x][y], WHITE)) {                  line_full = 0;              }          } @@ -473,14 +513,14 @@ void pattern_phase(void)              clear_line(y--);          }      } -    phase_time = 0.0; -    game_phase = GENERATION; +    game_state.phase_time = 0.0; +    game_state.phase = GENERATION;  }  void game_logic(void)  { -    phase_time += GetFrameTime(); -    switch (game_phase) { +    game_state.phase_time += GetFrameTime(); +    switch (game_state.phase) {          case GENERATION:              generation_phase();              break; @@ -494,34 +534,46 @@ void game_logic(void)              pattern_phase();              break;          case GAME_OVER: -            game_over = 1;              break;      }  } -int main(void) +void init(void)  { -    srand(time(NULL)); -    InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "~turnipGod's Tetris"); -    SetTargetFPS(60); - +    int y; +    int x;      // set default block colors -    for (int y = 0; y < 40; y++) { -        for (int x = 0; x < 10; x++) { +    for (y = 0; y < 40; y++) { +        for (x = 0; x < 10; x++) {              if (y < 20) { -                matrix[x][y] = BLACK; +                game_state.matrix[x][y] = BLACK;              } else { -                matrix[x][y] = WHITE; +                game_state.matrix[x][y] = WHITE;              }          }      } -    shuffle_bag(piece_queue); -    shuffle_bag(&(piece_queue[7])); -    phase_time = 0.0; -    game_phase = GENERATION; -    while (!WindowShouldClose() && !game_over) { +    shuffle_bag(game_state.piece_queue); +    shuffle_bag(&(game_state.piece_queue[7])); +    game_state.phase_time = 0.0; +    game_state.phase = GENERATION; +    game_state.hold_piece = 7; +    game_state.current_piece_index = 0; +    game_state.held = 0; +    game_state.fall_tick = FALL_TICK; + +} + +int main(void) +{ +    srand(time(NULL)); +    InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "~turnipGod's Tetris"); +    SetTargetFPS(60); + +    init(); + +    while (!WindowShouldClose() && game_state.phase != GAME_OVER) {          game_logic();          BeginDrawing();          ClearBackground(WHITE); | 
