第14回 最終課題レポート

■ 最終課題

以下に示す課題の中から1つを選択し、解決した上で、最終課題レポートとして提出せよ。

□ 課題1:Smalltalk 包含投げ

Smalltalk を用いて、砲丸の軌跡を表示するプログラムを作成しよう。入出力の条件は次のとおりである。

  1. 砲丸を発射する際の初速度および仰角を入力する。
  2. 砲丸の軌跡を Squeak の画面に表示するための位置情報とスケール比を入力する。
  3. 砲丸の表示のための Morph オブジェクト(StarMorph など)を入力する。
  4. 砲丸を表示する周期 T を入力する。
  5. 砲丸が発射された時点以降、周期 T ごとに、砲丸を Squeak の画面に表示する(静止画)。

以上により、連続ストロボ撮影をしたかのように、砲丸の軌跡を表示する。実行時の様子を参考として以下に示す。

設問1 既存の Point オブジェクトを使用して、砲丸の位置を扱うことにする。System Browser の「find class」という操作を用いて、Point オブジェクトの定義(インスタンス変数として何が存在するか)を検出し、表示せよ。そして、インスタンスメソッド x、y、およびクラスメソッド x:y: の定義を表示せよ。

設問2 砲丸の位置を計算するには、物理的な位置を表す座標系(p系と呼ぶことにする)を使用する。一方、砲丸を表示するには、Squeak の画面上の位置を表す座標系(s系と呼ぶことにする)を使用する。そこで、2つの座標系間の位置情報の変換を行うためのオブジェクト MyConverter を作成しよう。このオブジェクトにおいて、インスタンスメソッド setOx:、setOy:、および、setScale: を作成せよ。ここで、setOx: と setOy: は、p系の原点が対応する s系の位置を設定するものとする。setScale: は、p系における単位長に対する s系における長さを設定するものとする(たとえば、p系における1 がs系における 100 に対応するとき setScale: 100 とする)。次に、p系の位置を s系の位置に変換するメソッドとして toSfromP: を作成せよ。このメソッドの引数は、Point インスタンスを想定せよ。

設問3 まず、軌跡オブジェクト Tracer を作成しよう。Tracer は、抽象オブジェクトである。抽象メソッドとして、pointAtTime: を作成せよ。このメソッドは、引数の時刻における物体の位置(p系)を Point のインスタンスとして返すことが期待されている。次に、砲丸の軌跡オブジェクト TrCannonball を作成せよ。重力加速度を指定するメソッド setGravity:、砲丸の初速度を指定するメソッド setInitialVelocity:、砲丸の投射角度を指定するメソッド setAngle: を作成せよ。また、pointAtTime: を具体的に作成せよ。ちなみに、ラジアンの値に cos というメッセージを送ると、cos の値が返される。

設問4 軌跡をストロボ撮影風に表示するためのオブジェクト MyPrinter を作成しよう。このオブジェクトには、座標系変換のためのオブジェクトを指定するメソッド setConverter:、軌跡計算のためのオブジェクトを指定するメソッド setTracer:、表示する物体(StarMorph など)を指定するメソッド setMorph:、表示周期を指定するメソッド setTerm: を作成せよ。さらに、指定時刻までの軌跡を表示するメソッド showTill:、表示した物体を消去するメソッド clean を作成せよ。なお、showTill: にて表示する物体を Bag などのインスタンス変数に蓄積しておくことで、clean が作成しやすくなる。

設問5 ワークスペースで以下を1行ずつ実行し、画面中央付近に、放物線を描く☆の並びが表示されることを確認せよ。また、最後に mp clean を実行することで、☆が全て消去されることを確認せよ。レポートには☆の並びの表示を掲載せよ。
mc := MyConverter new
mc setOx: 300
mc setOy: 400
mc setScale: 50
ball := TrCannonball new
ball setGravity: 9.8
ball setInitialVelocity: 10.0
ball setAngle: 45
mp := MyPrinter new
mp setConverter: mc
mp setTracer: ball
mp setMorph: StarMorph
mp setTerm: 0.1

mp showTill: 1.7

mp clean

設問6 学籍番号の1桁目に応じて以下の問いを選択して答えよ。

問6−1:偶数の人 showTill: を実行後、p系で見て最も高い位置に表示されている物体の色を変更するためのメソッド changeTopObjectsColor: を作成せよ。
問6−2:奇数の人 showTill: を実行後、p系で見て原点より低い位置に表示されている物体の色を変更するためのメソッド changeUnderGroundObjectsColor: を作成せよ。

設問7 自身のオリジナルの問題を設定し、その解決例を示せ。

□ 課題2:Scheme の Array オブジェクト

Scheme を用いて、オブジェクト指向プログラミングをやってみよう。

配列オブジェクト array を定義しよう。このオブジェクトは次のように操作できるものとする:

