6 ブロックの入れ子構造

6.1 学習目標

6.2 繰り返しの入れ子

今回は繰り返しの入れ子(繰り返しの中に繰り返しがあること)に挑戦してみましょう。

6.2.1 たくさんの円を書くプログラム

次のプログラムを見てみましょう。

リスト 6.2.1.1 MultiCircle.java
  1: /*
  2:  * 複数の円を書くプログラム
  3:  * (角度を増やしていく版)
  4:  * 2003/06/08
  5:  * Yoshiaki Matsuzawa
  6:  */
  7: public class MultiCircle extends Turtle {
  8: 
  9: 	//起動処理
 10: 	public static void main(String[] args) {
 11: 		Turtle.startTurtle(new MultiCircle());
 12: 	}
 13: 
 14: 	//タートルを動かす処理
 15: 	public void start(){
 16: 	
 17: 		int i;//ループ用1
 18: 		int j;//ループ用2
 19: 		
 20: 		int length;//1回に進む距離
 21: 		int angle;//1回に曲がる角度
 22: 
 23: 		//円を10個書くためのループ
 24: 		i = 1;
 25: 		while(i <= 10){
 26: 			angle = i;
 27: 			length = 1;
 28: 
 29: 			//円を書くためのループ
 30: 			j = 1;
 31: 			while(j <= 360){
 32: 				fd(length);
 33: 				rt(angle);
 34: 				j = j + angle;
 35: 			}
 36: 			
 37: 			i = i + 1;
 38: 		}
 39: 		
 40: 	}
 41: 	
 42: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

図 6.2.1.1 たくさんの円を書くプログラム

前回、円を書くには繰り返しを使うことを習いました。今回は、さらにその円を何個も書くために、 もう一つ外側に繰り返しを作って、"繰り返しを繰り返す"ということをやっています。

6.2.2 ブロックの入れ子

ブロックは中括弧({})で囲まれた部分のことを言います。

下図のように、プログラムのifブロックやwhileブロックはいくつでも入れ子にすることができます。

図 6.2.2.1 ブロックの入れ子
コンパイルエラーに注意

ブロックを示す中括弧は必ず対応していなくてはなりません。 開き括弧が余ったり、閉じ括弧が余ったりすると、コンパイルエラーとなります。

括弧違いの場合、コンピュータはブロックを勘違いしてしまうので、 よけいなコンパイルエラーが(たくさん)でます。 たくさんのコンパイルエラーが一気にでたら、まず括弧の対応関係を確かめましょう。

6.2.3 インデント

第3回の時にも指摘しましたが、インデントをつけると括弧の対応関係やブロックの範囲が分かりやすくなります。 インデントがついていないソースは受理しません。

見やすいだけでなく、これができていないためにコンパイルエラーで動かない場合が非常に多いので、 注意してください。

図 6.2.3.1 インデント

論プロエディタでは、フォーマットをするとよいです。

6.3 奇数と偶数を判定する

剰余演算子(%)を使うと、割り算のあまりを求めることができます。 これを使うと、例えば奇数と偶数を判定することができます。

リスト 6.3.1 SquareAndTriangle.java
  1: /*
  2:  * 四角と三角を並べていくプログラム
  3:  * 2003/06/08
  4:  * Yoshiaki Matsuzawa
  5:  */
  6: public class SquareAndTriangle extends Turtle {
  7: 
  8: 	//起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new SquareAndTriangle());
 11: 	}
 12: 
 13: 	//タートルを動かす処理
 14: 	public void start(){
 15: 	
 16: 		int i;//ループ用1
 17: 		int j;//ループ用2
 18: 		
 19: 		int length = 50;//1辺の長さ
 20: 
 21: 		//8回繰り返す
 22: 		i = 0;
 23: 		while(i < 8){
 24: 		
 25: 			if(i % 2 == 0){//偶数なら
 26: 				//四角形を書く
 27: 				j = 1;
 28: 				while(j <= 4){
 29: 					fd(length);
 30: 					lt(90);
 31: 					
 32: 					j++;//jを1増やす([j = j + 1] の省略形)
 33: 				}
 34: 			}else{//奇数なら
 35: 				//三角形を書く
 36: 				j = 1;
 37: 				while(j <= 3){
 38: 					fd(length);
 39: 					lt(120);
 40: 						
 41: 					j++;//jを1増やす([j = j + 1] の省略形)
 42: 				}					
 43: 			}
 44: 			
 45: 			//次の図形を書く位置に移動
 46: 			up();
 47: 			rt(135);
 48: 			fd(length);
 49: 			rt(180);
 50: 			down();
 51: 			
 52: 			i++;//jを1増やす([i = i + 1] の省略形)
 53: 		}
 54: 		
 55: 	}
 56: 	
 57: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

図 6.3.1 三角形と四角形を交互に書くプログラム

6.4 応用:花を描くプログラム

応用として、花を描くプログラムを考えてみましょう。

図 6.4.1 花を書くプログラム

6.4.1 花びらを描く

花を描くには、まず花びらをかいて、それを繰り返す必要があります。

図 6.4.1.1 花びらを書くプログラム
リスト 6.4.1.1 Petal.java
  1: /*
  2:  * 花びらを書くプログラム
  3:  * 2003/06/08
  4:  * Yoshiaki Matsuzawa
  5:  */
  6: public class Petal extends Turtle {
  7: 
  8: 	//起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new Petal());
 11: 	}
 12: 
 13: 	//タートルを動かす処理
 14: 	public void start(){
 15: 	
 16: 		int i;//ループ用
 17: 
 18: 		int length = 1;
 19: 		int angle = 1;
 20: 		
 21: 		//円弧を書く
 22: 		i = 1;
 23: 		while(i <= 120){
 24: 			rt(angle);
 25: 			fd(length);
 26: 			i = i + angle;
 27: 		}
 28: 		
 29: 		//次の円弧の角度へ
 30: 		rt(60);
 31: 		
 32: 		//円弧を書く
 33: 		i = 1;
 34: 		while(i <= 120){
 35: 			rt(angle);
 36: 			fd(length);
 37: 			i = i + angle;
 38: 		}
 39: 
 40: 	}
 41: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

6.4.2 花を描く

花びらを描くには繰り返しが必要で、花を描くにはさらにそれを繰り返す必要があります。 以下のように、繰り返しの入れ子を使います。

リスト 6.4.2.1 Flower.java
  1: /*
  2:  * 花を書くプログラム
  3:  * 2003/06/08
  4:  * Yoshiaki Matsuzawa
  5:  */
  6: public class Flower extends Turtle {
  7: 
  8: 	//起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new Flower());
 11: 	}
 12: 
 13: 	//タートルを動かす処理
 14: 	public void start(){
 15: 	
 16: 		int i;//ループ用
 17: 		int j;//ループ用
 18: 
 19: 		int length = 1;
 20: 		int angle = 1;
 21: 		
 22: 		
 23: 		//6枚の花びらを書く
 24: 		i = 1;
 25: 		while(i <= 6){
 26: 		
 27: 			//円弧を書く
 28: 			j = 1;
 29: 			while(j <= 120){
 30: 				rt(angle);
 31: 				fd(length);
 32: 				j = j + angle;
 33: 			}
 34: 			
 35: 			//次の円弧の角度へ
 36: 			rt(60);
 37: 			
 38: 			//円弧を書く
 39: 			j = 1;
 40: 			while(j <= 120){
 41: 				rt(angle);
 42: 				fd(length);
 43: 				j = j + angle;
 44: 			}
 45: 			
 46: 			i++;
 47: 		}
 48: 	}
 49: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

ポイントは、花びらを書くループの外側にそれを6回繰り返すループをつくる (つまりループを入れ子にする)ことです。 「繰り返しを繰り返す」ためには、繰り返す繰り返しの外側に繰り返しループ を書く必要がありました。構造は以下のようになります。

図 6.4.2.1 花を書くプログラムの構造

以下に、よくある間違いの例を示します。

リスト 6.4.2.2 InvalidFlower.java
  1: /*
  2:  * 花を書くプログラム(うまくいかない版)
  3:  * 2003/06/08
  4:  * Yoshiaki Matsuzawa
  5:  */
  6: public class InvalidFlower extends Turtle {
  7: 
  8: 	//起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new InvalidFlower());
 11: 	}
 12: 
 13: 	//タートルを動かす処理
 14: 	public void start(){
 15: 	
 16: 		int i;//ループ用
 17: 		int j;//ループ用
 18: 
 19: 		int length = 1;
 20: 		int angle = 1;
 21: 		
 22: 		
 23: 		//6枚の花びらを書く
 24: 		i = 1;
 25: 		while(i <= 6){
 26: 			rt(angle);
 27: 			fd(length);
 28: 			i = i + angle;
 29: 		}
 30: 		
 31: 		//円弧を書く
 32: 		j = 1;
 33: 		while(j <= 120){
 34: 			rt(angle);
 35: 			fd(length);
 36: 			j = j + angle;
 37: 		}
 38: 		
 39: 		//次の円弧の角度へ
 40: 		rt(60);
 41: 		
 42: 		//円弧を書く
 43: 		j = 1;
 44: 		while(j <= 120){
 45: 			rt(angle);
 46: 			fd(length);
 47: 			j = j + angle;
 48: 		}
 49: 
 50: 	}
 51: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

これがうまくいかない理由が説明できるでしょうか? 以下に、このプログラムの構造を示しますので、 うまくいく方と比較してみましょう。

図 6.4.2.2 うまくいかない花を書くプログラムの構造

このように、入れ子を作る時には、{}の位置に注意する必要があります。

6.5 練習問題

6.5.1 問題1:四角形と三角形を交互に100個描くプログラムを作ろう

図 6.5.1.1 四角形と三角形を交互に100個描くプログラム

ヒント: 下の四角形を100個描くプログラムを参考にせよ

リスト 6.5.1.1 HandredBlock.java
  1: /*
  2:  * 四角を並べていくプログラム
  3:  * 2003/06/08
  4:  * Yoshiaki Matsuzawa
  5:  */
  6: public class HandredBlock extends Turtle {
  7: 
  8: 	//起動処理
  9: 	public static void main(String[] args) {
 10: 		Turtle.startTurtle(new HandredBlock());
 11: 	}
 12: 
 13: 	//タートルを動かす処理
 14: 	public void start(){
 15: 	
 16: 		int i;//ループ用1
 17: 		int j;//ループ用2
 18: 		int k;//ループ用3
 19: 		
 20: 		int length = 10;//四角の大きさ
 21: 		int margin = 5;//隣の四角との間隔
 22: 
 23: 		//縦に10回繰り返すためのループ
 24: 		i = 1;
 25: 		while(i <= 10){
 26: 		
 27: 			//横に10回繰り返すためのループ
 28: 			j = 1;
 29: 			while(j <= 10){
 30: 			
 31: 				//四角形を書くためのループ
 32: 				k = 1;
 33: 				while(k <= 4){
 34: 					fd(length);
 35: 					rt(90);
 36: 					
 37: 					k++;
 38: 				}
 39: 				
 40: 				//四角形を書いたら隣に移動
 41: 				up();
 42: 				rt(90);
 43: 				fd(length);
 44: 				fd(margin);
 45: 				lt(90);
 46: 				down();
 47: 
 48: 				j++;
 49: 			}
 50: 			
 51: 			//横一列が終ったら左下に移動
 52: 			up();
 53: 			lt(90);
 54: 			fd((length + margin) * 10);
 55: 			lt(90);
 56: 			fd(length + margin);
 57: 			rt(180);
 58: 			down();
 59: 			
 60: 			i++;
 61: 		}
 62: 		
 63: 	}
 64: 	
 65: }

下のボタンを押すと、このプログラムが実行できます。 ここをクリックすると、プログラムをダウンロードできます。

図 6.5.1.2 四角形を10×10描くプログラム

6.5.2 問題2:貝殻を描くプログラムを作ろう

図 6.5.2.1 貝殻を描くプログラム

ヒント:四角を大きくしながら、角度を変えていく ( 繰り返しの変数を利用すること )

6.5.3 問題3:タイヤを描くプログラムを作ろう

図 6.5.3.1 タイヤを描くプログラム

ヒント:ずらす角度は8度, 四角の1辺は10歩にするとうまくいく。 真ん中の円は多少ずれていても構わない。

6.5.4 問題4:ドラえもんを描くプログラムを作ろう

図 6.5.4.1 ドラえもんを描くプログラム

ノーヒント

6.5.5 問題5:キーボードを描くプログラムを作ろう

図 6.5.5.1 キーボードを描くプログラム

ノーヒント