62#define USAGE_MSG "Usage: ./life width height iterations\n"
63#define INVALID_ARGS_MSG \
64 "Invalid arguments: width, height must be positive, iterations " \
66#define MEM_ALLOC_FAIL_MSG "Memory allocation failed\n"
82int main(
int argc,
char *argv[]);
117int main(
int argc,
char *argv[]) {
118 int width, height, iterations;
119 Board *current_board_obj = NULL;
120 Board *next_board_obj = NULL;
130 if (!current_board_obj || !next_board_obj) {
131 write(STDERR_FILENO, MEM_ALLOC_FAIL_MSG,
sizeof(MEM_ALLOC_FAIL_MSG) - 1);
164 write(STDERR_FILENO, USAGE_MSG,
sizeof(USAGE_MSG) - 1);
168 *width = atoi(argv[1]);
169 *height = atoi(argv[2]);
170 *iterations = atoi(argv[3]);
172 if (*width <= 0 || *height <= 0 || *iterations < 0) {
173 write(STDERR_FILENO, INVALID_ARGS_MSG,
sizeof(INVALID_ARGS_MSG) - 1);
198 if (!new_board)
return NULL;
200 new_board->width = width;
201 new_board->height = height;
202 new_board->cells = (
char **)calloc(height,
sizeof(
char *));
203 if (!new_board->cells) {
210 new_board->cells[i] = (
char *)calloc(width,
sizeof(
char));
211 if (!new_board->cells[i]) {
214 free(new_board->cells[--i]);
216 free(new_board->cells);
224 new_board->cells[i][j] = DEAD;
246 if (!board_obj)
return;
248 if (board_obj->cells) {
249 while (i < board_obj->height) {
250 free(board_obj->cells[i]);
253 free(board_obj->cells);
281 pen_state->is_drawing = 0;
283 while ((bytes_read = read(STDIN_FILENO, &buffer, 1)) > 0) {
285 if (pen_state->y > 0) pen_state->y--;
286 }
else if (buffer ==
'a') {
287 if (pen_state->x > 0) pen_state->x--;
288 }
else if (buffer ==
's') {
289 if (pen_state->y < board_obj->height - 1) pen_state->y++;
290 }
else if (buffer ==
'd') {
291 if (pen_state->x < board_obj->width - 1) pen_state->x++;
292 }
else if (buffer ==
'x') {
293 pen_state->is_drawing = !pen_state->is_drawing;
296 if (pen_state->is_drawing) {
297 board_obj->cells[pen_state->y][pen_state->x] = ALIVE;
325 while (iter < iterations) {
327 while (y < current_board->height) {
329 while (x < current_board->width) {
332 if (current_board->cells[y][x] == ALIVE) {
333 if (live_neighbors < 2 || live_neighbors > 3) {
334 next_board->cells[y][x] =
337 next_board->cells[y][x] = ALIVE;
340 if (live_neighbors == 3) {
341 next_board->cells[y][x] = ALIVE;
343 next_board->cells[y][x] = DEAD;
373 for (dx = -1; dx <= 1; dx++) {
374 for (dy = -1; dy <= 1; dy++) {
375 if (dx == 0 && dy == 0)
continue;
380 if (nx >= 0 && nx < board_obj->width && ny >= 0 &&
381 ny < board_obj->height && board_obj->cells[ny][nx] == ALIVE) {
407 while (i < dest->height) {
409 while (j < dest->width) {
410 dest->cells[i][j] = src->cells[i][j];
436 while (i < board_obj->height) {
438 while (j < board_obj->width) {
439 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構造体)のメモリ確保と初期化