ラングトンのアリの描画
Posted feedbacks - Other
Excel VBAにて、ごくシンプルに。
Excelを以下のように調整すると、実行結果が見やすくなります。
- 行の高さと列の幅を調整して、全てのセルを正方形にする。
- 表示倍率を小さくして、なるべく多くのセルが画面内に収まるようにする
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | Option Explicit
'// [定数] 蟻の方向
Const DIR_UP = 0 '上向き
Const DIR_RIGHT = 1 '右向き
Const DIR_DOWN = 2 '下向き
Const DIR_LEFT = 3 '左向き
'// [定数] 色
Const COLOR_WHITE = &HFFFFFF '白
Const COLOR_BLACK = &H0 '黒
'// ラングトンの蟻
Sub Langtons_ant()
Dim r_Ant As Long '// 蟻の位置(行番号)
Dim c_Ant As Long '// 蟻の位置(行番号)
Dim dir_Ant As Integer '// 蟻の方向
'////////////////////////////////////////////////////////////////////
' 初期処理
'////////////////////////////////////////////////////////////////////
'// 蟻の位置を決める。
r_Ant = 50
c_Ant = 50
'// 蟻の方向を決める。
dir_Ant = DIR_UP '上向き
'////////////////////////////////////////////////////////////////////
' 主処理
'////////////////////////////////////////////////////////////////////
'// 蟻がシート内にいる間、以下を繰り返す。
Do While 0 < c_Ant And c_Ant <= Columns.Count _
And 0 < r_Ant And r_Ant <= Rows.Count
'// 蟻がいるマスの色による場合分け。
If Cells(r_Ant, c_Ant).Interior.Color = COLOR_BLACK Then
'// マスの色が黒:
'// 蟻を90°右に方向転換する。
dir_Ant = (dir_Ant + 1) Mod 4
'// マスの色を白に変える。
Cells(r_Ant, c_Ant).Interior.Color = COLOR_WHITE
Else
'// マスの色が白:
'// 蟻を90°左に方向転換する。
dir_Ant = (dir_Ant + 3) Mod 4
'// マスの色を黒に変える。
Cells(r_Ant, c_Ant).Interior.Color = COLOR_BLACK
End If
'// 蟻を一歩進める。
Select Case dir_Ant
Case DIR_UP
'// 蟻が上向き:
r_Ant = r_Ant - 1
Case DIR_RIGHT
'// 蟻が右向き:
c_Ant = c_Ant + 1
Case DIR_DOWN
'// 蟻が下向き:
r_Ant = r_Ant + 1
Case DIR_LEFT
'// 蟻が左向き:
c_Ant = c_Ant - 1
End Select
Loop
End Sub
|
Excel VBAにて、複数の蟻が動くようにしました。(#9388の変更)
Excelを以下のように調整すると、実行結果が見やすくなります。
- 行の高さと列の幅を調整して、全てのセルを正方形にする。
- 表示倍率を小さくして、なるべく多くのセルが画面内に収まるようにする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | Option Explicit
'// [定数] 蟻の方向
Const DIR_UP = 0 '上向き
Const DIR_RIGHT = 1 '右向き
Const DIR_DOWN = 2 '下向き
Const DIR_LEFT = 3 '左向き
'// [定数] 色
Const COLOR_WHITE = &HFFFFFF '白
Const COLOR_BLACK = &H0 '黒
'// [構造体] 蟻
Type typ_Ant
r As Long '// 蟻の位置(行番号)
c As Long '// 蟻の位置(列番号)
dir As Long '// 蟻の方向
died As Boolean '// 死亡フラグ
End Type
'// ラングトンの蟻(複数版)
Sub Langtons_ant_s()
Dim ants() As typ_Ant '蟻
Dim i As Integer 'インデックス
Dim AllDied As Boolean '全ての蟻が死亡したか?
'////////////////////////////////////////////////////////////////////
' 初期処理
'////////////////////////////////////////////////////////////////////
'// 蟻の数を決める。
ReDim ants(5)
'// 蟻1匹目
ants(0).r = 70
ants(0).c = 100
ants(0).dir = DIR_UP
'// 蟻2匹目
ants(1).r = 100
ants(1).c = 100
ants(1).dir = DIR_UP
'// 蟻3匹目
ants(2).r = 30
ants(2).c = 120
ants(2).dir = DIR_RIGHT
'// 蟻4匹目
ants(3).r = 40
ants(3).c = 90
ants(3).dir = DIR_DOWN
'// 蟻5匹目
ants(4).r = 40
ants(4).c = 10
ants(4).dir = DIR_LEFT
'// 蟻6匹目
ants(5).r = 70
ants(5).c = 100
ants(5).dir = DIR_UP
'////////////////////////////////////////////////////////////////////
' 主処理
'////////////////////////////////////////////////////////////////////
'// いずれかの蟻が生きている間、以下を繰り返す。
Do While True
AllDied = True
For i = 0 To UBound(ants)
If Not ants(i).died Then
AllDied = False
Exit For
End If
Next
If AllDied Then
'// 全ての蟻が死亡している。
'// 処理を中断する。
Exit Do
End If
'// 生きているすべての蟻について、以下を繰り返す。
For i = 0 To UBound(ants)
If Not ants(i).died Then
'// 蟻がいるマスの色による場合分け。
If Cells(ants(i).r, ants(i).c).Interior.Color = COLOR_BLACK Then
'// マスの色が黒:
'// 蟻を90°右に方向転換する。
ants(i).dir = (ants(i).dir + 1) Mod 4
'// マスの色を白に変える。
Cells(ants(i).r, ants(i).c).Interior.Color = COLOR_WHITE
Else
'// マスの色が白:
'// 蟻を90°左に方向転換する。
ants(i).dir = (ants(i).dir + 3) Mod 4
'// マスの色を黒に変える。
Cells(ants(i).r, ants(i).c).Interior.Color = COLOR_BLACK
End If
'// 蟻を一歩進める。
Select Case ants(i).dir
Case DIR_UP
'// 蟻が上向き:
ants(i).r = ants(i).r - 1
Case DIR_RIGHT
'// 蟻が右向き:
ants(i).c = ants(i).c + 1
Case DIR_DOWN
'// 蟻が下向き:
ants(i).r = ants(i).r + 1
Case DIR_LEFT
'// 蟻が左向き:
ants(i).c = ants(i).c - 1
End Select
'// 蟻がシート内にいることを確認する。
If Not (0 < ants(i).c And ants(i).c <= Columns.Count _
And 0 < ants(i).r And ants(i).r <= Rows.Count) Then
'// シート内にいない:
'// 蟻の死亡フラグをオンにする。
ants(i).died = True
End If
End If
Next
Loop
End Sub
|
Tkで描画。 canvasを配置し、そこにドットを描く。 使うモジュールはTk, Tkclient。 メモ ・TKの使い方 ・初期値つきの二次元配列の定義 ・ドットの代わりにlineを使用している。メモリを沢山消費しているかも
see: A Descent into Limbo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | implement d276;
# doukaku?276 Langton
include "sys.m";
sys:Sys;
include "draw.m";
draw: Draw;
include "tk.m";
tk: Tk;
include "tkclient.m";
tkclient: Tkclient;
d276: module {
init: fn(ctxt: ref Draw->Context, argv: list of string);
};
init(ctxt: ref Draw->Context, argv: list of string)
{
sys = load Sys Sys->PATH;
sys->pctl(sys->NEWPGRP, nil);
draw = load Draw Draw->PATH;
tk = load Tk Tk->PATH;
tkclient = load Tkclient Tkclient->PATH;
# canvas size
height := 128;
width := 128;
pixel := array [width] of { * => array [height] of { * => 0}}; # 2dimensional array
curx := width/2;
cury := height/2;
dir := 0; # N: 0 E: 1 S: 2 W: 3
tkclient->init();
if(ctxt == nil)
ctxt = tkclient->makedrawcontext();
(win, wmctl) := tkclient->toplevel(ctxt, nil, "d276", 0);
# create canvas
tk->cmd(win, sys->sprint("canvas .b -width %d -height %d -background white",width , height));
tk->cmd(win, "pack .b");
tk->cmd(win, "update");
tkclient->onscreen(win, nil);
tkclient->startinput(win, "kbd"::"ptr"::nil);
for(;;){
# toggle pixel and turn
color :=pixel[curx][cury];
cstr : string;
if(color){
cstr = "white";
color = 0;
dir += 1;
if(dir > 3) dir = 0;
}else{
cstr = "black";
color = 1;
dir -= 1;
if(dir < 0) dir = 3;
}
pixel[curx][cury] = color;
# Plot (using line)
tk->cmd(win, sys->sprint(".b create line %d %d %d %d -fill %s", curx,cury, curx,cury,cstr));
tk->cmd(win, "update");
# update direction
case dir{
0 =>
cury--;
1 =>
curx++;
2 =>
cury++;
3 =>
curx--;
}
# if it reaches edge, it stop
if((curx < 0) || (curx >= width) || (cury < 0) || (cury >= height)){
break;
}
}
# Window event loop?
for(;;) alt{
s := <-win.ctxt.kbd =>
tk->keyboard(win, s);
s := <-win.ctxt.ptr =>
tk->pointer(win, *s);
s := <-win.ctxt.ctl or
s = <-win.wreq or
s = <-wmctl =>
if(s == "exit")
return;
}
}
|

Songmu #9331() [ JavaScript ] Rating8/10=0.80
- 黒いマスにアリがいた場合、90°右に方向転換し、そのマスの色を反転させ、1マス前進する。
- 白いマスにアリがいた場合、90°左に方向転換し、そのマスの色を反転させ、1マス前進する。
詳しくはWikipedia等で調べるか、参考ページに拙作のデモがありますのでご覧下さい。
see: JavaScriptでラングトンの蟻
Rating8/10=0.80-0+
[ reply ]