Smalltalk-72で遊ぶOOPの原点:宇宙船を描く(たぶんこうなんじゃないか編)
アラン・ケイの“メッセージングによるプログラミング”という着想に基づき(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72に実際に触れてみるシリーズ 第2弾です(なお最新のSmalltalkについては Pharo などでお楽しみください!)。
今回は謎言語「Smalltalk-71」で書かれたスペースウォー・ゲームを Smalltalk-72に移植して動かすことを目指します。前回(2019年)を含む他の記事はこちらから→Smalltalk-72で遊ぶOOPの原点 | Advent Calendar 2023 - Qiita
エスパー力を発揮して宇宙船完成図を予想する
Smalltalk-71 のコードをもう一度確認してみましょう。一辺の長さが 2 もしくは 4 で宇宙船胴体とおぼしき扁平6角形が描かれたあと(青字)、2√3 → 2 → 2 → 2√3 の長さで4本の線分が引かれています(オレンジと赤字)。
to ship :size penup, left 180, forward 2 * :size, right 90 forward 1 * :size, right 90 pendown, forward 4 * :size, right 30, forward 2 * :size right 120, forward 2 * :size right 30, forward 4 * :size right 30, forward 2 * :size right 120, forward 2 * :size left 150, forward :size * 2 * sqrt 3 left 330, forward :size * 2 right 60, forward :size * 2 left 330, forward :size * 2 * sqrt 3 penup, left 90, forward :size, right 90, forward 2 * :size end to
[2023-12-04 追記:最後の right 60
との誤りと思われていた記述は、誌面では正しく right 90
で OCR の誤認識でしたので、以降もしれっと無かったことにしています。あしからず^^;]
ここで、あらぬ方向に伸びている最後の4本の線分について、その角度はともかく長さについては正しいと仮定します。
さらに、オレンジの線については角度も正しいとすると、最後の 2√3 の長さの赤線は、オレンジの線と同様に宇宙船の右側に沿って描かれる必要がある、と考えるのは妥当でしょう。
残りの二本の赤線の長さは 2 、オレンジと最後の赤の線分の長さが 2√3 であることをあわせると、宇宙船胴体底部の頂点に接するように 60度の角を作って2本の長さ 2 の線分が描かれるとすれば、収まりが良さそうです。
ところで、330
という数は 360 - 30
から求められた数値と考えることもできます。タートルグラフィックスで例えば正三角形を描く場合、60
度の角を作るために 180 - 60
度、つまり 120
度 曲げなければならないのですが、この 180
を 360
とうっかり取り違えてしまったとしたら…と想像するのはうがち過ぎでしょうか?
つまり、330
は 180-30
の 180
を 360
に取り違えで、続く 60
は 180-60
の 180
から引くのを忘れたよくあるミス…と解釈すると、それっぽく説明がつきそうではあります。
もとより、扁平六角形はきちんと描けているので、どうしてここに来て2度までも違う方法でミスったかという疑問は残りますが…^^;
[2023-12-04 追記:ぼんやりと図を眺めていたら、左に 330度、右に 60度、左に 330度…とよくある「180
から引くのを忘れる」勘違いをしたと解釈する方が自然では?思えてきました。その場合は一貫していて「2度までも違う方法」ではないですね^^; もっとも依然「どうしてここに来てミスったか?」という疑問は残りますが…]
ともあれ、Smalltalk-71 のコードは、とりあえずは次のように読み替えることにいたしましょう。
to ship :size penup, left 180, forward 2 * :size, right 90 forward 1 * :size, right 90 pendown, forward 4 * :size, right 30, forward 2 * :size right 120, forward 2 * :size right 30, forward 4 * :size right 30, forward 2 * :size right 120, forward 2 * :size left 150, forward :size * 2 * sqrt 3 left 150, forward :size * 2 right 120, forward :size * 2 left 150, forward :size * 2 * sqrt 3 penup, left 90, forward :size, right 90, forward 2 * :size end to
したがって、Smalltalk-72 へのトランスパイルは次のようにするのがよさそうです。
to sqrt x (:x. !1.73) to ship size ( @ penup turn 180 go 2 * :size turn 90 go 1 * size turn 90 pendn go 4 * size turn 30 go 2 * size turn 120 go 2 * size turn 30 go 4 * size turn 30 go 2 * size turn 120 go 2 * size turn `150 go (sqrt 3) * 2 * size turn `150 go 2 * size turn 120 go 2 * size turn `150 go (sqrt 3) * 2 * size penup turn `90 go 1 * size turn 90 go 2 * size ) disp clear @ home penup goto 200 100 pendn. ship 10
(スラスターの火炎を描く(準備編)へ続く)