Smalltalk-72で遊ぶOOPの原点:「spaceship」を解析する
アラン・ケイの“メッセージングによるプログラミング”という着想に基づき(非同期処理などいろいろ足りていないながらも──)比較的忠実に実装された1970年代の非常に古いSmalltalk-72に実際に触れてみるシリーズ 第2弾です(なお最新のSmalltalkについては Pharo などでお楽しみください!)。
今回は謎言語「Smalltalk-71」で書かれたスペースウォー・ゲームを Smalltalk-72に移植して動かすことを目指します。前回(2019年)を含む他の記事はこちらから→Smalltalk-72で遊ぶOOPの原点 | Advent Calendar 2023 - Qiita
どうやら宇宙船クラスらしい spaceship
をざっと読む
爆発を描く flash
、逆噴射の retro
、魚雷を描く torp
は省略されているので後回しにします。
torpedo
との類似性などを参考にしつつインデントを整えるとこんな感じでしょうか。
to spaceship :pilot :thrust :steer :trigger use :numtorps :location:(:x :y) :speed :direction repeat moveship if :trigger and :numtorps < 3 then create torpedo :speed :direction :location ?crash :self display ship pause until clock = :time + :movelag end to
Smalltalk-71 のクラスも、Smalltalk-72 のクラス同様に、クロージャのような性質を強く持ち合わせているようです。
この定義と start
の記述から、spaceship
はインスタンス化時=呼び出し時に :pilot
、:thrust
、:steer
、:trigger
という4つの引数をとり、それぞれ、パイロット名と宇宙船制御のための入力デバイスをアサインしているように読めます。
続くuse
文は、前述の呼び出し時の引数以外のインスタンス変数を宣言しているように読めます。:location
は :x
、:y
というフィールドを持つ、アドホックに宣言できるレコードのようなものでしょうか。
次のような処理が repeat
により繰り返されます。
- 宇宙船を移動
moveship
- もし発射ボタンが押されていて
:trigger
、まだ魚雷が残っていたら発射create torpedo
- 衝突判定
?crash
- 宇宙船の描画
shilp
- 単位時間経過を待つ
pause
ループは回り続けるようなので、並列性を意識した仕様のようによみとれます。Smalltalk-72 にはそうした機能はないので、なにか方法を考えないといけませんね…
(「sin」「cos」の実装へ続く)