これまでのプログラムでも,同種の要素を複数扱う必要があるプログラムがありました. 例えば,次の4匹の亀を扱うプログラムを考えてみましょう.
1: /* 2: * FourTurtles0.java 3: * 4匹の亀を動かすプログラム 4: * Created on 2012/01/07 5: * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved. 6: */ 7: public class FourTurtles0 extends Turtle { 8: 9: // 起動処理 10: public static void main(String[] args) { 11: Turtle.startTurtle(new FourTurtles0(), args); 12: } 13: 14: // タートルを動かす処理 15: public void start() { 16: hide(); 17: window.setSize(1100,500); 18: Turtle turtle0 = new Turtle(); 19: Turtle turtle1 = new Turtle(); 20: Turtle turtle2 = new Turtle(); 21: Turtle turtle3 = new Turtle(); 22: { //c//初期位置に移動する 23: turtle0.warp(100,100); 24: turtle1.warp(100,200); 25: turtle2.warp(200,100); 26: turtle3.warp(200,200); 27: } 28: { //for 29: int i = 0; 30: while(i < 360){ 31: { //一コマの処理をする 32: turtle0.fd(1); 33: turtle0.rt(1); 34: turtle1.fd(1); 35: turtle1.rt(1); 36: turtle2.fd(1); 37: turtle2.rt(1); 38: turtle3.fd(1); 39: turtle3.rt(1); 40: i++; 41: } 42: } 43: } 44: } 45: }
ここ をクリックすると、プログラムをダウンロードできます。
下のボタンを押すと、FourTurtles0プログラムが実行できます。
上記プログラムの問題は,カメを増やすたびに変数を追加したり,それに対応する動きのプログラムを書かなければならないことです. その結果,プログラム中に似たようなプログラムが繰り返しでてきてしまっています.
この章では,人間がプログラムを繰り返し書くのではなく,コンピュータに繰り返しをさせることで同様の目的を達成する方法を考えます.
必要なのは「集合データ構造」です.「集合データ構造」とは,同種のデータを一括してプログラムで扱うことの出来る仕組みで, 繰り返し(これはもう習得済みですね)と組み合わせることで,大量のデータを少量のプログラムで指示することが出来ます.
次のプログラムでは,タートルで使える集合データ構造の,ListTurtleクラスを使って4匹の亀を扱うプログラムを書いてみたものです.
1: /* 2: * FourTurtles.java 3: * 4匹の亀を動かすプログラム1(ListTurtle+カーソルで管理する) 4: * Created on 2012/01/07 5: * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved. 6: */ 7: public class FourTurtles1 extends Turtle { 8: 9: // 起動処理 10: public static void main(String[] args) { 11: Turtle.startTurtle(new FourTurtles1(), args); 12: } 13: 14: // タートルを動かす処理 15: public void start() { 16: hide(); 17: window.setSize(1100,500); 18: ListTurtle<Turtle> turtles = new ListTurtle<Turtle>(); 19: turtles.warpByTopLeft(100,300); 20: { //c//タートルを4匹作成する 21: int i = 0; 22: while(i < 4){ 23: turtles.add(new Turtle()); 24: i++; 25: } 26: } 27: { //c//初期位置に移動する 28: turtles.get(0).warp(100,100); 29: turtles.get(1).warp(100,200); 30: turtles.get(2).warp(200,100); 31: turtles.get(3).warp(200,200); 32: } 33: { //for 34: int i = 0; 35: while(i < 360){ 36: { //for 37: int j = 0; 38: while(j < 4){ 39: { //一コマの処理 40: turtles.moveCursorToNext(); 41: turtles.getObjectAtCursor().fd(1); 42: turtles.getObjectAtCursor().rt(1); 43: j++; 44: } 45: } 46: } 47: i++; 48: } 49: } 50: } 51: }
ここ をクリックすると、プログラムをダウンロードできます。
下のボタンを押すと、FourTurtles1プログラムが実行できます。
21行目でListTurtleを作っています.他のオブジェクトの生成と基本的には同じですが,ListTurtleに入れることの出来るオブジェクトの型を<>の中に書きます(2カ所).
ListTurtle<Turtle> turtles = new ListTurtle<Turtle>();
変数名は任意ですが,リストに入るものの名前の複数形にすると良いでしょう.
ListTurtleで使える基本的なメソッドとして,追加と削除,閲覧があります.
これらのメソッドを繰り返しを使って呼ぶことで,リストに入っている複数のオブジェクトすべてに対して,1行で命令をすることが出来ます.
ListTurtleでも,Java標準ライブラリでも,要素の番地は0番地から始まり,[要素数-1]番地まで存在します.
メモリアドレスの扱いやすさの関係から伝統的にC言語では0番地から始まる言語仕様で,C言語に影響を受けたJava言語も0番地から始まる仕様になっています.
しかしながら,人間にとっては1番地から始まり,[要素数]番地まで存在する方がわかりやすいので, 教育用言語を中心に1番地から始まるプログラミング言語も多く存在します.(例えばSmalltalk,Pascalなど).
戻り値を変数に格納するのではなく,メソッドを次々と呼び出すことが出来ます.例えば,30行目では次のようなプログラムがあります.
turtles.get(0).warp(100, 100);
これは,turtlesリストの0番目の要素を取り出して,その戻り値(1つめのタートル)に対して,warpメソッドを呼び出すという意味になります.
(戻り値が返ってくる限りは,1行で無制限にメソッドを呼び出すことが出来ます.)
ListTurtleで使える便利な機能として,カーソル機能があります.主な機能を以下に示します.
カーソルを進めて,カーソル位置のオブジェクトを取得して何か命令を行うことを繰り返すことによって,複数のオブジェクトすべてに対して,1行で命令をすることが出来ます.
(カーソルがリストの最後にあるときにカーソルを進めると,最初に戻るところが便利なところです.)
ListTurtleをアニメーションに応用した例を示します.
1: /* 2: * WalkingMan2.java 3: * 人が歩くアニメーションプログラム (List使用版) 4: * Created on 2012/01/07 5: * Copyright(c) 2011 Yoshiaki Matsuzawa, Shizuoka University. All rights reserved. 6: */ 7: public class WalkingMan2 extends Turtle { 8: 9: // 起動処理 10: public static void main(String[] args) { 11: Turtle.startTurtle(new WalkingMan2(), args); 12: } 13: 14: // タートルを動かす処理 15: public void start() { 16: hide(); 17: window.setSize(1100,500); 18: ListTurtle<ImageTurtle> holder = new ListTurtle<ImageTurtle>(true); 19: holder.warpByTopLeft(50,200); 20: { //アニメーション用画像を用意する 21: int i = 1; 22: while(i <= 8){ 23: holder.addLast(new ImageTurtle((("man" + i) + ".gif"))); 24: i++; 25: } 26: } 27: Turtle man = new Turtle(); 28: while(true){ 29: sleep(0.1); 30: { //1コマの処理 31: holder.moveCursorToNext(); 32: man.looks(holder.getObjectAtCursor()); 33: } 34: update(); 35: } 36: } 37: }
ここ をクリックすると、プログラムをダウンロードできます。
下のボタンを押すと、WalkingMan2プログラムが実行できます。
アニメーションをするときには,リストに入れたオブジェクトは,元の位置(キャンバス)からは消去して欲しいことがあります. そんなときに便利なのがListTurtleのautohideモードの指定です.autohideモードでは,リストは自動的にリストに入ってきたものをhide()してくれます.
autohideモードの指定には,new ListTurtleの所で,(true)の引数を与えます.
以下,「T」とは,リスト作成時に<[要素のクラス名]> で指定したクラスに置き換わることを示しています.
「0655アニメーションを作ろう」で作ったプログラムについて,ListTurtleを使って作り直してみてください.
ファイル名は「Zero655List.java」とすること.
「流れ星アニメーションを作ろう」で作ったプログラムについてListTurtleを使って作り直し,たくさんの星が流れるアニメーションを作ってみてください.
下のボタンを押すと、Snowsプログラムが実行できます。
ファイル名は「SuperShootingStar.java」とすること.