challenge ライフゲーム

セルオートマトンに関するお題です. 
2次元タイプの'ライフゲーム'を実装して下さい. 
初期値としては10行10列程度の格子上の平面に0.3程度の人口(?)密度を考え, 
末端はループするようにして下さい. (例: 座標[-1, -1] = [10, 10])

それだけだと簡単すぎると思われる方は, 
過密状態で間引きが発生するような機能を組み込んで下さい. 
間引きは, 少なくともその後の1時間ステップにおける死亡率が, 
それをしなかった場合よりも小さくなれば結構です. 
(死亡率の最小化は複雑性が高すぎる感がありますし. )
サンプル:
t = 0
[ ][*][ ][ ][ ][ ][*][*][*][ ]
[ ][ ][ ][ ][*][ ][ ][*][*][ ]
[ ][ ][ ][*][ ][ ][*][ ][*][ ]
[*][ ][*][*][ ][ ][*][ ][ ][ ]
[ ][*][ ][ ][ ][ ][ ][ ][*][ ]
[*][ ][ ][ ][*][ ][*][*][ ][*]
[ ][*][ ][ ][ ][ ][*][ ][ ][ ]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*]
[*][ ][ ][ ][ ][ ][*][ ][ ][*]
[ ][ ][ ][ ][*][*][ ][ ][*][ ]
t = 1
[ ][ ][ ][ ][*][ ][ ][ ][ ][*]
[ ][ ][ ][ ][ ][*][ ][ ][ ][*]
[ ][ ][*][ ][*][*][*][ ][*][*]
[ ][*][ ][*][ ][ ][ ][ ][ ][*]
[ ][ ][*][*][ ][*][*][ ][*][ ]
[ ][*][ ][ ][ ][*][*][ ][*][*]
[ ][ ][ ][ ][ ][*][*][*][*][*]
[ ][ ][ ][ ][ ][ ][ ][ ][ ][*]
[*][ ][ ][ ][ ][*][ ][ ][*][ ]
[*][ ][ ][ ][ ][ ][ ][ ][ ][ ]

Posted feedbacks - D

普通に。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import std.string, std.conv, std.contracts,
       std.random, std.stdio, std.c.time;

class Field {
    private uint width_, height_;
    private bool[] data_;
    
    this(uint width, uint height) {
        this.width_ = width;
        this.height_ = height;
        this.data_ = new bool[width * height];
    }
    
    const uint width() { return this.width_; }
    const uint height() { return this.height_; }
    
    const bool opIndex(uint x, uint y)
        in {
            assert(x < this.width);
            assert(y < this.height);
        }
        body {
            return this.data_[this.width * y + x];
        }
        
    bool opIndexAssign(bool value, uint x, uint y)
        in {
            assert(x < this.width);
            assert(y < this.height);
        }
        body {
            return this.data_[this.width * y + x] = value;
        }
    
    const string toString() {
        const len = (3 * this.width) * this.height + newline.length * (this.height - 1);
        auto s = new char[len], idx = 0;
        foreach(y; 0 .. this.height) {
            foreach(x; 0 .. this.width) {
                s[idx .. idx + 3] = this[x, y] ? "[*]" : "[ ]";
                idx += 3;
            }
            if(idx != len) {
                s[idx .. idx + newline.length] = newline;
                idx += newline.length;
            }
        }
        return assumeUnique(s);
    }
    
    const Field nextGeneration() {
        const w = this.width, h = this.height;
        Field f = new Field(w, h);
        foreach(y; 0 .. h) {
            foreach(x; 0 .. w) {
                int c;
                int l = (x + w - 1) % w, r = (x + 1) % w,
                    u = (y + h - 1) % h, d = (y + 1) % h;
               
                if(this[l, u]) c++; if(this[x, u]) c++; if(this[r, u]) c++;
                if(this[l, y]) c++;                     if(this[r, y]) c++;
                if(this[l, d]) c++; if(this[x, d]) c++; if(this[r, d]) c++;
                
                if(c == 3 || this[x, y] && c == 2)
                    f[x, y] = true;
            }
        }
        return f;
    }
}

void main(string[] args) {
    if(args.length < 3) return;
    auto width = to!(uint)(args[1]), height = to!(uint)(args[2]);
    
    auto f = new Field(width, height);
    auto rgen = Random(unpredictableSeed);
    foreach(y; 0 .. height) {
        foreach(x; 0 .. width) {
            f[x, y] = uniform!(int)(rgen, 0, 10) < 3;
        }
    }
    uint gen = 0;
    while(true) {
        writeln("Generation ", ++gen);
        writeln(f);
        writeln("");
        f = f.nextGeneration;
        msleep(100);
    }
}

Index

Feed

Other

Link

Pathtraq

loading...