§ Демон-станция

68b957e4862de917cf78e2caee5debdd.png
1#include <qblib.c>
2
3#define SAND(x,y,dx,dy) buf[1][x+(dx)][y+(dy)] = buf[0][x][y]; buf[1][x][y] = 0
4
5float timer;
6int buf[2][320][200];
7
8// Инициализация буфера, рисование препятствий и начального состояния
9void init() {
10
11    // Инициализация
12    for (int i = 0; i < 2; i++)
13    for (int y = 0; y < 200; y++)
14    for (int x = 0; x < 320; x++)
15        buf[i][x][y] = 0;
16
17    // Генератор блока
18    for (int y = 150; y < 200; y++) for (int x = 40; x < 100; x++) buf[1][x][y] = 7;
19    for (int y = 100; y < 108; y++) for (int x = 190; x < 250; x++) buf[1][x][y] = 7;
20
21    // Воронка
22    for (int x = 0; x < 74; x++) {
23
24        buf[1][75 +  x][40] = 7;
25        buf[1][225 - x][40] = 7;
26        buf[1][110 + x][50] = 7;
27        buf[1][75 + x][40 + x] = 7;
28        buf[1][225 - x][40 + x] = 7;
29    }
30
31    // Заполняем песком
32    for (int y = 52; y < 120; y++)
33    for (int x = 75; x < 225; x++)
34        if ((x - y - 35 > 0) && (265 - x - y > 0))
35            buf[1][x][y] = rand()&1 ? 14 : 6;
36
37}
38
39// Генерация нового песка
40void sand() {
41
42    for (int k = 0; k < 32; k++) {
43
44        int cx = (int)(140 + sin(timer)*100) + rand()%64 - 32;
45        int cl = 0;
46
47        switch (rand() % 2) {
48            case 0: cl = 6; break;
49            case 1: cl = 14; break;
50        }
51
52        // Разрешенные области автоматического песка
53        if (cx < 80 || cx > 210 || (cx > 140 && cx < 160))
54            buf[1][cx][0] = cl;
55    }
56
57    timer += 0.1;
58}
59
60// Клеточный автомат
61void step() {
62
63    for (int y = 0; y < 199; y++)
64    for (int x = 1; x < 319; x++) {
65
66        int p = buf[0][x][y];
67
68        // Информация о клетках снизу
69        int a = buf[0][x-1][y+1];
70        int b = buf[0][x  ][y+1];
71        int c = buf[0][x+1][y+1];
72
73        // Движение песка
74        if (p == 6 || p == 14) {
75
76            // Под песчинкой ничего нет
77            if (b == 0) { SAND(x,y,0,1); }
78            // Нет слева или справа (и не мешают стены)
79            else {
80
81                int can_lf = 0, can_rt = 0, can_move = 0;
82
83                if (a == 0 && buf[0][x-1][y] == 0) can_lf = 1;
84                if (c == 0 && buf[0][x+1][y] == 0) can_rt = 1;
85
86                // Если песок может двинуться влево и вправо
87                if (can_lf && can_rt) can_move = rand()&2 ? 1 : -1;
88                else if (can_lf)      can_move = -1;
89                else if (can_rt)      can_move = 1;
90
91                // Если песок может двинуться. Может и не двинуться с вероятность 25%
92                if (can_move != 0 && (rand()%4 != 0) ) { SAND(x,y,can_move,1); }
93            }
94
95        }
96    }
97
98    // Перенести
99    for (int y = 0; y < 200; y++)
100    for (int x = 0; x < 320; x++) {
101        buf[0][x][y] = buf[1][x][y];
102        pset(x, y, buf[0][x][y]);
103    }
104}
105
106int main(int argc, char* argv[]) {
107
108    screen(13);
109    init();
110
111    while (sdlevent(EVT_REDRAW)) {
112
113        sand();
114        step();
115    }
116
117    return 0;
118}