サンプルプログラム集
このページでは、いくつかサンプルプログラムを紹介します。 プログラムのコンパイルにはturtle.hが必要です。 また、実行には亀場サーバーも合わせて必要です。
C言語に不慣れな方は Cで学ぶコンピュテーショナル・シンキング もご覧ください。
フラクタル曲線
ヒルベルト曲線(Hilbert curve)を描くサンプルプログラム。描画が終わると、ロボット亀が登場するはず。
#include <stdio.h>
#include <math.h>
#include "turtle.h"
#define STEP 13.0
void hilbert(int level, float angle)
{
if (level<=0) return ;
RT(angle) ;
hilbert(level-1,-angle) ;
FD(STEP) ;
LT(angle) ;
hilbert(level-1,angle) ;
FD(STEP) ;
hilbert(level-1,angle) ;
LT(angle) ;
FD(STEP) ;
hilbert(level-1,-angle) ;
RT(angle) ;
}
main()
{
CON("localhost") ;
CLR() ;
RST() ;
LW(2) ;
COL(1.0,1.0,0.0);
BK(200);
LT(90);
FD(200);
RT(90);
PD();
hilbert(5,90.0);
FIRE();
ROBOT();
}
「ツリー」の描画
再帰を使って、樹形の様なパターンを描くプログラム。亀が行きつ戻りつしている様子が観察できます。
#include "turtle.h"
void branch(float step)
{
if (step<4.0) return ;
else {
LT(20) ;
PD() ; FD(step) ; PU() ;
branch(step*0.6) ;
BK(step) ;
RT(20) ;
RT(10) ;
PD() ; FD(step) ; PU() ;
branch(step*0.7) ;
BK(step) ;
LT(10) ;
}
}
int main() {
CON("localhost") ;
CLR() ;
RST() ;
COL(0.1,0.7,0.2) ;
JUMP(0,-220) ;
NORTH() ;
branch(150) ;
}
シェルピンスキーのガスケット
これも代表的なフラクタル図形。FILL( )モードを使っている。
#include "turtle.h"
void triangle(float size)
{
FILL(); PD(); FD(size); LT(120); FD(size); LT(120); FD(size); PU(); LT(120);
}
void sierpinski(float size)
{
if (size<20.0) { triangle(size) ; return ; }
else {
sierpinski(size/2.0) ;
FD(size/2.0) ;
sierpinski(size/2.0) ;
LT(120) ;
FD(size/2.0) ;
RT(120) ;
sierpinski(size/2.0) ;
RT(120) ;
FD(size/2.0) ;
LT(120) ;
}
}
main() {
CON("localhost") ;
CLR() ;
JUMP(-250,-200) ;
EAST() ;
sierpinski(500) ;
}
ひまわり
右回りと左まわりの螺旋が「見える」だろうか。
#include <math.h>
#include "turtle.h"
void seed(float x, float y, float size)
{
float step=size*sqrt(2.0) ;
JUMP(x,y) ;
EAST() ;
LT(atan2(y,x)*180.0/M_PI) ;
FD(size) ;
LT(135) ;
PD(); FD(step); LT(90); FD(step); LT(90); FD(step); LT(90); FD(step); PU();
}
int main()
{
int n ;
float x,y ;
float GR=(1.0+sqrt(5.0))*0.5 ;
CON("localhost") ;
CLR();
FILL() ;
COL(1,1,0) ;
for (n=1 ; n<250 ; n=n+1) {
x = n*cos(2*M_PI/(GR*GR)*n) ;
y = n*sin(2*M_PI/(GR*GR)*n) ;
seed(x,y,sqrt(n)) ;
}
}
書道
「亀」と書くプログラム。Cのプログラムとしては全く見所はありませんが、BRUSHモードを使った例として。
#include "turtle.h"
int main()
{
int cnt ;
CON("localhost") ;
CLR() ;
RST() ;
BGC(0.8,0.8,0.7) ;
COL(0,0,0) ;
BRUSH() ;
LW(30) ;
JUMP(10,205) ;
WEST(); LT(40) ; PD() ; FD(100) ; PU() ;
JUMP(0,190) ; EAST() ; RT(30) ; PD() ; FD(40) ; RT(120) ; FD(100) ; PU() ;
JUMP(-90,120) ; EAST() ; LT(5) ;
PD() ; FD(170) ; RT(100) ; FD(80) ; FD(0) ; PU() ;
JUMP(-90, 100) ; SOUTH() ; LT(8) ; PD() ; FD(60) ; FD(0) ; PU() ;
JUMP(-70, 80) ; EAST() ; LT(5) ; PD() ; FD(130) ; FD(0) ; PU() ;
JUMP(-70, 40) ; EAST() ; LT(5) ; PD() ; FD(130) ; FD(0) ; PU() ;
JUMP(-130,0) ; EAST() ; LT(5) ; PD() ; FD(250) ; RT(100) ; FD(90) ; FD(0) ; PU() ;
JUMP(-120, -5) ; SOUTH() ; LT(8) ; PD() ; FD(80) ; FD(0) ; PU() ;
JUMP(-100, -40) ; EAST() ; LT(5) ; PD() ; FD(200) ; FD(0) ; PU() ;
JUMP(-110, -80) ; EAST() ; LT(5) ; PD() ; FD(220) ; FD(0) ; PU() ;
LW(35) ;
JUMP(0,110) ; SOUTH(); RT(5) ;
PD() ; FD(210) ;
for (cnt=0; cnt<10 ; cnt=cnt+1) {
LT(10) ; FD(8) ;
}
FD(120) ; LT(85) ; FD(50) ; PU() ;
}
雲のようなパターン
自己アフィンフラクタル(的)なパターンを生成する例。 少しリストが長くなるので、以下にリンクを設けました。 これと同様の手法が、コンピュータグラフィックスで地形や雲を生成する際に使われています。
掃除ロボット
亀場にコインを100枚ばらまいてから、カメがそれを回収します。 プログラムを複数走らせることによって、複数のカメが共同でお掃除してくれます。
#include "turtle.h"
void running_into_wall(unsigned int tm) {
int cnt ;
for (cnt=0; cnt<60; cnt++) LT(3) ;
}
void running_into_turtle(unsigned int tm) {
int cnt ;
for (cnt=0; cnt<40; cnt++) LT(3) ;
}
void found_coin(unsigned int tm) {
PICKCOIN() ;
}
main() {
int cnt,n ;
CON("localhost") ;
BMODE() ;
NM("kame") ;
SET_RUN_INTO_TURTLE_HANDLER(running_into_turtle) ;
SET_RUN_INTO_WALL_HANDLER(running_into_wall) ;
SET_FOUND_COIN_HANDLER(found_coin) ;
Q_NT(&n) ;
if (n==1) for (cnt=0; cnt<100; cnt++) COIN() ;
for (;;) {
FD(2) ;
RT(0.2) ;
}
}
コイン集め
上の例と同様に、コインを100枚散らかしてから、「コインが見つかったときに、もしコインを持っていたらその場に落とす、 持っていなければ拾う」を繰り返す例です。 ここで、「コインが見つかる」とは、「周囲にコインが無い状態からある状態に変化した」という事象のことです。 プログラムを走らせているうちに、(効率は悪いですが)だんだんとコインが集まっていく様子が観察できるはずです。
10匹の亀が同時にコイン集めをしている例
#include "turtle.h"
void found_coin(unsigned int tm) {
int nc ;
Q_MYCOIN(&nc) ;
if (nc>0) DROPCOIN() ;
else PICKCOIN() ;
}
void running_into_object(unsigned int tm) {
int cnt ;
for (cnt=0; cnt<50; cnt=cnt+1) LT(3) ;
}
main()
{
int n,cnt ;
CON("localhost") ;
BMODE() ;
NM("kame") ;
SET_RUN_INTO_WALL_HANDLER(running_into_object) ;
SET_RUN_INTO_TURTLE_HANDLER(running_into_object) ;
SET_FOUND_COIN_HANDLER(found_coin) ;
Q_NT(&n) ;
if (n==1) for (cnt=0; cnt<100; cnt=cnt+1) COIN() ;
while(1) {
FD(2) ;
RT(0.5) ;
}
}
ハノイのカード
よく知られた「ハノイの塔」をトランプのカードを使って表示するデモ。 動作には、2017年6月版以降のバージョンの亀場サーバーとturtle.hが必要。
トランプによる「ハノイの塔」
#include <stdio.h>
#include "turtle.h"
int card[3][52] ;
int ncard[3]={0,0,0} ;
void redraw(int x) {
int i, j, k ;
CLR() ;
for (i=0 ; i<3 ; i++) {
for (j=0 ; j<ncard[i] ; j++) {
k = card[i][j] ;
CARD(k, -200 + i*150.0 - j*2, -220+j*30.0) ;
}
}
JUMP(-160 + x*150.0, -140+(ncard[x]-1)*30.0) ;
}
void move_card(int x, int y) {
if (ncard[x]>0) {
ncard[x]-- ;
card[y][ncard[y]] = card[x][ncard[x]] ;
ncard[y]++ ;
}
redraw(y) ;
}
void move(int n, int x, int y, int z) {
if (n==2) {
move_card(x,z) ;
move_card(x,y) ;
move_card(z,y) ;
} else {
move(n-1,x,z,y) ;
move_card(x,y) ;
move(n-1,z,y,x) ;
}
}
main()
{
int k ;
int n=13 ;
CONNECT("localhost") ;
CLR() ;
BGC(0.1, 0.3, 0.1) ;
NORTH() ;
ncard[0]=n ;
for (k=0; k<n ; k++) {
card[0][k] = 39+n-k ;
}
redraw(0) ;
move(n,0,2,1) ;
}