最近「ラングトンの蟻」というものを知ったので作ってみました。
手順は簡単で、
1.アリは頭の向いてる方向に1マス進む
2.元いたマスは色が反転する
3.進んだ先のマスが白ならばアリは右に90度回転、黒なら左に90度回転する
4.手順1に戻る
5.満足したらやめる
これだけ。
やってみると、
最初はこんなん
ちょっと大きくなってきて
突然触手を伸ばし始めて
(上下左右でループしてるので)戻ってきてぶつかってまた触手伸ばしてをくりかえす
まだ上下左右の4方向だから納得できるけど、斜め方向を加えた8方向になるとウニョウニョ度が激増して全体がアメーバみたいな動きするから気持ち悪い。
ソースコードは以下
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace RangtonNoAri { public partial class Form1 : Form { public CMain cm; public Form1() { InitializeComponent(); cm = new CMain(); this.pictureBox1.Image = cm.world; } private void pictureBox1_Paint(object sender, PaintEventArgs e) { //e.Graphics.DrawImage(cm.world, new Point(0, 0)); } private void button1_Click(object sender, EventArgs e) { this.timer1.Enabled = true; } private void timer1_Tick(object sender, EventArgs e) { for (int i = 0; i < 50; i++) { cm.Step(); } this.pictureBox1.Invalidate(); } } }
CMain.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Drawing; namespace RangtonNoAri { public class CMain { public Bitmap world; private Graphics g; CAnt ant; Point ws = new Point(400, 400); public CMain() { ant = new CAnt(ws); this.CrateWorld(); } //1ステップ public void Step() { ant.ChangeDirection(this.GetColor(ant.p)); this.ChangePixColor(ant.p); ant.Move(); ant.p = this.Edge(ant.p); } //ビットマップ生成 private void CrateWorld() { world = new Bitmap(ws.X, ws.Y); g = Graphics.FromImage(world); g.FillRectangle(Brushes.White, new RectangleF(0, 0, ws.X, ws.Y)); } //指定場所の色取得 private Color GetColor(Point p) { return world.GetPixel(p.X, p.Y); } //タイルの色変更 private void ChangePixColor(Point p) { if (GetColor(p) == Color.FromArgb(255, 255, 255)) { world.SetPixel(p.X, p.Y, Color.Black); } else if (GetColor(p) == Color.FromArgb(0, 0, 0)) { world.SetPixel(p.X, p.Y, Color.White); } } //境界 private Point Edge(Point p) { if (p.Y < 0) p.Y = ws.Y + p.Y; if (p.Y >= ws.Y) p.Y = p.Y % ws.Y; if (p.X < 0) p.X = ws.X + p.X; if (p.X >= ws.X) p.X = p.X % ws.X; return p; } } class CAnt { public Point p; private int d; public CAnt(Point ws) { p = new Point(ws.X/2, ws.Y/2); d = 1; } //方向 public void ChangeDirection(Color c) { if (c == Color.FromArgb(255,255,255)) d+=1; else if (c == Color.FromArgb(0, 0, 0)) d-=1; if (d < 0) d = 4+d; if (d > 3) d = d-4; } //移動 public void Move() { switch (d) { case 0: p.Y--; //上 break; case 1: p.X++; //右 break; case 2: p.Y++; //下 break; case 3: p.X--; //左 break; } } } }