MTでPerlを学ぶ(その11・for文による繰り返し)

「MTでPerlを学ぶ」の第11回をお送りします。
今回は、for文を使った繰り返しを解説します。

1.繰り返しについて

プログラムの中では、同じ処理を何度か繰り返して行うことは非常に多いです。
例えば、ブログで言えば、最近の記事を順に出力する処理は、「記事を1つ読み込んで出力する」という処理を繰り返して行われます。

2.for文を使った繰り返し

Perlには、繰り返しを行う命令として、for/foreach/while/until/do~while/do~untilがあります。
これらの中で、forは繰り返し回数があらかじめ分かっているときによく使います。

一定回数の繰り返しは、以下のように書くことが多いです。

for (変数 = 0; 変数 < 繰り返し回数; 変数++) {
    繰り返す処理
}

「変数」には、繰り返し回数をカウントするための変数を指定します。
あらかじめ変数を宣言しておいても良いですし、また「for (my $i = 0;・・・)」のようにfor文の中で宣言しても構いません。
ただし、for文の中で変数を宣言した場合、その変数はfor文の繰り返しの中でだけ使うことができます。

例えば、同じ処理を10回繰り返したいとします。
また、繰り返し回数を変数$iでカウントするとし、$iはすでに宣言されているとします。
この場合、for文は以下のように書きます。

for ($i = 0; $i < 10; $i++) {
    繰り返す処理
}

また、変数$iを繰り返しの中だけで使いたい場合は、上のfor文を以下のように変えます。

for (my $i = 0; $i < 10; $i++) {

なお、「変数++」という書き方は、「変数の値を1増やす」ことを意味します。
ちなみに、変数の値を変化させる方法には、以下のようなものもあります。

書き方の例内容
$x--;変数$xの値を1減らす
$x += 2;変数$xの値を2増やす
$x -= 3;変数$xの値を3減らす
$x *= 2;変数$xの値を2倍する
$x /= 3;変数$xの値を3分の1にする

3.for文を使った例

以下のリストは、for文を使って「サイコロを10回振る」というプログラムを作った例です。

print "<ul>\n";
for (my $i = 0; $i < 10; $i++) {
    my $x = int(rand(6)) + 1;
    print "<li>$i回目 : サイコロは$x</li>\n";
}
print "</ul>\n";

上記を含むインデックステンプレートのサンプルをダウンロード

また、このプログラムを実行すると、以下のようなHTMLが出力されます。
ただし、「サイコロは」の後の数は、プログラムを実行するたびにランダムに変化します。

<ul>
<li>0回目 : サイコロは6</li>
<li>1回目 : サイコロは3</li>
<li>2回目 : サイコロは3</li>
<li>3回目 : サイコロは2</li>
<li>4回目 : サイコロは4</li>
<li>5回目 : サイコロは6</li>
<li>6回目 : サイコロは2</li>
<li>7回目 : サイコロは3</li>
<li>8回目 : サイコロは2</li>
<li>9回目 : サイコロは2</li>
</ul>

このプログラムの各行の意味は、以下の通りです。

1行目

「<ul>」タグと、改行(\n)を出力します。

2行目

for文で10回の繰り返しを行います。
変数$iで繰り返しの回数をカウントします。

3行目

1~6のランダムな数を求め、変数$xに代入します。

「rand」はPerlの組み込み関数で、「rand(★)」とすると、0以上★未満のランダムな数を作りだします。
また、「int」もPerlの組み込み関数で、「int(☆)」とすると、☆の小数点以下を切り捨てる働きをします。

「int(rand(6))」は、「0以上6未満の乱数を求め、その小数点以下を切り捨てる」という動作になります。
したがって、この部分で0、1、2、3、4、5のどれかを得ることができます。

また、「int(rand(6))」の後に「+ 1」がありますので、得られた数に1を足すことになり、結果として1、2、3、4、5、6のどれかを得ることができます。

4行目

「<li>○回目 : サイコロは□</li>」と、改行(\n)を出力します。
「○」の箇所は変数$iになっていますので、繰り返しの回数が出力されます。
また、「□」の箇所は変数$xになっていますので、サイコロの数が出力されます。

6行目

「</ul>」タグと、改行(\n)を出力します。

4.問題

サイコロのプログラムを改造して、以下のように出力するプログラムを作ってみてください。

<ul>
<li>1回目 : -3戻る : 現在位置 後ろに-3</li>
<li>2回目 : 3進む : 現在位置 スタート</li>
<li>3回目 : そのまま : 現在位置 スタート</li>
<li>4回目 : -2戻る : 現在位置 後ろに-2</li>
<li>5回目 : -1戻る : 現在位置 後ろに-3</li>
<li>6回目 : -2戻る : 現在位置 後ろに-5</li>
<li>7回目 : -1戻る : 現在位置 後ろに-6</li>
<li>8回目 : 3進む : 現在位置 後ろに-3</li>
<li>9回目 : 2進む : 現在位置 後ろに-1</li>
<li>10回目 : 3進む : 現在位置 前に2</li>
</ul>

上の出力例は、以下のような処理を想定したものです。

  • カードを10回引きます。
  • カードには-3、-2、-1、0、1、2、3のどれかの数字が書いてあります。
  • プラスの数字が出たら、その数だけ前に進みます。
  • マイナスの数字が出たら、その数だけ後ろに戻ります。
  • 10回のそれぞれで、繰り返しの回数と、進む(戻る)数、そして現在の位置を表示します。

    0のカードを引いたときは、進む(戻る)数の代わりに「そのまま」と表示します。

    また、現在の位置が0(スタート位置)に戻ったときは「スタート位置」と表示します。

問題の回答は後日にこのブログにアップします。