設問1 (define a ((array 'new))) により、変数 a に array のインスタンスをバインドせよ。

設問2 (define b ((array 'list) 〈リスト〉)) により、〈リスト〉から作成した配列を持つインスタンスを変数 b にバインドせよ。

設問3 次のメソッドを定義せよ。なお、下記の〈 〉は引数を表す。メッセージ名と引数を並べて記述しているが、Scheme 上で実行する際、上記の形式で引数を与えるものとする。また、「返す」という意味は、「返り値として返す」であり、「writeなどで表示する」ではない。

「'size」により、現在確保している配列のサイズを返す。
「'listing」により、保持している配列をリスト形式で返す。
「'add 〈要素〉」により、配列の末尾に〈要素〉を追加する。
「'add-at 〈要素〉 〈数〉」により、指定番目に〈要素〉を追加する。なお、配列は、0 番目から数える。
「'set-list 〈リスト〉」により、Scheme のリスト構造を、配列として格納する。
「'ref-at 〈数〉」により、指定番目の要素を返す。
「'member 〈要素〉」により、〈要素〉が存在するならばその番目を返し、存在しないならば #f を返す。
「'reverse」により、配列の順序を逆順に変更した新しい array インスタンスを返す。ただし、レシーバの配列は変化しない。
「'append 〈array インスタンス〉」により、レシーバの配列の後ろに引数のインスタンスの配列を接続した配列を持つ新しい array インスタンスを返す。ただし、レシーバの配列は変化しない。
「'each 〈1引数のlambda式〉」により、配列の各要素に対して lambda 式の処理を行う。なお、返り値は不問とする。

設問4 先頭要素を扱うメソッドを作ろう。

「'add-head 〈要素〉」により、0 番目に要素を追加する。元々 0 番目であった要素は 1 番目に、元々 1番目であった要素は 2 番目にと、すべての内容を理論的に移動する。ここで、レシーバの配列は変化するものとせよ。
「'shift」により、0 番目要素を返し、元々の 1 番目要素を新たな 0 番目要素に、元々の 2 番目要素を新たな 1 番目要素にと、すべての内容を理論的に移動する。ここで、レシーバの配列は変化するものとせよ。

設問5 「'qsort」により、レシーバの配列をクイックソートした結果を持つ新しい array インスタンスを返す。ただし、レシーバの状態は変化しない。

設問6 学籍番号の1桁目に応じて以下の問いを選択して答えよ。

問6−1:偶数の人 配列から数値の要素を抽出して合計値を返すメソッド「sum-numbers」を作成せよ。
問6−2:奇数の人 配列から文字列の要素を抽出して文字列の長さの合計値を返すメソッド「sum-string-length」を作成せよ。

設問7 自身のオリジナルの問題を設定し、その解決例を示せ。

※ オブジェクト指向プログラミングの性質が再現できていない場合には、点数が伸びない。よく考えて解答すること。

□ 課題3:Prolog の旅行計画

Prolog を用いて、旅行を計画するプログラムを作成しよう。

入出力の条件は次のとおりである。

  1. 出発地と到着地を入力する。
  2. 出発時刻を入力する。
  3. 経路兼交通手段名を順に出力する。
  4. 最終到着時刻を出力する。
  5. 移動の総コスト(金額 円)を出力する。

※ 3〜5は経路が存在する場合のみ出力

このプログラムで扱う交通手段として、(1) 徒歩、(2) 鉄道、(3) 航空機 の3種類を少なくとも用意せよ。徒歩は、出発時刻の制限が無く、移動コスト(金額)は 0 とせよ。鉄道は、普通列車(短距離のみ)、特急列車、新幹線、モノレールを用意せよ。

鉄道と航空機は、出発時刻、移動コスト、主要な駅・空港を、やや現実的な情報として設定せよ。主要な停車駅や空港として、少なくとも以下を含めること:

鳥取大学前駅、鳥取駅、姫路駅、三宮駅、新大阪駅、京都駅、品川駅、浜松町駅、東京駅
鳥取空港、羽田空港

設問1 移動区間を表すデータの構造を説明せよ。また、全体像を図示せよ。図は、手書きで良い。

設問2 徒歩の場合、出発時刻の制限が無いことへの対処方法を説明せよ。

設問3 鳥取大学から東京駅までの計画を幾つか出力し、その意味を説明せよ。

設問4 最も安く/高く移動する方法を求める規則(find_cheap_path/find_expensive_path)を作成せよ。そして鳥取大学から東京駅までについて各実行例を示せ。

設問5 最も移動時間のかからない方法を求める規則(find_fast_path)を作成せよ。そして鳥取大学から東京駅までについて実行例を示せ。

設問6 学籍番号の1桁目に応じて以下の問いを選択して答えよ。

問6−1:偶数の人 主要な駅として「岡山駅」を追加して、特急「いなば」および関連する新幹線などを追加せよ。そして、幾つか面白い実行例を示せ。
問6−2:奇数の人 主要な空港として神戸空港を追加して、神戸空港から羽田空港への便、および、関連する鉄道を追加せよ。そして、幾つか面白い実行例を示せ。

設問7 自身のオリジナルの問題を設定し、その解決例を示せ。

■ レポートの提出要領

□ 様式

レポートは次の様式で作成せよ。

(1) 表紙(講義名、選択した課題名、初版の提出日、氏名、学籍番号)
(2) プログラム(設問との対応の説明)
(3) 実行結果(設問との対応の説明)
(4) その他の課題に関する説明(オリジナリティを示せ)
(5) プログラミング言語に対する感想(採点の対象です)

□ 受付期間

2008年8月4日(月) 9:00 から 7日(木) 17:00 までを受付期間とします。

□ 提出方法

「最終課題レポート」と「小レポート一式」をまとめて提出せよ。小レポートが7件揃っていない場合は受理しません。提出場所は、社会開発棟1階 1504 室(計算機工学講座C)です。提出時に、簡単な質問を行います。内容に不備のある場合は受理しません。

□ 注意事項

他人のレポートをコピーするなどの不正がある場合には、見せた人も、見た人も未提出扱いとします。

最終課題レポートを提出してもらった後に、レポートの採点を行います。その際、不完全なレポートは、いい点数が付きません。その結果、合計点が60点に到達しないならば、不合格になります。最終課題はとても難しいものになっています。不安なところや疑問のあるところが沢山あると思います。ささいなデバッグ相談からでも質問を受け付けています。


(c) 2008.7.15 by tokuhisa