Untitled
#include <stdio.h> #include <stdlib.h> #include <termios.h> #include <unistd.h> #include <fcntl.h> void clear_terminal() { printf("\033[0d\033[2J"); } void wait(int n) { usleep(n * 1000); // Ожидание в миллисекундах } char getch(void) { char buf = 0; struct termios old = {0}; if (tcgetattr(0, &old) < 0) perror("tcgetattr()"); old.c_lflag &= ~(ICANON | ECHO); old.c_cc[VMIN] = 1; old.c_cc[VTIME] = 0; if (tcsetattr(0, TCSANOW, &old) < 0) perror("tcsetattr ICANON"); if (read(0, &buf, 1) < 0) perror("read()"); old.c_lflag |= ICANON | ECHO; if (tcsetattr(0, TCSADRAIN, &old) < 0) perror("tcsetattr ~ICANON"); return buf; } int create_field(int ***field, int width, int height) { *field = calloc(height, sizeof(int*)); if (*field == NULL) { return 0; } for (int y = 0; y < height; ++y) { (*field)[y] = calloc(width, sizeof(int)); if ((*field)[y] == NULL) { while (--y >= 0) free((*field)[y]); free(*field); return 0; } } return 1; } void free_field(int ***field, int height) { if (*field != NULL) { for (int y = 0; y < height; ++y) { free((*field)[y]); } free(*field); *field = NULL; } } void render(int **field, int width, int height) { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { printf("%c", field[y][x] ? '*' : ' '); } printf("\n"); } } void update(int ***field, int width, int height) { int **next_state = calloc(height, sizeof(int*)); for (int y = 0; y < height; ++y) { next_state[y] = calloc(width, sizeof(int)); for (int x = 0; x < width; ++x) { int alive_neighbors = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 && j == 0) continue; int nx = (x + i + width) % width; int ny = (y + j + height) % height; alive_neighbors += (*field)[ny][nx]; } } int cell = (*field)[y][x]; next_state[y][x] = alive_neighbors == 3 || (cell && alive_neighbors == 2); } } for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { (*field)[y][x] = next_state[y][x]; } free(next_state[y]); } free(next_state); } void get_input(int *n) { char ch = getch(); switch(ch) { case 'q': exit(0); case 'a': *n = (*n > 100 ? *n - 100 : *n); break; case 'z': *n += 100; break; } } int main(void) { int **field = NULL; int width = 80, height = 25, n = 1000; if (!create_field(&field, width, height)) { fprintf(stderr, "Ошибка создания поля.\n"); return EXIT_FAILURE; } while (1) { clear_terminal(); get_input(&n); update(&field, width, height); render(field, width, height); wait(n); } free_field(&field, height); return 0; }
Leave a Comment