長文を流したいけど皆さんのTLを汚したくないときに使う場所です
[10]  [9]  [8]  [7]  [6]  [5]  [4]  [3]  [2]  [1
時間のある時に書いていきます。今回もAOAI.plを解き放ちましょう

≪前回までのあらすじ≫
システムの準備をして、継続と設定を読み込み、戦闘前行動に入りました

≪今回のめにゅう≫
224~401行……メインループ!!(配列編)



昨日に引き続き解説します
今回は配列の話

261~267行目
if($act == 11){
# オプション
# 初期化
for (my $i=13; $i<19; $i++){
$machine_list[$eno][$i] = -1;
}
}

オプションパーツの内部に「-1」という数字を入れて初期化し、何もオプションパーツを装備していない状態にする処理です
なぜ最初に持ってくるかというと、この後出てくる処理に、「継続内容が空欄だと、処理を省略する」という処理があるからです。
前回オプションを装備して、今回白紙継続すると、空欄なのでオプションアセンブル処理が省略され、白紙にしたはずなのに前回のオプションを装備している! というバグを防ぎます

$actが11のときに分岐する処理です。11とはすなわち、オプションの設定です
これは非常にまずいプログラミングです。11番目が何を意味するかパッと分からないし、オプションの順番が11番目じゃなくなった際、この分岐を修正しないと予期せぬバグを生むからです
これを魔法の数字、マジックナンバーと言います

FIX案)
$actを文字にしてしまいましょう

if($act eq "オプション"){

分かりやすくなりましたね。文字が同じか判定する場合、== ではなく eq を使います。文字になったイコールです
まってよ! $actが数字じゃなくなったら、229行目

for(my $act=1; $act<19; $act++) {

がバグるじゃん! そうです。その通りです。この行は数字を1から18まで巡回する命令なので、勝手に文字にしたら崩壊します
なので、ここを変えます。その前に、配列を用意します

◆配列とは?

タンスです。変数の存在を知っている方は多いかもしれません[要出展]。変数とは、数字や文字を入れておく箱です。普通変数には一つの数字か、一つにつながった文字しか入りません

$マークの付いた文字が、変数を意味します。$actがそうですね
$act = 1;
で$actという箱に「1」という数字を入れた状態になります。この数字は算数の要領で増減させることができます
$act += 1;
これが足し算です。先ほど$actに1を入れておけば、いまは2になっているはずです。ほかの計算式はググって調べてみてください。これをゲームにするには簡単です

$enemy_attack = 2;
$defence = 2;
$hp = 10;

$hp -= $enemy_attack * 2 - $defence;

少しググっただけで、以前は全く意味不明なはずの暗号が読めるようになったはずです。この暗号を見たあなたは

攻撃力2の敵がHP10で防御力2のキャラにダメージを与えている図

が浮かんできたはずです。浮かんでこない場合、感度を3000倍にしてみてください
ダメージ量さえわかりますね、つまり

攻撃力を2倍した数値から防御力を引いた数がダメージ

ということが分かります。実際にはこうすると防御力の高すぎるキャラが被攻撃で回復し始めたり(面白そう!)、攻撃力と防御力が同じ数値だけ伸びていくとダメージ量のインフレがすごくなって防御力が意味なくなったりします

◆忘れてない? 配列とは……

君のこと忘れてないよ……! 変数を知ったあなたは、配列をすぐに理解することができるはずです。つまり、変数がたくさん並んだのが配列です。変数を箱とするならば、箱がたくさん入っているタンスが、まさに配列というべきでしょう

$enemy_attack = 2;
$defence = 2;
$hp = 10;

$hp -= $enemy_attack * 2 - $defence;

これは攻撃力と防御力とHPしかないのでまだ把握できますが、無数のステータスを用意した場合、変数を無数に作りすぎてパンクしそうになってしまいます。なので、キャラデータという配列を作ってみましょう

# キャラステータス
my @chara_data;

# HP
$chara_data[0] = 10;
# 攻撃力
$chara_data[1] = 2;
# 防御力
$chara_data[2] = 2;

配列を意味する記号は@です。でも、実際に数値を入れてるときは、$ですよね? これはタンスの中の箱一つ一つを開けて、変数の状態にしてから数値を入れているイメージです
[0]~[2]がタンスの引き出しの順番です

配列できた! これでキャラのデータは万全……いいえ、もうひと手間! これだと一人のデータしか扱えません

# キャラステータス
my @chara_data;
my $eno = 1;

# HP
$chara_data[$eno][0] = 10;
# 攻撃力
$chara_data[$eno][1] = 2;
# 防御力
$chara_data[$eno][2] = 2;

引き出しが……増えた! これは2次配列と言って、先ほどの配列が引き出し縦一列のタンスだとすると、この2次配列は縦一列のタンスが横に何列も並んでいる壁だと思ってください
要するに、キャラ一人一人にステータスをいくつもいれられるタンスが与えられたと思ってください

さて、より進歩的な戦闘処理を組んでみます

my @chara_data;
my $atk_eno = 1;
my $def_eno = 20;

# 攻撃側HP
$chara_data[$atk_eno][0] = 10;
# 攻撃側攻撃力
$chara_data[$atk_eno][1] = 2;
# 攻撃側防御力
$chara_data[$atk_eno][2] = 2;

# 防御側HP
$chara_data[$def_eno][0] = 10;
# 防御側攻撃力
$chara_data[$def_eno][1] = 2;
# 防御側防御力
$chara_data[$def_eno][2] = 2;

$chara_data[$def_eno][0] -= $chara_data[$atk_eno][1] * 2 - $chara_data[$def_eno][2];

目を閉じて、光景を思い浮かべてください。そう、見えてきましたね……? eno1のキャラがeno20のキャラを殴っている姿が……それに必死に耐えているeno20のキャラが!

◆さて、何をしていたんだっけ?

そう、マジックナンバーを減らすFIX案です。結論はこうです
226行あたりに

my @act_name;
$act_name[1] = "日記前行動";
$act_name[2] = "日記";
$act_name[3] = "訓練";
$act_name[4] = "送品";
$act_name[5] = "送金";
…etc

という風に戦闘前行動のメニューを指定しておき(もっと簡略化する方法はありますが割愛)、229行目を

for(my $act_id=1; $act_id<19; $act_id++) {

と名前を変えて234行目あたりに

$act = $act_name[$act_id] ;

を挟めば、メニューを呼び出すことが可能です。これならば、マジックナンバーである$act_idの指定するメニューが一塊になっているので順番を修正しやすいです
基本的に変えなくてはいけないマジックナンバーがあちこちに散らばっていると地獄です。できるだけまとめておきましょう

≪今回のまとめ≫
配列が勝利のカギ!

配列は絶対に避けては通れない知識なので、じっくりと説明しました。もっといいコードを書ける人も、配列を分かりやすく説明しているサイトもいろいろあるので、調べてみると楽しいはずです。やりたいことやったもん勝ちです。青春なら……

拍手[2回]

この記事にコメントする
color
name
subject
mail
url
comment
pass   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
プロフィール
HN:
霧のひと
Webサイト:
性別:
男性
P R

photo byAnghel. 
◎ Template by hanamaru.