61#define USAGE_MSG "Usage: ./life width height iterations\n"
62#define INVALID_ARGS_MSG \
63 "Invalid arguments: width, height must be positive, iterations " \
65#define MEM_ALLOC_FAIL_MSG "Memory allocation failed\n"
81int main(
int argc,
char *argv[]);
116int main(
int argc,
char *argv[]) {
117 int width, height, iterations;
118 Board *current_board_obj = NULL;
119 Board *next_board_obj = NULL;
129 if (!current_board_obj || !next_board_obj) {
130 write(STDERR_FILENO, MEM_ALLOC_FAIL_MSG,
sizeof(MEM_ALLOC_FAIL_MSG) - 1);
163 write(STDERR_FILENO, USAGE_MSG,
sizeof(USAGE_MSG) - 1);
167 *width = atoi(argv[1]);
168 *height = atoi(argv[2]);
169 *iterations = atoi(argv[3]);
171 if (*width <= 0 || *height <= 0 || *iterations < 0) {
172 write(STDERR_FILENO, INVALID_ARGS_MSG,
sizeof(INVALID_ARGS_MSG) - 1);
197 if (!new_board)
return NULL;
199 new_board->width = width;
200 new_board->height = height;
201 new_board->cells = (
char **)calloc(height,
sizeof(
char *));
202 if (!new_board->cells) {
209 new_board->cells[i] = (
char *)calloc(width,
sizeof(
char));
210 if (!new_board->cells[i]) {
213 free(new_board->cells[--i]);
215 free(new_board->cells);
223 new_board->cells[i][j] = DEAD;
245 if (!board_obj)
return;
247 if (board_obj->cells) {
248 while (i < board_obj->height) {
249 free(board_obj->cells[i]);
252 free(board_obj->cells);
280 pen_state->is_drawing = 0;
282 while ((bytes_read = read(STDIN_FILENO, &buffer, 1)) > 0) {
284 if (pen_state->y > 0) pen_state->y--;
285 }
else if (buffer ==
'a') {
286 if (pen_state->x > 0) pen_state->x--;
287 }
else if (buffer ==
's') {
288 if (pen_state->y < board_obj->height - 1) pen_state->y++;
289 }
else if (buffer ==
'd') {
290 if (pen_state->x < board_obj->width - 1) pen_state->x++;
291 }
else if (buffer ==
'x') {
292 pen_state->is_drawing = !pen_state->is_drawing;
295 if (pen_state->is_drawing) {
296 board_obj->cells[pen_state->y][pen_state->x] = ALIVE;
324 while (iter < iterations) {
326 while (y < current_board->height) {
328 while (x < current_board->width) {
331 if (current_board->cells[y][x] == ALIVE) {
332 if (live_neighbors < 2 || live_neighbors > 3) {
333 next_board->cells[y][x] =
336 next_board->cells[y][x] = ALIVE;
339 if (live_neighbors == 3) {
340 next_board->cells[y][x] = ALIVE;
342 next_board->cells[y][x] = DEAD;
372 for (dx = -1; dx <= 1; dx++) {
373 for (dy = -1; dy <= 1; dy++) {
374 if (dx == 0 && dy == 0)
continue;
379 if (nx >= 0 && nx < board_obj->width && ny >= 0 &&
380 ny < board_obj->height && board_obj->cells[ny][nx] == ALIVE) {
406 while (i < dest->height) {
408 while (j < dest->width) {
409 dest->cells[i][j] = src->cells[i][j];
435 while (i < board_obj->height) {
437 while (j < board_obj->width) {
438 putchar(board_obj->cells[i][j]);
void free_board_obj(Board *board_obj)
ゲーム盤のメモリ解放
int main(int argc, char *argv[])
ライフゲーム・シミュレーターのエントリポイント
void initialize_board_from_input(Board *board_obj, PenState *pen_state)
標準入力からペン操作を受け取り、初期盤面を作成する
void simulate_life_obj(Board *current_board, Board *next_board, int iterations)
ライフゲームのルールに基づき、次世代の盤を計算する
static void copy_board_obj(Board *dest, const Board *src)
ある盤の状態を別の盤に完全に複製する
static int count_live_neighbors_obj(const Board *board_obj, int x, int y)
指定した座標の周囲(8近傍)にいる生存セル数をカウントする
void print_board_obj(const Board *board_obj)
盤面の現在の状態を標準出力に描画する
int parse_arguments(int argc, char *argv[], int *width, int *height, int *iterations)
コマンドライン引数のバリデーションとパース
Board * create_board_obj(int width, int height)
ゲーム盤(Board構造体)のメモリ確保と初期化