ポスト「ゲームの類似物ライフ」-Evoの続きで、 Evoで使用される「遺伝子言語」のコマンドのより詳細な説明を行い、このゲームで個人を横断する方法についての私の考えを共有したいと思います。
遺伝暗号
Evoの個人の遺伝暗号は、ほぼ無制限の長さの一連のバイトです。 さらに、各バイトはセルオートマトンのコマンドとして扱われます。 マシンには、コマンドとメモリの2つのテープがあります。 したがって、2つのポインターcmd_ptrおよびmem_ptrがあります。 動物のRAMとして、1バイト(8ビット)の次元を持つ変数データが使用されます。
現在、次のコマンドがあります。
- 「遺伝」コードの実行を制御する9チーム:
- nop-何もしない
- move_cmd_left-コマンドポインターを左に移動する
- move_cmd_right-コマンドポインターを右に移動する
- jump_to-コマンドポインターをX位置だけ右にシフトします(コマンドに続くバイトは符号付き文字として扱われます。つまり、負の値はポインターを左にシフトします)
- jump_to_ifz - jump_toと同じですが、 データの値== 0
- jump_to_ifnz - jump_toと同じですが、 dataの値を指定します!= 0
- startはnopと同じですが、いくつかの孤立した部分の始まり(関数の始まり)のラベルにすぎません
- restart -cmd_ptrを0にリセットします
- end-関数の終わり。テープのさらに下を見て、実行を継続する開始ラベルを探します(ラベルがない場合、 cmd_ptr = 0 )
- 家畜が自分の周りを見ることができる8つのコマンド(結果は家畜のRAMのデータ変数に保存されます):
- eye_up_distance-最も近いオブジェクトまでの距離の値を取得する
- eye_down_distance-最も近いオブジェクトまでの距離の値を取得する
- eye_left_distance-一番左のオブジェクトまでの距離の値を取得する
- eye_right_distance-右側の最も近いオブジェクトまでの距離の値を取得する
- touch_up-最も近いオブジェクトのタイプの値を取得する
- touch_down-最も近いオブジェクトのタイプの値を取得する
- touch_left-左に最も近いオブジェクトの型の値を取得
- touch_right-右側に最も近いオブジェクトの型の値を取得
- 10個のライブメモリ管理コマンド:
- move_mem_left -mem_ptrポインターを左に移動します
- move_mem_right -mem_ptrポインターを左に移動する
- save_to_mem-家畜のRAM( data )の内容を現在のセルに保存します
- load_from_mem-現在のセルから家畜RAM( data )に値をロードします
- add_mem-現在のメモリセルの値をデータに追加します
- sub_mem- データから現在のメモリセルの値を引きます
- set_mem_ptr -mem_ptrをRAMの値に設定
- data_clear -RAMを消去します
- data_inc -RAMの増分値
- data_dec -RAMの値をデクリメントします
- 動物が実行できるアクション用の12のコマンド(信号をワールドオブジェクトに送信):
- action_move_left-家畜は左に移動します
- action_move_right-生き物は左に移動します
- action_move_up-家畜は左に移動します
- action_move_down-家畜は左に移動します
- action_eat_left-動物は左側のオブジェクトを食べようとします
- action_eat_right-動物は左側のオブジェクトを食べようとします
- action_eat_up-動物は左側のオブジェクトを食べようとします
- action_eat_down-動物は左側のオブジェクトを食べようとします
- action_wait-家畜は待機しており、移動をスキップします
- action_suicide-生き物は自己破壊します
- action_split-家畜はクローンによって共有されます
- action_split_mutate-動物はクローンを共有しますが、いくつかの変異があります
プログラム例
原則として、このようなコマンドのセットは、ループと分岐を行うのに十分です。 もう1つの疑問は、そのような言語でアルゴリズムを記述することは、たとえばC ++ほど便利ではないということです。
しかし、例として、生物を正方形のらせん状に動かすプログラムを示します。
start action_split load_from_mem //load from var1 move_mem_right //save var2 data_dec save_to_mem move_mem_right //save to var3 data_dec save_to_mem //right action_move_right data_dec jump_to_ifnz AnimalCommand(-3) //up load_from_mem data_dec save_to_mem action_move_up data_dec jump_to_ifnz AnimalCommand(-3) //left load_from_mem data_dec save_to_mem action_move_left data_dec jump_to_ifnz AnimalCommand(-3) //down load_from_mem data_dec save_to_mem action_move_down data_dec jump_to_ifnz AnimalCommand(-3) //dec var2 move_mem_left load_from_mem data_dec save_to_mem jump_to_ifnz AnimalCommand(-33) move_mem_left // restore var1 end;
メモリには、10、0、0の3つの値がロードされます。アルゴリズムについては説明しません。 私の意見では、すべてがかなり明白です。
このコードはmainwindow.cppにあります:117。
突然変異について
ゲーム内の突然変異は現在、このように実装されています。 生物の要求に応じて、クローンを作成し、突然変異を伴うクローンを作成します。 クローンは、0から9の量の突然変異を受けます(大きなランダムの裁量で)。 各突然変異について、グランドランダムは4つのオプションのいずれかを選択します。
- コードの任意の1バイトが任意の値に置き換えられます
- ランダムバイトがDNAに追加されます
- ランダムな位置でバイトビットオフ
- 任意のバイトがDNAの任意の位置に挿入されます(新規コミット )
交配について
それでは、2つの生物の交配方法について考えてみましょう。 コードの長さは異なっていても、メモリが異なっていてもかまいません。
- 心に懇願する最初のことは、単に2つのDNAを1つの長い長さにブラインドすることです。 ただし、この場合、アルゴリズムの2番目の部分がまったく機能しないか、非常にまれにしか動作しない場合があります。 まあ、まあ-それは実際に劣性遺伝子になります。
- 各DNAに3つの任意のポイントを取り、原則に従って新しいポイントを組み立てることができます。最初のDNAから0-1、2番目から1-2、1番目から2-3、2番目から3-4です。 さらに、ピースの長さはゼロにすることができます。
- 異なる生物の機能をまとめるだけで、 開始タグと終了タグを検索し、新しいDNAを作成できます。 これにより、クリーチャーは強制的にコードを構造化しようとします。
- DNAがなくなるまで、各生物からバイトサイクルを取り込むオプションがあります。 それは一種のフランキンシュタインであることが判明しますが、その特性は非常に興味深いものになります。
それはおそらく、すぐに私の頭に浮かぶすべてのオプションです。 記憶の継承についてはまだ考えていません。
あ! ここで私が忘れていたものです。 何が良いと思いますか?
- Xラウンド後、最もYを取り、それらをクロスします。 同時に、全人口を殺し、これらのY個人とその子孫を世界に住まわせます。
- すべてのXラウンドは、Y(2から5など)を最も強く取り、それらをクロスして、子孫を人口に追加します。
- 3番目のオプションは、あなたが思いついてコメントを書くオプションです。
もちろん、このトピックに関する考えは緻密ではありませんが、行商人の豊かな想像力を願っています。
ありがとう フィードバックを待っています。