/*
988 名前：デフォルトの名無しさん [sage]： 2012/02/04(土) 20:06:33.75
[1] 授業単元：Ｃ言語
[2] 問題文　初期状態をファイルより読み込みライフゲームを実行しなさい
[3] 環境
　[3.1] OS： Windows７
　[3.2] コンパイラ名とバージョン： VisualStudio2010
　[3.3] 言語： C言語
[4] 期限： 2/5
[5] その他の制限： ライフゲームの作成です。セルの生死を判定するための条件付けをうまく記述することができません。
他にもツッコミどころ満載ですがどなたか指摘していただけると助かります。お願いします
http://i...content-available-to-author-only...e.com/LFPu6
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define FieldSize 20
#define TimeMax 20

#define ALIVE " O "
#define DEAD " . "

/*フィールドの初期化 (ファイルの読み込み)*/
void
init_field(int field[FieldSize][FieldSize], char *fname)
{
    int i, j;
    FILE *fp;

    fp = fopen(fname, "r");
    if (fp == NULL) {
        printf("init_field(): Cannot open \"%s\"\n",fname);
        exit(1);
    }

    for (i=0;i<FieldSize;i++) {
        for (j=0;j<FieldSize;j++) {
            fscanf(fp,"%d ", &field[i][j]);
        }
    }
    fclose(fp);
}

int count(int i, int j, int field[FieldSize][FieldSize]){
    int move_horizontal, move_vertical;
    int sum;

    sum=0;
    for(move_vertical=-1;move_vertical<=1;move_vertical++){
        for(move_horizontal=-1;move_horizontal<=1;move_horizontal++){
            if (move_vertical == 0 && move_horizontal == 0)
                continue;
            sum += field[i + move_vertical][j + move_horizontal];
        }
    }
    return sum;
}

void update_field(int field[FieldSize][FieldSize])
{
    int i, j;
    int around = 0;
    int new_field[FieldSize][FieldSize];

    printf("field = %p in update_field()\n", field);

    memset(new_field, 0, sizeof(new_field));

    for(i=0;i<FieldSize;i++){
        for(j=0;j<FieldSize;j++){
            if (i == 0 || j == 0 ||
                i == FieldSize - 1 ||
                j == FieldSize - 1)
                continue;

            around = count(i, j, field);
            if (field[i][j] == 0){
                // 死んでいる状態
                if (around == 3) {
                    // 誕生
                    new_field[i][j] = 1;
                }
            }
            else{
                // 生きている状態
                if (around == 2 || around == 3){
                    // 生存
                    new_field[i][j] = 1;
                }
                else if (around <= 1) {
                    // 過疎
                    new_field[i][j] = 0;
                }
                else if (around >= 4) {
                    // 過密
                    new_field[i][j] = 0;
                }
            }
        }

    }

    /*
    for(i = 0;i < 20;i++){
        for(j = 0;j < 20;j++){
            field[i][j] = new_field[i][j];
        }
    }
    */
    memcpy(field, new_field, sizeof(new_field));
}


void
display(int field[FieldSize][FieldSize])
{
    int i,j;

    printf("   ");
    for(j=0;j<20;j++)
        printf("%3d", j);
    printf("\n");

    for(i=0;i<20;i++){
        printf("%3d ", i);
        for(j=0;j<20;j++){
            if (field[i][j] == 0) {
                printf("%s", DEAD);
            }
            else{
                printf("%s", ALIVE);
            }
        }
        printf("\n");
    }
}

int main(int argc, char *argv[])
{
    int t;
    int field[FieldSize][FieldSize];

    if(argc!=2){
        printf("実行方法 : ./a.out 初期状態のファイル\n");
    }

    //system("clear");
    printf("field = %p in main()\n", field);
    init_field(field, argv[1]);
    printf("field =\n");
    display(field);
    printf("\n");

    //sleep(1);
    system("clear");

    for(t=0;t<TimeMax;t++){
        printf("t = %d\n", t);
        update_field(field);
        display(field);
        sleep(1);
        system("clear");
    }

    return 0;
}