たくさんのタートル
かめを増やして,名前をつけて,別々に動かします.
第 2 章からここまで,画面にいるかめはずっと 1 匹でした.
fd(100) と書けばそのかめが進み,lt(90) と書けばそのかめが回る.
命令する相手が 1 匹しかいないので,相手を指定する必要がなかったのです.
今回はかめを何匹でも増やせるようにします. そうなると「どのかめに命令するのか」を書かなければなりません. そのために,かめを変数に入れて名前をつけ,その名前に向かって命令を出す という書き方を覚えます.これは Python だけの話ではなく, 現在のプログラミングで最もよく使われている考え方 (オブジェクト指向)の入口でもあります.
t = Turtle()でかめを何匹でも作れるt.fd(100)のように,相手を指定して命令が出せる- これまでの
fd(100)が誰への命令だったのかを説明できる - かめごとに色・太さ・形・大きさを変えられる
- 複数のかめを同時に動いているように見せられる
distance・towardsでかめ同士の関係を調べられる
8.1 かめを増やす
8.1.1 なぜ 1 匹では足りないのか
前の章(第 7 章)までで,if と for,
そして繰り返しの入れ子まで覚えました.
1 匹のかめで描ける絵なら,もうたいていのものは描けます.
しかし,次のようなことはまだできません.
- 2 つの絵が同時に育っていくアニメーション(左の円と右の円が一緒に描かれていく)
- 競走.3 匹が横に並んで,それぞれ違う速さで進む
- 追いかけっこ.片方がもう片方を追いかける
- 画面のあちこちにばらばらの状態(位置・向き・色)を同時に持たせること
どれも「状態を持った登場人物が複数いる」という点で共通しています.
かめが 1 匹しかいないと,位置も向きも色も 1 組しか持てません.
goto で行ったり来たりさせれば真似はできますが,すぐに破綻します.
登場人物が 2 人いるなら,かめも 2 匹用意するのが素直です.
8.1.2 これまでの fd(100) は誰への命令だったのか
from turtle import * と書いて fd(100) と命令したとき,
実は舞台裏で名前のないかめが 1 匹用意されていました.
引数のない fd(100) は,その「名前のないかめ」への命令だったのです.
この教材ではこれを既定(きてい)のかめと呼ぶことにします.
既定のかめにも,あとから名前をつけることができます.
getturtle() と書くと,既定のかめを受け取れます.
from turtle import * pensize(3) fd(100) # 名前のないかめ(既定のかめ)への命令 kame = getturtle() # そのかめに「kame」という名前をつける kame.lt(90) # 今度は名前を指定して命令する kame.fd(100) done()
前半の fd(100) と後半の kame.fd(100) は,
まったく同じかめを動かしています.違うのは書き方だけです.
前半は「(あのかめに)進め」,後半は「kame よ,進め」と言っています.
getturtle() を使う場面は実はあまりありません.
ここでは「今まで命令していた相手は誰だったのか」をはっきりさせるために出しました.
次の節からは,自分で新しいかめを作ります.
8.1.3 t = Turtle() でかめを作る
新しいかめを作るには Turtle() と書きます.
そして,できたかめを変数に入れて名前をつけます.
t = Turtle()
= の右でかめが 1 匹生まれ,
= の左の変数 t がそのかめを指す名札になります.
Turtle は大文字の T で始まることに注意してください.
かっこも必要です.
命令を出すときは,名前のうしろに .(ドット)を打って命令を書きます.
t.fd(100)
t.lt(90)
t.pencolor("red")
ドットは「の」と読むとわかりやすいでしょう.
t.fd(100) は「t の fd 命令を,100 で実行する」,
もっとくだけて言えば「t よ,100 進め」です.
| これまで(第 1〜7 回) | 今回から |
|---|---|
fd(100) | t.fd(100) |
lt(90) | t.lt(90) |
pencolor("red") | t.pencolor("red") |
pu() | t.pu() |
| 相手は 1 匹だけ.書かなくても決まる | 相手を名前で指定する.何匹いてもよい |
8.1.4 2 匹のかめを動かす
では実際に 2 匹作ってみましょう.名前は何でもかまいませんが, ここでは亀太郎と亀次郎にします.
from turtle import *
# かめを 2 匹作る
kame_taro = Turtle()
kame_jiro = Turtle()
# 亀太郎への命令
kame_taro.pensize(4)
kame_taro.pencolor("crimson")
kame_taro.fd(120)
# 亀次郎への命令
kame_jiro.pensize(4)
kame_jiro.pencolor("royalblue")
kame_jiro.lt(90)
kame_jiro.fd(120)
done()
kame_taro への命令と kame_jiro への命令が
まったく干渉していないことを確かめてください.
太郎を赤にしても次郎は青のままですし,次郎を左に向けても太郎は右を向いたままです.
かめはそれぞれ自分の位置・向き・色・太さを持っています.
pu() → goto() → pd() で配置します.
8.1.5 よくある間違い
| 書き方 | 何が起きるか |
|---|---|
t = turtle() | NameError.大文字の T で Turtle() |
t = Turtle | かっこが無い.かめが作られず,t.fd(100) でおかしなエラーになる |
Turtle() だけ書く | かめは生まれるが名札が無いので,二度と命令できない |
t fd(100) | ドットが無い.SyntaxError |
t.fd 100 | かっこが無い.SyntaxError |
かめを作らずに t.fd(100) | NameError: name 't' is not defined.先に作ってから命令する |
3 匹のかめを中央から 3 方向へ進ませて,Y 字(三つ又)を描きます. ____ を埋めてください. 3 方向に均等に開くので,角度は 360 ÷ 3 = 120 度ずつです.
from turtle import *
a = Turtle()
b = Turtle()
c = ____()
a.pensize(5)
b.pensize(5)
c.pensize(5)
a.pencolor("crimson")
b.pencolor("seagreen")
c.pencolor("royalblue")
a.lt(90)
a.fd(120)
b.lt(210)
____.fd(120)
c.lt(____)
c.fd(120)
done()
8.2 かめごとに見た目を変える
かめが複数いると,どれがどれだか分からなくなります. 見た目を変えて区別できるようにするのが,複数のかめを扱うコツです.
8.2.1 色と太さ
pencolor(線の色)と pensize(線の太さ)は,
第 2 章で習ったとおりです.前にドットで名前を付けるだけで,
そのかめだけに効くようになります.
from turtle import *
a = Turtle()
b = Turtle()
c = Turtle()
a.pencolor("crimson")
a.pensize(1)
b.pencolor("seagreen")
b.pensize(4)
b.lt(120)
c.pencolor("darkorange")
c.pensize(8)
c.lt(240)
# 3 匹とも「正六角形を描く」という同じ動きをする
for i in range(6):
a.fd(60)
a.rt(60)
b.fd(60)
b.rt(60)
c.fd(60)
c.rt(60)
done()
color("red") と書くと,線の色と塗りの色の両方が変わります.
かめの姿(次の節で出てくる shape)の色も塗りの色で決まるので,
かめ自身を色分けしたいときは pencolor ではなく
color を使うのが早道です.
8.2.2 かめの形を変える — shape
shape で,かめの姿そのものを変えられます.
使える形は次の 7 種類です.
| 指定 | 見た目 |
|---|---|
"classic" | 細い矢じり(最初の姿) |
"arrow" | 三角の矢印 |
"square" | 四角 |
"triangle" | 大きめの三角 |
"circle" | 丸.ボールに使える |
"turtle" | かめの形.いちばんかわいい |
"blank" | 姿を出さない(ht() と似ている) |
大きさは shapesize(縦, 横) で変えます.
shapesize(3, 3) なら縦横とも 3 倍です.
from turtle import *
a = Turtle()
b = Turtle()
c = Turtle()
d = Turtle()
e = Turtle()
a.shape("classic")
b.shape("arrow")
c.shape("square")
d.shape("triangle")
e.shape("turtle")
a.color("crimson")
b.color("darkorange")
c.color("goldenrod")
d.color("seagreen")
e.color("royalblue")
a.pu()
b.pu()
c.pu()
d.pu()
e.pu()
a.goto(-200, 20)
b.goto(-100, 20)
c.goto(0, 20)
d.goto(100, 20)
e.goto(200, 20)
# 全員 2 倍の大きさにする
a.shapesize(2, 2)
b.shapesize(2, 2)
c.shapesize(2, 2)
d.shapesize(2, 2)
e.shapesize(2, 2)
# 文字を書くためだけのかめ
pen = Turtle()
pen.ht()
pen.pu()
pen.goto(-225, -50)
pen.write("classic", font=("Arial", 13, "normal"))
pen.goto(-125, -50)
pen.write("arrow", font=("Arial", 13, "normal"))
pen.goto(-25, -50)
pen.write("square", font=("Arial", 13, "normal"))
pen.goto(75, -50)
pen.write("triangle", font=("Arial", 13, "normal"))
pen.goto(175, -50)
pen.write("turtle", font=("Arial", 13, "normal"))
done()
pen は,文字を書くためだけのかめです.
絵を描くかめと文字を書くかめを分けておくと,
色や位置を行ったり来たりさせずに済みます.
複数のかめが使えるようになると,こういう「役割分担」ができるようになります.
8.2.3 姿を隠す・出す — ht と st
ht()(hide turtle)でかめの姿が消え,
st()(show turtle)でまた現れます.
線はそのまま残るので,絵の仕上げによく使います.
a.ht() # a の姿を隠す(a が描いた線は残る) a.st() # a の姿をまた出す ht() # 既定のかめを隠す
複数のかめを使うプログラムでは,冒頭に ht() と書いて
使わない既定のかめを消しておくのが定石です.
これを書かないと,何もしていないかめが 1 匹,画面の真ん中に立ったままになります.
3 匹のかめを横に並べ,形・色・大きさをそれぞれ変えます.
____ を埋めてください.
文字列(形や色の名前)は " で囲むのを忘れないように.
from turtle import *
ht() # 既定のかめを消しておく
a = Turtle()
b = Turtle()
c = Turtle()
a.shape("turtle")
b.shape(____) # 丸にする
c.shape("square")
a.color("seagreen")
b.color("crimson")
c.color(____) # 好きな色にする
a.shapesize(2, 2)
b.shapesize(____, ____) # b だけ 3 倍
c.shapesize(1, 1)
a.pu()
b.pu()
c.pu()
a.goto(-140, 0)
b.goto(0, 0)
c.goto(140, 0)
done()
8.3 同時に動いているように見せる
ここが今回の一番おもしろいところです. 同じ絵ができあがるのに,動き方がまったく違う 2 つのプログラムを見比べます.
8.3.1 順番に動かす
まず,素直に書いた版です.亀太郎が円を描き終わってから,亀次郎が描き始めます. 実行して,動きをよく見てください.
from turtle import *
ht()
a = Turtle()
b = Turtle()
c = Turtle()
d = Turtle()
a.pencolor("crimson")
b.pencolor("royalblue")
c.pencolor("seagreen")
d.pencolor("darkorange")
b.lt(90)
c.lt(180)
d.lt(270)
# a が 1 周ぜんぶ描いてから,b が描き始める
for i in range(120):
a.fd(2)
a.rt(3)
for i in range(120):
b.fd(2)
b.rt(3)
for i in range(120):
c.fd(2)
c.rt(3)
for i in range(120):
d.fd(2)
d.rt(3)
done()
8.3.2 交互に命令を出す
次は,繰り返しの中身を変えた版です.
4 匹ぶんの命令を 1 つの for の中に並べました.
できあがる絵はさっきとまったく同じです.実行してください.
from turtle import *
ht()
a = Turtle()
b = Turtle()
c = Turtle()
d = Turtle()
a.pencolor("crimson")
b.pencolor("royalblue")
c.pencolor("seagreen")
d.pencolor("darkorange")
b.lt(90)
c.lt(180)
d.lt(270)
# 4 匹に少しずつ交互に命令を出す
for i in range(120):
a.fd(2)
a.rt(3)
b.fd(2)
b.rt(3)
c.fd(2)
c.rt(3)
d.fd(2)
d.rt(3)
done()
4 つの円が一緒に育っていくように見えたはずです. 実際には,コンピュータは「a を少し,b を少し,c を少し,d を少し」と 1 匹ずつ順番に動かしています. ただ,切り替えが細かいので,人間の目には同時に見えるのです.
- 1 つの仕事を最後までやってしまうと,他の仕事が待たされる(8.3.1).
- 少しずつ切り替えると,全部が同時に進んでいるように見える(8.3.2).
- 切り替えを細かくしすぎると,切り替えそのものに時間を取られて遅くなる.
この考え方をマルチタスクといいます. 第 10 章のアニメーションも,第 12 章のゲームも,同じ原理でできています.
8.3.3 交互に出すときの書き方のコツ
- 1 回ぶんの動きを小さくする.
fd(100)のように大きく動かすと,交互にしても同時に見えない.fd(2)くらいに刻む. - 繰り返しは 1 つにまとめる.かめの数だけ
forを書いたら,それは 8.3.1 の「順番」になる. - 動く距離が違ってもよい.
a.fd(2)とb.fd(5)にすれば,b のほうが速く見える.競走はこれで作る. - 途中で抜けるかめがいてもよい.
ifを使えば,あるかめだけ止めることもできる.
左端の赤いかめと右端の青いかめが,同時に弧を描きながら進みます. ____ を埋めてください. 青いかめは最初に左(西)を向かせる必要があります.
from turtle import *
ht()
a = Turtle()
b = Turtle()
a.pensize(3)
a.pencolor("crimson")
a.pu()
a.goto(-220, -60)
a.pd()
b.pensize(3)
b.pencolor("royalblue")
b.pu()
b.goto(220, -60)
b.pd()
b.lt(____) # 左(西)を向かせる
for i in range(60):
a.fd(5)
a.lt(3)
____.fd(5)
____.rt(____) # b は a と反対まわり
done()
8.4 4〜5 匹をまとめて使う
8.4.1 まんじ(卍)を描く
4 匹を中央から東・南・西・北に向けて,同じ命令を同時に出します. 「まっすぐ進む → 左に 90 度曲がる → またまっすぐ進む」だけで卍になります.
from turtle import *
ht() # 既定のかめを消す
a = Turtle()
b = Turtle()
c = Turtle()
d = Turtle()
a.pensize(4)
b.pensize(4)
c.pensize(4)
d.pensize(4)
a.pencolor("crimson")
b.pencolor("royalblue")
c.pencolor("seagreen")
d.pencolor("darkorange")
# 90 度ずつずらして,四方を向かせる
b.rt(90)
c.rt(180)
d.rt(270)
# まっすぐ進む
for i in range(50):
a.fd(2)
b.fd(2)
c.fd(2)
d.fd(2)
# その場で左に 90 度まわる
for i in range(90):
a.lt(1)
b.lt(1)
c.lt(1)
d.lt(1)
# またまっすぐ進む
for i in range(50):
a.fd(2)
b.fd(2)
c.fd(2)
d.fd(2)
done()
for は,向きを変えるだけなので線を引きません.
それでも 1 度ずつ 90 回に分けているのは,
lt(90) と一気に書くと 4 匹が「カクッ」と同時に回ってしまい,
アニメーションとして面白くないからです.
動きを細かく刻むという発想は,第 10 章でそのまま使います.
8.4.2 タートルリレー
4 匹を四角形の頂点に配置し,1 匹ずつ順番に走らせます.
走り終わったかめは ht() で消えて,次のかめにバトンを渡します.
こちらは「同時」ではなく「順番」を意図的に使う例です.
from turtle import *
ht()
a = Turtle()
b = Turtle()
c = Turtle()
d = Turtle()
a.shape("turtle")
b.shape("turtle")
c.shape("turtle")
d.shape("turtle")
a.color("crimson")
b.color("royalblue")
c.color("seagreen")
d.color("darkorange")
a.pensize(4)
b.pensize(4)
c.pensize(4)
d.pensize(4)
# 4 すみに配置して,走る向きを決める
a.pu()
a.goto(-150, 90)
a.seth(0)
a.pd()
b.pu()
b.goto(150, 90)
b.seth(270)
b.pd()
c.pu()
c.goto(150, -90)
c.seth(180)
c.pd()
d.pu()
d.goto(-150, -90)
d.seth(90)
d.pd()
# 第 1 走者
for i in range(60):
a.fd(5)
a.ht()
# 第 2 走者
for i in range(36):
b.fd(5)
b.ht()
# 第 3 走者
for i in range(60):
c.fd(5)
c.ht()
# 第 4 走者(ゴール)
for i in range(36):
d.fd(5)
done()
seth(角度) は「その場でその方角を向く」命令です.
lt・rt が「今の向きから何度回るか」なのに対し,
seth は今の向きに関係なく向きが決まります.
0 が東,90 が北,180 が西,270 が南です.
複数のかめをそろえて配置するときに便利です.
8.4.3 変数を 4 つ並べるということ
ここまでのプログラムでは,a・b・c・d
と変数を 4 つ書き,同じ命令を 4 回ずつ書いてきました.
かめが 4 匹なら我慢できますが,10 匹だったらどうでしょうか.100 匹だったら.
a.fd(2) b.fd(2) c.fd(2) d.fd(2) # …あと 96 行
for で回せるようになります.
今は面倒に感じておくことが大事です.
第 2 章で同じ図形を 3 回書いたのと同じ状況にいます.
今回は多くても 5 匹までにしておきましょう.
8.5 かめ同士の関係を調べる
かめが複数いると,「あのかめはどこにいるのか」を 知りたくなります.そのための命令が 2 つあります.
8.5.1 距離を測る — distance
a.distance(b) と書くと,
a から b までの距離が数として返ってきます.
かめに命令するのではなく,かめにたずねて答えをもらう使い方です.
第 3 章の input() や int() と同じ仲間で,
返ってきた数を変数に入れたり,計算に使ったりできます.
こういう「答えを返す命令」を自分で作る方法は,第 14 章で習います.
from turtle import *
ht()
a = Turtle()
b = Turtle()
a.shape("turtle")
a.color("seagreen")
b.shape("circle")
b.color("crimson")
a.pu()
a.goto(-120, -60)
b.pu()
b.goto(90, 70)
# 距離を測って表示する
print("a から b までの距離は", round(a.distance(b)))
# 2 匹を線で結んでみる
a.pencolor("gray")
a.pensize(2)
a.pd()
a.goto(b.xcor(), b.ycor())
a.pu()
done()
b.xcor()・b.ycor() は,
b の x 座標・y 座標を返します.
相手の座標を取ってきて,そこへ goto したわけです.
座標を数で書かずに「相手のいるところ」と書けるのが,
かめを変数で持っていることの利点です.
a.distance(b) は,a.distance(100, 50) のように
座標を直接渡すこともできます.
どちらの書き方でも,返ってくるのは「そこまでの距離」です.
8.5.2 相手の方を向く — towards
a.towards(b) は,a から見た b の方角を返します.
これを seth に渡せば,a は b の方を向きます.
a.seth(a.towards(b)) # a が b の方を向く a.fd(5) # b に向かって 5 進む
この 2 行を繰り返すだけで,追いかけっこになります.
from turtle import *
ht()
nezumi = Turtle() # 逃げるほう
kame = Turtle() # 追うほう
nezumi.shape("circle")
nezumi.color("crimson")
nezumi.pensize(2)
nezumi.pu()
nezumi.goto(160, 100)
nezumi.pd()
kame.shape("turtle")
kame.color("seagreen")
kame.shapesize(1.5, 1.5)
kame.pensize(2)
kame.pu()
kame.goto(-200, -120)
kame.pd()
for i in range(80):
# ねずみは円を描いて逃げる
nezumi.lt(4)
nezumi.fd(6)
# かめはねずみの方を向いて追いかける
kame.seth(kame.towards(nezumi))
kame.fd(7)
print("最後の距離は", round(kame.distance(nezumi)))
done()
かめのほうが 1 歩だけ大きい(7 と 6)ので,じわじわ追いつきます.
kame.fd(7) を kame.fd(5) に変えると,
今度は追いつけません.数を変えて確かめてください.
towards が返すのは角度,
distance が返すのは長さです.
どちらも答えを返してくる命令なので,
print で表示したり,if の条件に使ったりできます.
if kame.distance(nezumi) < 20: と書けば,
「つかまえた」の判定になります.第 12 章のゲームで使います.
青い子どもが逃げ,赤い鬼が追いかけます. ____ を埋めてください. 「相手の方を向く」ための命令と,「距離を測る」ための命令を思い出しましょう.
from turtle import *
ht()
ko = Turtle() # 逃げる子ども
oni = Turtle() # 追う鬼
ko.shape("circle")
ko.color("royalblue")
ko.pensize(2)
ko.pu()
ko.goto(180, 120)
ko.pd()
oni.shape("turtle")
oni.color("crimson")
oni.pensize(2)
for i in range(60):
ko.lt(5)
ko.fd(8)
oni.seth(oni.____(ko)) # ko の方を向く
oni.fd(____) # ko より少しだけ速く
print("最後の距離は", round(oni.____(ko)))
done()
8.6 足跡を残す — stamp
t.stamp() と書くと,そのときのかめの姿が
その場にハンコのように押されて残ります.
線ではなく姿そのものが残るのがポイントです.
from turtle import *
ht()
t = Turtle()
t.shape("turtle")
t.color("seagreen")
t.shapesize(1.6, 1.6)
t.pu() # 線は引かない
t.goto(-220, -80)
for i in range(9):
t.stamp() # 今の姿をその場に残す
t.fd(52)
t.lt(7)
done()
pu() してあるので線は引かれません.
それでも進んだ跡がわかるのは,stamp() が姿を残しているからです.
| 命令 | 意味 |
|---|---|
t.stamp() | 今の姿をその場に残す |
t.clearstamps() | そのかめが残した足跡をすべて消す |
stamp は第 10 章・第 12 章でとても役に立ちます.
たとえば「弾を撃つ」「星をばらまく」「通った道に印をつける」といった処理を,
かめを何匹も作らずに書けます.
8.7 この章で出てきた命令
| 命令 | 意味 |
|---|---|
t = Turtle() | かめを 1 匹作り,t という名前をつける |
t.fd(長さ) | t に「進め」と命令する.bk lt rt も同じ形 |
t.pu() / t.pd() | t のペンを上げる・下ろす |
t.pencolor(色) | t の線の色 |
t.color(色) | t の線の色と姿の色の両方 |
t.pensize(太さ) | t の線の太さ |
t.shape(名前) | t の姿.classic arrow square triangle circle turtle blank |
t.shapesize(縦, 横) | t の姿の大きさ(倍率) |
t.ht() / t.st() | t の姿を隠す・出す |
t.goto(x, y) | t をその座標へ動かす |
t.seth(角度) | t をその方角に向ける.0 が東,90 が北 |
t.xcor() / t.ycor() | t の x 座標・y 座標を返す |
t.heading() | t が今向いている角度を返す |
t.distance(u) | t から u までの距離を返す |
t.towards(u) | t から見た u の方角を返す |
t.stamp() | t の姿をその場に残す |
t.clearstamps() | t が残した足跡を消す |
getturtle() | 既定のかめ(名前のないかめ)を受け取る |
演習
以下の演習には,出発点となるプログラムが入っています. 「▶ この演習を開く」で右側に読み込み,それを発展させて作品にしてください. できあがったら「⤓ 保存」でファイルに保存して,手元に残しておきましょう.
ht() を書いて
既定のかめを消しておくことを忘れずに.
作ったかめが何匹いるのか,自分でも分からなくなったら,
かめごとに色を変えてみてください.
4 匹のかめを同時に動かしてまんじ(卍)を描くプログラムを与えます. これをもとに,独自にアレンジを加えたプログラムを作ってください.
- かめの数を 4 匹から 6 匹・8 匹に増やしてみる(向きは 360 ÷ 匹数 度ずつ)
- 曲がる回数を増やして,渦巻きのようにしてみる
- 太さや色を途中で変えてみる
- 曲がる向き(
ltとrt)を入れ替えてみる
4 匹のかめが四角形のコースをリレーするプログラムを与えます. これをもとに,独自にアレンジを加えたプログラムを作ってください.
- コースを三角形・五角形・星形にしてみる
- 走者を 5 人・6 人に増やしてみる
- 走り終わった人を
ht()で消すのをやめて,並ばせてみる - バトンを渡す瞬間に
stamp()で印を残してみる - 走る速さ(
fdの数)を走者ごとに変えてみる
3 匹のかめが左から右へ競走するプログラムを与えます. 進む距離を乱数で決めるので,実行するたびに結果が変わります. これをもとに,独自にアレンジを加えたプログラムを作ってください.
- 走者を 4 匹・5 匹に増やす
- コースに線を引く,ゴールの線を引く
xcor()を比べて,優勝者をprintで発表する- 速い走者と遅い走者を作る(
randintの上限を変える) - 途中で転ぶ走者を作る(
ifで一定回数だけ進ませない)
from random import randint と書いておくと,
randint(0, 6) で 0 以上 6 以下のでたらめな整数
が手に入ります.毎回違う数になるので,レースらしくなります.
今まで描いた絵を,何匹かのかめで分担して描いてみます. 第 2 章で描いた「家」を,屋根係・かべ係・ドア係の 3 匹で描くプログラムを与えます. これをもとに,独自にアレンジを加えたプログラムを作ってください.
- 係を増やす(窓係・煙突係・木係・太陽係)
- 係ごとに色と太さを変えて,誰が何を描いたか分かるようにする
- 3 匹を同時に動かして,家が一度に組み上がるようにしてみる(8.3 節)
- 家を 2 軒・3 軒に増やす
2 匹のかめが,同時にそれぞれ星と五角形を描くプログラムを与えます. どちらも「進む」と「曲がる」を細かく刻み,交互に命令を出しています. 星は 1 か所で 144 度,五角形は 72 度曲がるので, 同じ回数だけ刻んで,1 回に曲がる角度を変えています. これをもとに,独自にアレンジを加えたプログラムを作ってください.
- 3 匹目を足して,正六角形や正八角形も同時に描かせる
- 大きさを変える(
fdの数) - 描き終わったあと,2 匹を中央に集合させる
- 描きながら色が変わるようにする
ここまでの命令だけを使って,複数のかめが登場する作品を作ってください. 絵でも,競走でも,追いかけっこでも,かめたちのダンスでもかまいません.
- かめを 3 匹以上使うこと
- かめごとに色または形を変えて,区別できるようにすること
- 8.3 節の「交互に命令を出す」をどこかで必ず使うこと
- 先頭にコメントで,題名・氏名・日付を書くこと
- 仕上げに既定のかめを
ht()で消すこと
まとめ
t = Turtle()でかめを作り,t.fd(100)のようにドットで相手を指定して命令する.- これまでの
fd(100)は,名前のないかめ(既定のかめ)への命令だった. - かめはそれぞれ自分の位置・向き・色・太さ・姿を持っている.
shapeとcolorで区別をつける. - 順番に動かすと順番に見え,交互に少しずつ動かすと同時に見える.コンピュータは本当は同時に 2 つの仕事をしていない.
t.distance(u)で距離,t.towards(u)で方角がわかる.seth(towards(…))で追いかけっこになる.t.stamp()で姿をその場に残せる.- かめが増えると変数も増える.まとめて扱う方法は第 16 章(リスト)で習う.
次の回では,いったん絵から離れます. タートルを使わず,入力・計算・表示だけで作る CUI プログラムを書いてみます. 絵がない代わりに,仕様を読んでそのとおりに作る力がためされます.
そのあとの第 10 章で,このかめたちを本当に動かします.
ontimer という命令を使って,
「少し動かして,少し待って,また少し動かす」を繰り返させると,
絵がアニメーションになります.