4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ライフゲームAdvent Calendar 2017

Day 25

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

Posted at

#概要
ライフゲーム 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」ですが、大変シンプルなアルゴリズムですので私のような万年初心者やプログラムが好きだけど本業でやっていない人のための一つの目標として存在意義は揺るがないと考えています。見ていて飽きないし、きっとプログラマなら通じる共通の話題だと思うし。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?