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 により繰り返されます。

  1. 宇宙船を移動 moveship
  2. もし発射ボタンが押されていて :trigger 、まだ魚雷が残っていたら発射 create torpedo
  3. 衝突判定 ?crash
  4. 宇宙船の描画 shilp
  5. 単位時間経過を待つ pause

ループは回り続けるようなので、並列性を意識した仕様のようによみとれます。Smalltalk-72 にはそうした機能はないので、なにか方法を考えないといけませんね…

「sin」「cos」の実装へ続く)