jag

tetoris_c

public

Small block game in C

Star0
Watch0
6642d1d9ca12fe4a7b7732a94430c68fb49956ce
1
ssh://git@git.jaglekon.de:30/jag/tetoris_c.git
main.cC228 lines4.1 KB
1
#include "main.h"
2
3
4
tetromino playfield[FULL_HEIGHT][FULL_WIDTH] = {};
5
6
7
int main () {
8
  
9
10
  /* Setting up the seed */
11
  
12
  srand(time(NULL));
13
14
15
  /* Setting up terminal with termios */
16
  
17
  struct termios old, new;
18
19
  tcgetattr(STDIN_FILENO, &old);
20
  new = old;
21
22
  new.c_lflag &= ~(ECHO | ICANON);
23
  new.c_cc[VMIN] = 0;
24
  new.c_cc[VTIME] = 0;
25
26
  tcsetattr(STDIN_FILENO, TCSANOW, &new);
27
28
  struct winsize init_size, current_size;
29
  ioctl(STDOUT_FILENO, TIOCGWINSZ, &init_size);
30
  current_size = init_size;
31
32
  printf("\033[?25l\033[?1049h");
33
34
35
  /* Init */
36
37
  init_field();
38
39
  bool is_piece = false;
40
41
  piece current_piece = {};
42
43
44
  uint16_t i;
45
46
  for (i = 0;; i++) {
47
48
    int8_t move = 0;
49
    bool down = false;
50
    bool draw = false;
51
    bool rotate = false;
52
53
    int8_t j, k;
54
55
    if (!is_piece) {
56
      current_piece = init_piece((rand() % Z_PIECE) + 1);
57
      is_piece = true;
58
      draw = true;
59
      i = 0;
60
    }
61
62
63
    /* Take care of the input */
64
65
66
    char buf[10] = {};
67
68
    if (read(STDIN_FILENO, buf, sizeof(buf)) > 0) {
69
      if (buf[0] == 'q') {
70
        break;
71
      }
72
73
      if (buf[0] == '\033' && buf[1] == '[') {
74
        
75
        switch (buf[2]) {
76
          case 'A':
77
            rotate = true;
78
            break;
79
          case 'B':
80
            down = true;
81
            break;
82
          case 'C':
83
            move = 1;
84
            break;
85
          case 'D':
86
            move = -1;
87
            break;
88
          default:
89
            break;
90
        }
91
      }
92
    }
93
94
95
    /* Move piece */
96
97
    if (move != 0) {
98
      if (
99
        current_piece.x + move >= 0 && 
100
        current_piece.x + move + current_piece.size <= FULL_WIDTH
101
      ) {
102
       
103
        bool is_valid = true;
104
105
        piece moved_piece = current_piece;
106
        moved_piece.x += move;
107
108
        if (valid_position(moved_piece)) {
109
          current_piece.x += move;
110
          draw = true;
111
        }
112
      }
113
    }
114
115
116
    /* Piece rotates */
117
    
118
    if (rotate && current_piece.positions > 1) {
119
      
120
      piece rotated = current_piece;
121
122
      rotated.rotation = (current_piece.rotation + 1) % (current_piece.positions);
123
      
124
      if (valid_position(rotated)) {
125
        current_piece = rotated;
126
        draw = true;
127
      }
128
    }
129
    
130
131
    /* Piece falls */
132
133
    if (i >= 100 || down) {
134
      current_piece.y++;
135
      i = 0;
136
      draw = true;
137
    }
138
139
140
    /* When a piece is stuck */
141
142
    if (!valid_position(current_piece)) {
143
144
      for (j = 0; j < current_piece.size; j++) {
145
        for (k = 0; k < current_piece.size; k++) {
146
          
147
          if (current_piece.piece[j][k]) {
148
            
149
            coord solid = find_direction(current_piece, k, j);
150
151
            playfield[current_piece.y - 1 + solid.y][current_piece.x + solid.x] = current_piece.name;
152
          }
153
        }
154
      }
155
      is_piece = false;
156
      draw = true;
157
    }
158
159
160
    /* Looks if there is a tetris */
161
162
    bool blink[FIELD_HEIGHT] = {};
163
    bool is_tetris = false;
164
165
    for (j = FIELD_HEIGHT - 1; j >= 0; j--) {
166
167
      uint8_t blocked = 0;
168
169
      for (k = 0; k < FIELD_WIDTH; k++) {
170
        if (playfield[j][k + BORDER_WIDTH] != EMPTY)
171
          blocked++;
172
      }
173
174
      if (blocked == 10) {
175
        
176
        blink[j] = true;
177
        is_tetris = true;  
178
      }
179
    }
180
181
    if (is_tetris) {
182
      for (j = 0; j < 4; j++) {
183
        draw_board(current_piece, (j % 2 == 0) ? NULL : blink, is_piece);
184
        usleep(200000);
185
      }
186
187
      for (j = 0; j < FIELD_HEIGHT; j++) {
188
        if (blink[j]) {
189
190
          for (k = j; k > 0; k--) {
191
            int8_t l;
192
          
193
            for (l = 0; l < FIELD_WIDTH; l++) {
194
              playfield[k][l + BORDER_WIDTH] = playfield[k - 1][l + BORDER_WIDTH];
195
            }
196
          }
197
        }
198
      }
199
    }
200
201
202
    /* Looks for game over */
203
204
    for (j = 0; j < FIELD_WIDTH; j++) {
205
      if (playfield[TOP_GAP][j + BORDER_WIDTH] > 0) {
206
        draw_board(current_piece, NULL, is_piece);
207
        sleep(2);
208
        printf("\033[2J\033[H");
209
        printf("HAHA LOSER\n");
210
        sleep(1);
211
        goto end;
212
      }
213
    }
214
215
216
    if (draw)
217
      draw_board(current_piece, NULL, is_piece);
218
    usleep(10000);
219
  }
220
221
end:
222
223
  printf("\033[?1049l\033[?25h");
224
225
  tcsetattr(STDIN_FILENO, TCSANOW, &old);
226
227
  return 0;
228
}