Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h> // нужно для рандома. Удалить, когда будет готова загрузка из файлов
- #include <unistd.h>
- #define TRUE 1
- #define FALSE 0
- #define WIDTH 80
- #define HEIGHT 25
- #define ALIVE 'O'
- #define DEAD ' '
- #define MIN_NEIGHBORS_TO_SURVIVE 2 // Мин. соседей для выживания (≥ 2)
- #define MAX_NEIGHBORS_TO_SURVIVE 3 // Макс. соседей для выживания (≤ 3)
- #define NEIGHBORS_TO_REBORN 3 // Точно 3 соседа для рождения
- #define MAX_SPEED_RATIO 3 // максимум ускоряемся до 3x
- #define MIN_SPEED_RATIO 0.25f // минимум замедляемся до 0.25x
- #define SPEED_RATIO_STEP 0.25f // шаг ускорения
- #define BASE_GENERATION_DELAY 100000
- void initialize_grid_randomly(char grid[HEIGHT][WIDTH]); // временное рандомное заполнение. Удалить, когда будет готова загрузка из файлов
- void load_grid_from_file(char grid[HEIGHT][WIDTH]);
- void draw_grid(char grid[HEIGHT][WIDTH]);
- void update_grid(char grid[HEIGHT][WIDTH]);
- int get_alive_neighbors_count(char grid[HEIGHT][WIDTH], int x, int y);
- char update_cell_status(char current_status, int neighbors_count);
- void update_input(int *need_simulate, float *speed_ratio);
- int main() {
- char grid[HEIGHT][WIDTH];
- initialize_grid_randomly(grid); // временное рандомное заполнение. Удалить, когда будет готова загрузка из файлов
- // load_grid_from_file(grid);
- float speed_ratio = 1;
- int need_simulate = TRUE;
- while (need_simulate == TRUE) {
- draw_grid(grid);
- update_grid(grid);
- int generation_delay = (int) (speed_ratio * BASE_GENERATION_DELAY);
- usleep(generation_delay);
- update_input(&need_simulate, &speed_ratio);
- }
- return 0;
- }
- void initialize_grid_randomly(char grid[HEIGHT][WIDTH]) { // временное рандомное заполнение. Удалить, когда будет готова загрузка из файлов
- srand(time(0));
- for (int y = 0; y < HEIGHT; y++) {
- for (int x = 0; x < WIDTH; x++) {
- grid[y][x] = (rand() % 5 == 0) ? ALIVE : DEAD;
- }
- }
- }
- void load_grid_from_file(char grid[HEIGHT][WIDTH]) {
- // TODO: Сделать логику загрузки поля из файла
- }
- void update_input(int *need_simulate, float *speed_ratio) {
- // TODO: Если нажат Space, то need_simulate = false
- // TODO: Если нажат A, то *speed_ratio += SPEED_RATIO_STEP
- // TODO: Если нажат Z, то *speed_ratio -= SPEED_RATIO_STEP
- if (*speed_ratio < MIN_SPEED_RATIO) {
- *speed_ratio = MIN_SPEED_RATIO;
- } else if (*speed_ratio > MAX_SPEED_RATIO) {
- *speed_ratio = MAX_SPEED_RATIO;
- }
- }
- void draw_grid(char grid[HEIGHT][WIDTH]) {
- printf("\n\n===================================================\n\n");
- for (int y = 0; y < HEIGHT; y++) {
- for (int x = 0; x < WIDTH; x++) {
- printf("%c", grid[y][x]);
- }
- printf("\n");
- }
- }
- int get_alive_neighbors_count(char grid[HEIGHT][WIDTH], int x, int y) {
- int alive_neighbors_count = 0;
- for (int delta_y = -1; delta_y <= 1; delta_y++) {
- for (int delta_x = -1; delta_x <= 1; delta_x++) {
- // Пропускаем текущую клетку
- if (delta_x == 0 && delta_y == 0)
- continue;
- int neighbor_x = x + delta_x;
- int neighbor_y = y + delta_y;
- // Проверка границ (тороидальная вселенная). Благодаря этому мир "зациклен" по краям
- if (neighbor_x < 0) neighbor_x = WIDTH - 1;
- if (neighbor_x >= WIDTH) neighbor_x = 0;
- if (neighbor_y < 0) neighbor_y = HEIGHT - 1;
- if (neighbor_y >= HEIGHT) neighbor_y = 0;
- if (grid[neighbor_y][neighbor_x] == ALIVE)
- alive_neighbors_count++;
- }
- }
- return alive_neighbors_count;
- }
- void update_grid(char grid[HEIGHT][WIDTH]) {
- char updated_grid[HEIGHT][WIDTH];
- for (int y = 0; y < HEIGHT; y++) {
- for (int x = 0; x < WIDTH; x++) {
- int neighbors = get_alive_neighbors_count(grid, x, y);
- updated_grid[y][x] = update_cell_status(grid[y][x], neighbors);
- }
- }
- for (int y = 0; y < HEIGHT; y++) {
- for (int x = 0; x < WIDTH; x++) {
- grid[y][x] = updated_grid[y][x];
- }
- }
- }
- // TODO: подумать, как это отрефакторить, мб стоит разбить этот метод на подметоды CanDie и CanReborn
- char update_cell_status(char current_status, int neighbors_count) {
- char new_status = current_status;
- int should_die = current_status == ALIVE &&
- (neighbors_count < MIN_NEIGHBORS_TO_SURVIVE ||
- neighbors_count > MAX_NEIGHBORS_TO_SURVIVE);
- int should_reborn = current_status == DEAD && neighbors_count == NEIGHBORS_TO_REBORN;
- if (should_die == TRUE) {
- new_status = DEAD;
- } else if (should_reborn == TRUE) {
- new_status = ALIVE;
- }
- return new_status;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement