Guest User

Untitled

a guest
Jan 22nd, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.76 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. enum { UP, DOWN, LEFT, RIGHT };
  6. typedef unsigned color;
  7.  
  8. struct vector { int x, y; };
  9. struct tetris { vector v[4]; };
  10.  
  11. enum { WIDTH = 10, HEIGHT = 20 };
  12. typedef int board[WIDTH * HEIGHT];
  13.  
  14. struct game
  15. {
  16. board b; // cell == 0 is empty else solid
  17. tetris t; // shape of block
  18. int r, x, y; // rotation and position of block
  19. int gravtime; // time until next drop
  20. int gravinit; // time between drops
  21. int score; // scoring is by squared number of cleared rows
  22. };
  23.  
  24. const tetris shapes[] =
  25. {
  26. {{{-1, 0}, {0, 0}, {1, 0}, {2, 0}}}, // I
  27. {{{-1, 0}, {0, 0}, {1, 0}, {1, 1}}}, // L
  28. {{{-1, 1}, {-1, 0}, {0, 0}, {1, 0}}}, // J
  29. {{{ 0, 0}, {0, 1}, {1, 0}, {1, 1}}}, // O
  30. {{{-1, 0}, {0, 0}, {0, 1}, {1, 1}}}, // Z
  31. {{{-1, 1}, {0, 1}, {0, 0}, {0, 1}}}, // S
  32. {{{-1, 0}, {0, 0}, {1, 0}, {0, 1}}} // T
  33. };
  34.  
  35. const vector rotations[][2] =
  36. {
  37. {{ 1, 0}, {0, 1}}, {{0, 1}, {-1, 0}}, // 0, 90
  38. {{-1, 0}, {0, -1}}, {{0, -1}, { 1, 0}} // 180, 270
  39. };
  40.  
  41. tetris transform(tetris t, int r, int x, int y)
  42. {
  43. for (vector *v = t.v; v < t.v + 4; v++) {
  44. const vector *m = rotations[r];
  45. int vx = v->x, vy = v->y;
  46. v->x = m[0].x * vx + m[0].y * vy + x;
  47. v->y = m[1].x * vx + m[1].y * vy + y;
  48. }
  49. return t;
  50. }
  51.  
  52. #define CELL(b, x, y) ((b)[(x) + (y) * WIDTH])
  53.  
  54. int cell(board b, int x, int y)
  55. {
  56. if (0 <= x && x < WIDTH && 0 <= y && y < HEIGHT)
  57. return CELL(b, x, y);
  58. else
  59. return 1;
  60. }
  61.  
  62. int hits(board b, tetris t, int r, int x, int y)
  63. {
  64. t = transform(t, r, x, y);
  65. for (vector *v = t.v; v < t.v + 4; v++)
  66. if (cell(b, v->x, v->y))
  67. return 1;
  68. return 0;
  69. }
  70.  
  71. void put(board b, tetris t)
  72. {
  73. for (vector *v = t.v; v < t.v + 4; v++)
  74. CELL(b, v->x, v->y) = 1;
  75. }
  76.  
  77. void gameover(game *g)
  78. {
  79. printf("score: %d\n", g->score);
  80. exit(0);
  81. }
  82.  
  83. void newblock(game *g)
  84. {
  85. g->t = shapes[rand() % (sizeof(shapes) / sizeof(*shapes))];
  86. g->r = 0;
  87. g->x = WIDTH / 2;
  88. g->y = 0;
  89.  
  90. if (hits(g->b, g->t, g->r, g->x, g->y))
  91. gameover(g);
  92. }
  93.  
  94. void newgame(game *g)
  95. {
  96. bzero(g->b, sizeof(g->b));
  97. newblock(g);
  98. g->gravtime = g->gravinit;
  99. g->score = 0;
  100. }
  101.  
  102. void checkrows(game *g)
  103. {
  104. const int rowsize = WIDTH * sizeof(*g->b);
  105. int cleared = 0;
  106. for (int y = 0; y < HEIGHT; y++) {
  107. int x;
  108. for (x = 0; x < WIDTH && cell(g->b, x, y); x++) {}
  109. if (x == WIDTH) {
  110. cleared++;
  111. memmove(g->b + rowsize, g->b, y * rowsize);
  112. bzero(g->b, rowsize);
  113. }
  114. }
  115. g->score += cleared * cleared;
  116. }
  117.  
  118. void drop(game *g)
  119. {
  120. if (hits(g->b, g->t, g->r, g->x, ++g->y)) {
  121. put(g->b, transform(g->t, g->r, g->x, g->y - 1));
  122. checkrows(g);
  123. newblock(g);
  124. }
  125. }
  126.  
  127. void input(game *g, int key)
  128. {
  129. int dr = 0, dx = 0;
  130. switch (key) {
  131. case DOWN: drop(g); return;
  132. case UP: dr = +1; break;
  133. case LEFT: dx = -1; break;
  134. case RIGHT: dx = +1; break;
  135. }
  136.  
  137. int r = (g->r + dr) % 4, x = g->x + dx;
  138. if (!hits(g->b, g->t, r, x, g->y)) {
  139. g->r = r; g->x = x;
  140. }
  141. }
  142.  
  143. void tick(game *g)
  144. {
  145. if (--g->gravtime == 0) {
  146. g->gravtime = g->gravinit;
  147. drop(g);
  148. }
  149. }
  150.  
  151. void rect(color *fb, int pitch, int x, int y, int w, int h, color c)
  152. {
  153. for (fb += x + y * pitch, y = 0; y < h; y++, fb += pitch)
  154. for (x = 0; x < w; x++, fb++)
  155. *fb = c;
  156. }
  157.  
  158. void draw(game *g, color *fb, int size, int pitch, int cellwidth, int cellheight)
  159. {
  160. int w = cellwidth, h = cellheight;
  161.  
  162. bzero(fb, size);
  163.  
  164. tetris t = transform(g->t, g->r, g->x, g->y);
  165. for (vector *v = t.v; v < t.v + 4; v++)
  166. rect(fb, pitch, v->x * w, v->y * h, w, h, 0x00FF00);
  167.  
  168. for (int y = 0; y < HEIGHT; y++)
  169. for (int x = 0; x < WIDTH; x++) {
  170. color c = cell(g->b, x, y) ? 0x0000FF : 0x000000;
  171. rect(fb, pitch, x * w, y * h, w, h, c);
  172. }
  173. }
  174.  
  175. int main()
  176. {
  177. extern int getkey(), getfbsize(), getfbpitch();
  178. extern color *getfb();
  179.  
  180. game g;
  181. g.gravinit = 100;
  182. newgame(&g);
  183.  
  184. while (1) {
  185. input(&g, getkey());
  186. tick(&g);
  187. draw(&g, getfb(), getfbsize(), getfbpitch(), 10, 10);
  188. }
  189. return 0;
  190. }
Add Comment
Please, Sign In to add comment