40行でライフゲーム


ニコニコ生放送「寝ながらライフゲームつくる」にて

Main

# include <Siv3D.hpp>

void Main()
{
    const Point size = Window::Size();
    Image image(size.x, size.y);
    DynamicTexture tex;

    std::array<std::vector<bool>, 2> worlds;
    const int num = size.x*size.y;
    worlds[0].resize(num);
    worlds[1].resize(num);

    std::array<Point, 8> neighbors = { { { -1, -1 }, { 0, -1 }, { 1, -1 }, { -1, 0 }, { 1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 } } };
    std::array<bool, 9> boneRule = { false, false, false, true, false, false, false, false, false };
    std::array<bool, 9> surviveRule = { false, false, true, true, false, false, false, false, false };
    std::array<std::array<bool, 9>, 2> rule = { boneRule, surviveRule };

    while (System::Update())
    {
        if (Input::MouseL.clicked)
            for (int y = 1; y < size.y - 1; ++y)
                for (int x = 1; x < size.x - 1; ++x)
                    worlds[0][y*size.x + x] = RandomBool(0.5);

        //update
        for (int y = 1; y < size.y - 1; ++y)
            for (int x = 1; x < size.x - 1; ++x)
                worlds[1][y*size.x + x] = rule[worlds[0][y*size.x + x]][std::count_if(neighbors.begin(), neighbors.end(), [&](const Point& v){return worlds[0][(v.y + y)*size.x + (v.x + x)]; })];

        worlds[0].swap(worlds[1]);      

        //draw
        for (int y = 1; y < size.y - 1; ++y)
            for (int x = 1; x < size.x - 1; ++x)
                image[y][x] = ColorF(0.0, worlds[0][y*size.x + x], 0.0);

        tex.tryFill(image);
        tex.draw();
    }
}