C#
Xaml
UWP
StoreApp
lifegame

UWPアプリ(Xaml+C#) ライフゲーム 作成・公開

概要

ライフゲーム Advent Calendar 2017の23日目25日目の記事です。
23日間に合わず23時55分くらいに空いていた25日に延期しました。本当にごめんなさい。しかもこんな出来で。orz
C#+WPFでMVVMにライフゲームを作ってみました。
レベル低いですがお手柔らかに...お願いします。

ソースコード

工夫した点1:セルの状態はenumにした

セルの状態
enum StatusLife : int { Dead, Live };

工夫した点2:トーラスワールドを実現

1.セルのフィールド
        List<Windows.UI.Xaml.Shapes.Rectangle> list_rect;
        StatusLife[,] field;
        int N_x = 30;
        int N_y = 20;
        int cell_width = 25;
        int cell_height = 25;

以下でLifegameのアルゴリズムの計算で生死判定をしています。(「計算アルゴリズム核心部」)
トーラス世界の実現で悩みどころは端の処理ですが、私は

  • 端を特別扱いしたくない
  • 割り算をしたくない

という方針から、実際のフィールドよりも(準備:計算用フィールドへ移す)上下左右に1つずつ広い計算用のフィールドを作成し、実フィールドの端の値を計算用フィールドの端へコピーして計算フィールドを準備するという方法をとりました。
実際計算量がこれによって有利に働いているのかはまだしっかり考察できていません。しかもこの準備段階で思いっきり端を特別扱いしています。

計算アルゴリズム核心部
//外周1マスは端をつなげるための領域である
        //return:field[size_x,size_y]
        private StatusLife[,] calc_cell_1step(StatusLife[,] field, int size_x, int size_y)
        {
            StatusLife[,] f_calc = FieldToFieldCalc(field, size_x, size_y);
            StatusLife[,] result = new StatusLife[size_x, size_y];
            int sum = 0;
            int x = 1, y = 1;
            for (y = 1; y < size_y + 1; y++)
            {
                for (x = 1; x < size_x + 1; x++)
                {
                    sum = (int)f_calc[x - 1, y - 1] + (int)f_calc[x, y - 1] + (int)f_calc[x + 1, y - 1] + (int)f_calc[x + 1, y] + (int)f_calc[x - 1, y] + (int)f_calc[x + 1, y + 1] + (int)f_calc[x, y + 1] + (int)f_calc[x - 1, y + 1];
                    result[x - 1, y - 1] = LiveLife(f_calc[x, y], sum);
                }
            }
            return result;
        }
準備
//fieldから計算フィールドへうつす。端はつながってる形である
        private StatusLife[,] FieldToFieldCalc(StatusLife[,] field, int size_x, int size_y)
        {
            StatusLife[,] f_calc = new StatusLife[size_x + 2, size_y + 2];
            //真ん中
            for (int y = 0; y < size_y; y++)
            {
                for (int x = 0; x < size_x; x++)
                {
                    f_calc[x + 1, y + 1] = field[x, y];
                }
            }
            //4隅
            f_calc[0, 0] = field[size_x - 1, size_y - 1];           //左上
            f_calc[size_x + 1, 0] = field[0, size_y - 1];           //右上
            f_calc[size_x + 1, size_y + 1] = field[0, 0];            //右下
            f_calc[0, size_y + 1] = field[size_x - 1, 0];            //左下

            //外枠直線
            //上下
            for (int x = 0; x < size_x; x++)
            {
                f_calc[x, 0] = field[x, size_y - 1];
                f_calc[x, size_y + 1] = field[x, 0];
            }

            //左右
            for (int y = 0; y < size_y; y++)
            {
                f_calc[0, y] = field[size_x - 1, y];
                f_calc[size_x + 1, y] = field[0, y];
            }
            return f_calc;
        }

src

xaml Gist
cs Gist

公開先

ちなみにこのクソアプリはWindowsStoreで公開しています。しかも広告付きで。
アップデート、していけたらいいな。
TheLifeGame

プログラマにとっての意義

今となっては特に目的はない「LifeGame」ですが、大変シンプルなアルゴリズムですので私のような万年初心者やプログラムが好きだけど本業でやっていない人のための一つの目標として存在意義は揺るがないと考えています。見ていて飽きないし、きっとプログラマなら通じる共通の話題だと思うし。