昨日告知しましたように、Embarcadero C++BCCS keltonで開発したCellのC#版(ユーザーもアバターで参加できるのでVersion 2.0としましたが...)Cells for C#がどうもできあがったようなので、これについて書いてみようかと思います。

 

最初にこのコンセプトでプログラムを作ろうとしたとき時の【Cell】シリーズ始動...でも書いていますが、

 

(1)プログラムの本質はライフゲームです。セル・オートマトンと言い換えてもよいかと思います。(Cellとか、Cellsf or C#の名称もそこから来ています。)

 

(2)ただ、よく知られたライフゲーム

(このブログでも2023年に紹介した、矢張りEmbarcadero C++とBCCS keltonで開発したもの)

 

は数学的で、静的に集合離散(過密過疎)を表したものであり、その生成、消滅ルールが結構単純であることが不満でした。

 

(3)それで我々が住む「人間社会」に似せた「動的」な変化を与えたらどうなるか、見てみたいと、と考えました。この「動的」の意味は「単に『主役である存在の単位、セル』が『動く(Mobility)』だけではなく、セルの行動様式がセルの行動や、セル間のコミュニケーションにより『社会的に変化』してゆく」ことで、

 

同じ条件でスタートしても結果が常に異なる

 

ようにしたいと考えました。

 

(4)その結果、オリジナル版のブログで書いたように、

 

***仕様メモ***
1.新しいコンセプトのライフゲーム
2.オブジェクトは"world"と"cell"で、"world"がゲームの「場」、"cell"が「場」で誕生、生存、死亡する生命体プレーヤー
3."world"クラスは80 x 40(ピクセルで1280 x 640)の広さを持つ
4.従来のライフゲームは植物の様に移動せず、過密、過疎で生態系が影響を受けたが、"cell"は動物をイメージして移動する。
5."cell"は誕生と共に別スレッドで個別に行動し、"world"内を移動する。
6."cell"の特徴(DNAをイメージ)として、「年齢」、「生命力」、「攻撃力」、「防御力」、「生殖力」etcを持つ。
7."cell"が移動して他のcellと隣接すると、「愛着」または「攻撃性」の特性により、交尾したり、闘争になったりする。
8.死亡要因は「寿命」、攻撃による「生命力の枯渇」
9.「栄養」や「水分」の摂取をどうするか、「病気」、「事故」をどうするか検討中

 

昨日はこう(「Cell種」、「人種」は即ち生物学的な"race")書きましたが、チト「参●党」を想起してしまうので政治色が強くなりすぎるのと、意図するものはより「社会、文化的集団」である「部族-"tribe"」であったことから、本日「(しかし、往々にして「部族」も「種」の違いが起源となりうるので)種族-"tribe"」という概念に変えました。

 

今度は「愛着性」、「敵対性(攻撃性<hostility>から変更しました)」という特性の契機としてこの「種族」が使えることを思いつき、また同時に「種族」を超えた行動を許可するパラメーターとして「異種族婚(Inter-tribe marriage)許可」の概念も、本日取り入れることにしました。

 

という「社会的存在」を想定し、その概念はCells for C#でも承継しております。以下にCells for C#におけるCellクラスのデータ部のみ掲載します。

 

    /////////////////
    //Cellクラス定義
    /////////////////

    public class Cell
    {
        ///////////////////////
        //ゲーム関係フィールド
        //     定数定義 (解説:C#はCやC++の"define"が使えないので、このように定数を定義しています。namespace共通で宣言できるとよいのですが、クラスごとに設定する必要があります。)
        ///////////////////////

        int Max_Left = 17520;                    //セルの最長余命(単位1時間、2年で24hours x 365days x 2years = 17,520)
        int Max_Life = 4320;                    //セルの最大初期エネルギー(半年で24hours x 180days = 4320)
        const int Max_Tribe = 4;                //現在はCell-P, Cell-B, Cell-G, Cell-D(死亡)
        const int Max_Dir = 8;                   //↑:0、↗:1、→:2、↘:3、↓:4、↙:5、←:6、↖:7
        const int Not_Found = -1;                //Find_***処理用
        int Living_Cost = 24;                    //【調整項目】余命(Left)、生命力(Life)の消耗時間
        /////////////////////////////////
        //メンバーフィールドとプロパティ
        /////////////////////////////////

        //生存フラグ
        public bool Alive {get; private set;}    //生存(true)、死亡(false)
        //繁殖フラグ
        public bool Intmarg {get; set;}            //異種族間婚の許可
        //位置
        private Point Location;                    //Cellの位置(World内の位置座標)
        private int[] m_Around = new int[8];    //環境情報フィールド(Aroundの実体)
        public int[] Around                        //Cell周囲の存在(野原:0、山:1、河川:2、食物:3、セル:4 + ID)
        {    get
            {
                return m_Around;
            }
            private set
            {
                m_Around = value;
            }
        }
        //性格系
        public int Affection {get; set;}        //愛着性
        public int Hostility {get; set;}        //敵対性
        //能力系
        public int Left {get; set;}                //余命(Max_Left: 単位1時間、2年で24hours x 365days x 2years = 17,520)
        public int Life {get; set;}                //生命力(Max_Life: 半年分で24hours x 180days = 4320)
        public int Power {get; private set;}    //攻撃力(Lifeによる)
        public int Defense {get; private set;}    //防御力(LifeとLeft<経験>による)
        public int Fertility {get; private set;}//生殖力(Leftによる)
        //識別系
        public int ID {get; set;}                //Cellのゼロベースの固有番号
        public int Tribe {get; set;}            //種族(ピンク:0、ブルー:1、グリーン:2、モノ(死亡):3の4色)
        //運動系
        public int Dir {get; set;}                //Cellの移動方向(↑:0、↗:1、→:2、↘:3、↓:4、↙:5、←:6、↖:7)

        ///////////////////
        //メンバーメソッド
        ///////////////////
        (以下略)

 

そしてこのセルという生命体が社会活動を行う「場」がWorldであり、矢張りデータ部分だけ紹介しておきます。

 

    //////////////////
    //Worldクラス定義
    //////////////////

    public class World : PictureBox

//解説:オリジナル版では描画やUIはメインウィンドウで行っていましたが、C#版はPictureBoxをベースとしてコントロール化しています。
    {
        ///////////////////////
        //定数定義(変更不可)
        ///////////////////////

        const int Wld_Width = 80;                //Worldの幅(セル数)
        const int Wld_Height = 40;                //Worldの高さ(セル数)
        const int Max_Population = Wld_Width * Wld_Height / 2;    //「世界」に棲めるセルの最大人口
        const int Max_Tribe = 4;                //現在はCell-P, Cell-B, Cell-G, Cell-D(死亡)
        const int Max_Dir = 8;                    //↑:0、↗:1、→:2、↘:3、↓:4、↙:5、←:6、↖:7
        const int Not_Found = -1;                //Find_***処理用
        /////////////////////////////////
        //ゲーム関係フィールド
        /////////////////////////////////

        public static Random rand;                //乱数(World、Cell共通-解説:これもC#の仕様の為、この静的変数を共通の乱数発生拠点にしました。)
        private bool Gameover = false;            //ゲーム終了サイン
        private string Message;                    //ゲームオーバーの際に、呼び出しユーザーに返すメッセージ
        private int Ini_pop = 0;                //開始時のセル数(0で初期化)
        private List<Cell> CellList = new List<Cell>();                //セルリスト
        private int[] Tribe_Status = new int[4];                    //Cell-P, Cell-B, Cell-G, Cell-Dの状況を記録(0で初期化)
        private char[] Map = new char[Wld_Width * Wld_Height];        //「文字」地形図(野原:' '、山:'^'、河川:'~'、食物:'O')
        private int[] PrevMap = new int[Wld_Width * Wld_Height];    //直前の「論理」地形図(野原:0、山:1、河川:2、食物:3、セル:4 + ID)
//解説:「世界」のマップは「(文字ベースの)物理マップ」と「論理マップ」の二つがあります。

        public int MyID = Not_Found;            //アバターCellのID(解説:Ver 2.0で追加しました。)
        //【調整項目】定数定義(変更可)
        int Max_Param = 100;                    //Cellの属性の最大値
        int Increase = 1;                        //パラメーターの増加幅
        int Decrease = -1;                        //パラメーターの減少幅
        ///////////////////////
        //描画関係フィールド
        ///////////////////////

        //地形描画用Bitmap「野原:0」、「山:1」、「河川:2」、「食物:3」
        Bitmap[] Terrain_Bmp = new Bitmap[Max_Tribe];
        //Cell描画用Bitmap「ピンク:0」、「ブルー:1」、「グリーン:2」、「モノ(死亡):3」+ Cell-Me(Avatar)
        Bitmap[] Cell_Bmp = new Bitmap[Max_Tribe + 1];
        //PictrueBox描画関係プロパティ
        public Bitmap Canvas {set; get;}        //仮想画面ビットマップ
        public Graphics gHandle {set; get;}        //仮想画面のグラフィック

//解説:↑で述べたように、オリジナルではメインウィンドウでCANVASクラスとCBITMAPクラスを使って描画していましたが、C#版ではコントロール化して、ここで描画しています。

 

このように、「『世界の中で生成された性格や能力が一つづつ異なるセル』が、放浪しつつ、他セルと遭遇して、ライフサイクルに応じて性格や能力を変化させつつ、社会を形成、発展、破壊してゆく物語」を作りたかったのでした。

 

このコンセプトはCells for C#でも全く変わりありません。

 

次回は最初に行ったC#へ単純移植する際の失敗談でも披露しましょうかね?