プログラミング実習I : 課題 R8
目標
- 教科書の 7 章の内容を理解し,配列や Vector の概念や使い方を理解する
R8_1
準備
- 教科書 p.124 から p.137 までをよく読み,7.1 節から 7.3 節までの内容を理解する
課題
- 以下の質問とその回答( 1 〜 3 行程度 )をレポートにまとめよ(プログラムの作成は行わなくてよい)
- 配列とは何か? 教科書にどのように書かれてあったか答えよ
- リスト 7.3 で,配列変数はどれか?(配列変数の名前を答えよ) また,その配列変数の添字の範囲を答えよ
- あるメソッド内で int の配列変数 data (要素数 10) を使いたい.そのような配列変数 data を作るためには,プログラムでどのように記述したらよいか?
- リスト 7.3 と リスト 7.6 を比べて,配列を用いるメリットを答えよ.
- リスト 7.7 で例外が発生した理由を答えよ.また,例外が発生しなくするためにはどのようにプログラムを修正したらよいか?
- 配列が持つ length フィールドにはどのような値が格納されているか?
R8_2
準備
- R7_2 で作成した Face.java および DisplayFaceObject.java をコピーする
- ※ R7_3 で作成したものでもよい
課題
- R7_2 で作成した Face.java を修正し,R8_2 で作成する Face クラスの仕様 を満たすように修正せよ
- リスト 7.10 を参考に,以下の図のように 10 個の顔が移動するアニメーションを実行する DisplayFaceObject.java を作成せよ
条件
- アニメーションに関して,以下を満たす
- アニメーション総コマ数は 150 とする
- ※ リスト 7.10 では 30 となっている
- sleep に与える待機時間を 0.1 とする (リスト 7.10 と同じ)
- アニメーション総コマ数は 150 とする
- 10 個の顔(Face オブジェクト)に関して,以下を満たす
- ※ 10 個の顔を 0番, 1 番, … , 9 番の番号で呼ぶ
- j 番の顔は以下とすること
- 顔の左端と上端の座標の初期値: (20, 80 + 24*j)
- 変化量: (j を 3 で割った余り) + 5
- 幅と高さ: (10, 12)
- ウィンドウの右端から消えたら,左端に移動すること
- 顔の左端の \(x\) 座標が 400 となったら 0 にすること(Face クラスの moveOrigin メソッドを呼出せばよい)
- 配列を用いて,Face オブジェクトを管理すること
提出物
- 作成した Face.java
- 作成した DisplayFaceObject.java
R8_2 で作成する Face クラスの仕様
フィールド
- x : 顔の左端の \(x\) 座標(int)
- y : 顔の上端の \(y\) 座標(int)
- vx : 顔の左上 \(x\) 座標の変化量 (R8_2 で追加)
- w : 顔の幅(int)
- h : 顔の高さ(int)
コンストラクタ
- public Face(int x, int y, int vx, int w, int h)
- 引数
- x : 顔の左上の \(x\) 座標
- y : 顔の左上の \(y\) 座標
- vx : 顔の左上 \(x\) 座標の変化量 (R8_2 で追加)
- w : 顔の幅
- h : 顔の高さ
- 動作
- 引数で与えられた値を,各フィールドに代入する
- 引数
メソッド
- public void draw(MyFrame2 frame)
- 引数
- frame: MyFrame2 クラスのオブジェクト
- 動作
顔を以下の図のレイアウトで描画する
図2: 顔のレイアウト
- 引数
- public void move() (R8_2 で追加)
- 動作
- 顔の左上 \(x\) 座標 x を vx だけ変化させる
- 動作
- public void moveOrigin() (R8_2 で追加)
- 動作
- 顔の左端の \(x\) 座標 x を 0 にする(ウィンドウの左端に移動する)
- 動作
R8_3
準備
- 教科書 p.138 から p.143 までをよく読み,7.4 節の内容を理解する
課題
- 以下の質問とその回答( 1 〜 3 行程度 )をレポートにまとめよ(プログラムの作成は行わなくてよい)
- Vector オブジェクトとは何か? 配列との違いが分かるように,p138 の冒頭の記述,もしくは Web 検索を行った結果に基づいて答えよ
- 図 7.4 に示されているエラーメッセージの内容と,解決方法を答えよ.
- Vector が格納している要素数を取得するには,どのメソッドを呼び出せばよいか?
- あるメソッド内で Ball クラスの Vector オブジェクト balls を使いたい.そのような Vector オブジェクト balls を作成するためには,プログラムでどのように記述したらよいか?
- 質問 4 で作成した Vector オブジェクト balls に,Ball クラスのオブジェクトを追加するにはプログラムでどのように記述したらよいか?
R8_4
準備
- R7_4 で作成した Car.java および DisplayCarObject.java をコピーせよ
課題
- リスト 7.14 を参考に,以下の図のように,時間とともに自動車が生成され,生成された自動車が垂直線を越えるまで移動するアニメーションを実行する DisplayCarObject.java を作成せよ
- R7_4 と同様に,垂直線(x = b) を境に左側のエリアを 0,右側のエリアを 1 としている
- この条件 を満たすように DisplayCarObject.java を作成すること
- ※ 図 3 では,便宜上,以下を表示しているが,提出するプログラムでは表示させる必要はない
- 時刻 i
- 各自動車の番号
- 各エリアで生成された順に番号を付けている
- ※ R7_4 の Car クラスではこのような表示はできない
- エリア 0 で生成された自動車の台数 nc0
- エリア 1 で生成された自動車の台数 nc1
実行例
図3: R8_4 で作成するプログラムで表示されるアニメーション(ループ再生)の例 (学籍番号を 5 で割った余り n = 4 の場合)
条件
- R7_4 と同様に,ウィンドウの幅と高さを (600, 500) にすること
- run メソッドの冒頭で setSize(600, 500) を実行すること
- アニメーションに関して,以下とすること
- アニメーション総コマ数 = 150
- sleep に与える待機時間 = 0.1
- R7_4 と同様に,垂直線(x = b) の b は 300 とすること
- drawLine を用いて,垂直線 (x = 300) を描画すること
- 色は好きな色でよい
- drawLine(300, 0, 300, 500) と書けばよい
- drawLine を用いて,垂直線 (x = 300) を描画すること
- 自動車(Car クラスのオブジェクト)に関して,以下とすること
- 以下の 2 つの Vector を作成し,それぞれの自動車を管理すること
- cars0 : エリア 0 で生成された自動車を管理する Vector オブジェクト
- cars1 : エリア 1 で生成された自動車を管理する Vector オブジェクト
- 時刻 i が 7 の倍数である場合,以下の処理を行うこと
- エリア 0 に以下の自動車を 1 台作成し,cars0 に追加する
- 自動車の中心座標の初期値を (50 + 10 * n, 350 + 10 * n) とすること(R7_4 での自動車 0 と同じ)
- ※ n は,学籍番号を 5 で割った余り
- 幅と高さは (32, 24) とすること (R7_4 と同じ)
- 中心座標の変化量を (n+5, -v0) とすること
- ※ n は,学籍番号を 5 で割った余り
v0 は,0 〜 9 の乱数(整数) とする.Math.random() を用いて以下を書けばよい
v0 = (int)(Math.random()*10)
- ※ Math.random() は,0 以上 1 未満の範囲の擬似乱数を返すメソッド(参考:教科書 p211)
- ※ Math.random() は,呼び出す度に異なる値を返す.自動車を生成するたびに,Math.random()を呼出すこと.
- 自動車の中心座標の初期値を (50 + 10 * n, 350 + 10 * n) とすること(R7_4 での自動車 0 と同じ)
- エリア 1 に以下の自動車を 1 台生成し,cars1 に追加すること
- 中心座標の初期値を (450 - 10 * n, 250 - 10*n) とすること (R7_4 での自動車 1 と同じ)
- ※ n は,学籍番号を 5 で割った余り
- 幅と高さは (32, 24) とすること (R7_4 と同じ)
- 中心座標の変化量を (-n-5, v1) とすること
- ※ n は,学籍番号を 5 で割った余り
- v1 は,0 〜 9 の乱数(整数)とする.計算方法は上を参照
- 中心座標の初期値を (450 - 10 * n, 250 - 10*n) とすること (R7_4 での自動車 1 と同じ)
- エリア 0 に以下の自動車を 1 台作成し,cars0 に追加する
- それぞれの自動車の色は好きなものでよい
- 以下の 2 つの Vector を作成し,それぞれの自動車を管理すること
提出物
- 使用した Car.java
- 作成した DisplayCarObject.java
R8_5
準備
- Triangle クラス作成用のサンプルプログラム を Triangle.java にコピー & ペーストする
課題
- サンプルプログラムを修正し, R8_5 で作成する Triangle クラスの仕様 を満たす Triangle クラスを完成させよ
完成させた Triangle.java を実行すると以下のようなアニメーションが実行されることを確認せよ
- 三角形の描画がおかしい場合 → draw メソッド(TODO その 1) がうまくできてない
- 赤い十字が描画される場合 → move メソッド(TODO その 2) がうまくできてない
図4: Triangle.java を実行した時に表示されるテストアニメーション(ループ再生)
- 図 5 のように,時間とともに三角形(Triangle クラスのオブジェクト)が生成され,流星群(?)のようなアニメーションを実行する DisplayTriangleObject.java を作成せよ
条件
- DisplayTriangleObject クラスは MyFrame2 クラスを継承すること
- アニメーションに関して,以下とすること
- アニメーション総コマ数 = 200
- sleep に与える待機時間 = 0.1
- ウィンドウに関して
- 背景を黒い四角形で塗り潰すこと(以下の手順を参考にする)
- プログラムの 1 行目に 「import java.awt.Color;」を追加する
run メソッドの冒頭で,以下を追加する
bgColor = Color.black;
- 背景を黒い四角形で塗り潰すこと(以下の手順を参考にする)
- 三角形に関して,以下とすること
- 時刻 t が 5 の倍数である場合,以下の星(Triangle クラスのオブジェクト)を生成すること
- 三角形の中心座標の初期値を (30 + 10 * n, 50) とすること
- ※ n は,学籍番号を 5 で割った余り
- 三角形の中心座標の変化量 vx および vy の初期値をそれぞれ 0 から 9 までの乱数(整数)とすること
- 三角形の大きさは 10 とすること
- 三角形の描画および移動は,Trinangle クラスの draw メソッドおよび move メソッドをそれぞれ呼び出して行うこと
- 三角形は黄色(255, 255, 0)で描画すること
- 三角形の中心座標の初期値を (30 + 10 * n, 50) とすること
- 生成した Triangle クラスのオブジェクトは,それを管理する Vector に追加すること
- DisplayTriangleObject クラスの run メソッド内にて行うこと
- 時刻 t が 5 の倍数である場合,以下の星(Triangle クラスのオブジェクト)を生成すること
提出物
- 作成した Triangle.java
- 作成した DisplayTriangleObject.java
Triangle クラス作成用のサンプルプログラム
以下のサンプルコードは,三角形を描画する Triangle クラスを作成しようとしているところである
- TODO にある部分を 仕様 を満たすように埋めて,完成させよ
- その 1 : (draw メソッド内) 頂点間に drawLine を用いて線を引く
- その 2 : (move メソッド内) 三角形の移動を加速させる(変化量 vx および vy をそれぞれ 1 ずつ増やす)
import java.awt.Color; // bgColor = Color.black の実行に必要 public class Triangle { int x, y; // 三角形の中心座標 int nPoints ; // 三角形の頂点数 double[] xPoints; // 三角形の頂点 x 座標を格納する配列 double[] yPoints; // 三角形の頂点 y 座標を格納する配列 int vx, vy; // 三角形の中心座標の変化量 int size; // 三角形の大きさ /** コンストラクタ */ public Triangle(int x, int y, int vx, int vy, int size) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.size = size; nPoints = 3; // 三角形なので頂点数に 3 を代入している xPoints = new double[nPoints]; // double 型の配列(要素数 nPoints)を作成 yPoints = new double[nPoints]; // double 型の配列(要素数 nPoints)を作成 setPoints(); // 頂点の座標を更新 } /** 中心座標(x, y) を持つ三角形の頂点座標を設定する */ public void setPoints() { // 頂点 0 の座標 xPoints[0] = x ; yPoints[0] = y - size; // 頂点 1 の座標 xPoints[1] = x + (int)(1.732*size/2); yPoints[1] = y + size/2; // 頂点 2 の座標 xPoints[2] = x - (int)(1.732*size/2); yPoints[2] = y + size/2; } /** 頂点座標の配列 xPoints および yPoints を用いて三角形を描画 */ public void draw(MyFrame2 frame) { // TODO: (その 1.1) 以下の手順で線を引く for 文を書く // 頂点 0 から頂点 1 に drawLine で線を引く // 頂点 1 から頂点 2 に drawLine で線を引く // : // 頂点 nPoints-2 から頂点 nPoints-1 に drawLine で線を引く // TODO: (その 1.2) 頂点 nPoints-1 から頂点 0 に drawLine で線を引く } /** 中心座標(x, y) を (vx, vy) だけ変化させる */ public void move() { x += vx; y += vy; setPoints(); // 頂点の座標を再設定 // TODO: (その 2) 三角形の移動を加速させる(変化量 (vx, vy) をそれぞれ 1 ずつ増やす) } /** テスト用の main メソッド(一つの三角形が流れ落ちていく) */ public static void main(String[] args) { int ww = 400, wh = 400; // ウィンドウの幅と高さ MyFrame2 f = new MyFrame2(); f.bgColor = Color.black; //背景色を黒に変更 int x = 50, y = 50; int vx = 0, vy = 0; int size = 20; Triangle s = new Triangle(x, y, vx, vy, size); // Triangle クラスのオブジェクト作成 int animeT = 20; double wtime = 0.1; for(int t = 0; t < animeT; t++) { f.clear(); // 三角形を黄色で描画 f.setColor(255,255, 0); s.draw(f); // 正しい中心座標 (x, y) を通る赤い十字を描画(軌道確認用) f.setColor(255, 0, 0); f.drawLine(x, 0, x, wh); f.drawLine(0, y, ww, y); // 三角形の中心座標を通る緑の十字を描画(レイアウト確認用) f.setColor(0, 255, 0); f.drawLine(s.x, 0, s.x, wh); f.drawLine(0, s.y, ww, s.y); x += vx; y += vy; vx += 1; vy += 1; // 三角形の移動 s.move(); f.sleep(wtime); } } }
- TODO にある部分を 仕様 を満たすように埋めて,完成させよ
R8_5 で作成する Triangle クラスの仕様
フィールド
- x : 三角形の中心 \(x\) 座標(int)
- y : 三角形の中心 \(y\) 座標(int)
- nPoints : 三角形の頂点数 (int)
- xPoints : 三角形の各頂点の \(x\) 座標(double の配列)
- yPoints : 三角形の各頂点の \(y\) 座標(double の配列)
- vx : 三角形の中心 \(x\) 座標の変化量(int)
- vy : 三角形の中心 \(y\) 座標の変化量(int)
- size : 三角形の大きさ(int)
コンストラクタ
- public Triangle(int x, int y, int vx, int vy, int size)
- 引数
- x : 三角形の中心 \(x\) 座標(int)
- y : 三角形の中心 \(y\) 座標(int)
- vx : 三角形の中心 \(x\) 座標の初期変化量(int)
- vy : 三角形の中心 \(y\) 座標の初期変化量(int)
- size : 三角形のサイズ
- 動作
- 引数で与えられた値を,各フィールドに代入する
- 頂点数 nPoints を 3 に設定する
- double の配列(要素数 nPoints)を 2 つ作成し,xPoints と yPoints にそれぞれ代入する
- 引数
メソッド
- public void setPoints()
- 動作
- 座標 (x, y) を中心として,三角形の各頂点の座標を計算し,xPoints および yPoints に代入する
- size に応じて大きさが変わるようになっている
- 座標 (x, y) を中心として,三角形の各頂点の座標を計算し,xPoints および yPoints に代入する
- 動作
- public void draw(MyFrame2 frame)
- 引数
- frame : MyFrame2 クラスのオブジェクト
- 動作
- xPoints および yPoints から三角形を書く (TODO 1)
- for 文 と drawLine メソッドを組み合わせること
- xPoints および yPoints から三角形を書く (TODO 1)
- 引数
- public void move()
- 動作
- 三角形の中心座標 (x, y) を変化量 (vx, xy) だけ変化させる
- xPoints と yPoints を再設定する(setPoints メソッドを呼び出す)
- vx および vy をそれぞれ 1 増加させる (TODO 2)
- 三角形の移動を加速させるため
- 動作
R8_6 (オプション)
準備
課題
- Star.java を,三角形ではなく星(五芒星 + 軌跡付き)を描画するように修正せよ
- 修正箇所は以下となる
- nPoints を 5 に変更
- setPoints メソッドを,星のだいたいの頂点を計算するように変更
- draw メソッドを,星に軌跡っぽいもの(参考:図 6)が描画されるように変更
- ※ 星やその軌跡は,綺麗である必要はない
- 手書きのものをベースにしてもよいので,星や軌跡っぽく見えるようにすること
- ただし,フィールド size で星の大きさを変えられるようにすること
- 修正箇所は以下となる
- DisplayStarOject.java で星(Star クラスのオブジェクト)を時間とともに生成し,図 6 のように流星群のようなアニメーションを実行するように修正せよ
- 条件は,R8_5 で作成するプログラムの条件 で「三角形」を「星」に読み替えたものとする
- ※ 図 6 では時刻 t を描画しているが,提出するプログラムでは描画しなくてもよい
図6: R8_6 で作成するプログラムで表示されるアニメーション(ループ再生)の例 (学籍番号を 5 で割った余り n = 4 の場合)
提出物
- 作成した Star.java
- 作成した DisplayStarObject.java
R8_7 (オプション)
準備
- R7_5 で作成した Ball.java および BallGame.java をコピーする
課題
- この条件 に従うように R7_5 で作成した BallGame.java を修正し,図 7 のように次々とランダムに円を発生させ,円に関する様々な量(それぞれの色を持つボールの個数,上下左右それぞれの辺にぶつかった回数) をカウントして表示できるようにせよ
- R7_5 と異なる条件には下線を引いている
- ※ 図 7 では時刻 t を表示しているが,作成するプログラムでは表示させなくてよい
図7: R8_7 で作成するプログラムで表示されるアニメーション(2倍速,ループ再生)の例
条件
- BallGame クラスは MyFrame2 クラスを継承すること
- アニメーションに関して以下とすること
- アニメーション総コマ数 animeT = 300
- sleep に与える待機時間 wtime = 0.1
- 四角形に関して以下とすること
- 左上の座標 (bx, by) = (50, 100)
- 幅と高さ (w, h) = (300, 230)
- 好きな色で描画すること
- ただし,円の色と背景色とは異なる色とすること
- 円に関して
- 時刻 t が 5 で割り切れる場合,以下の円(Ball クラスのオブジェクト)を新しく作成すること
- 中心座標の初期値 = 四角形内部のランダムな点
- ただし,\(x\) 座標および \(y\) 座標ともに 5 で割り切れること
- 中心座標の変化量の初期値 = 以下の中からランダムに選択
- (5, 5), (5, -5), (-5, 5), (-5, -5)
- 半径 = 5
- 色 = 赤
- 中心座標の初期値 = 四角形内部のランダムな点
- 四角形の辺に円がぶつかったら円が跳ね返ってみえるように,中心座標 (x, y) の変化量(dx, dy) を適切に変化させること
- ただし,跳ね返った後に,円の移動量は変化しないものとする
- 四角形の辺に円がぶつかったら,円の色を別の色に変化させること
- 時刻 t が 5 で割り切れる場合,以下の円(Ball クラスのオブジェクト)を新しく作成すること
- ウィンドウに表示する量
- それぞれの色(赤 or 黄色 or 青)を持つ円の数
- 四角形のそれぞれの辺(上辺, 右辺,下辺,左辺)にぶつかった回数
提出物
- 使用した Ball.java
- 作成した BallGame.java
R8_8 (オプション)
課題
- 1 次元セルオートマトンを勉強して,その内容を簡単にレポートにまとめよ.
- 1 次元セルオートマトンを以下のルールに従って m 世代まで計算し,図 7 のようにアニメーションで表示するプログラム(CA.java) を作成せよ.
- ※ 最初の世代を 1 とする
- ※ 確認が容易になるように,図 8 のように世代の番号も表示せよ
- ルール(※ n は学籍番号の下 1ケタ)
- n = 0 : ルール 54
- n = 1 : ルール 60
- n = 2 : ルール 62
- n = 3 : ルール 90
- n = 4 : ルール 94
- n = 5 : ルール 126
- n = 6 : ルール 150
- n = 7 : ルール 158
- n = 8 : ルール 182
- n = 9 : ルール 190
- 実行例
図8: 1 次元セルオートマトンのアニメーション(ループ再生)の例 (ルール 30)
提出物
- 作成した CA.java
- MyFrame2 クラスを継承すること
- 世代数 m = 20 としたものを提出すること
- ウィンドウサイズは,全ての世代が確認できるだけの十分な大きさとすること