テキスト考 on ぷよクエ③

前回までで、ぷよクエの強いキャラ約 700のデータをを入手し、それを各色別に所定の形式で収納しました。 文字コードは UTF-8、改行コードは \n です。 色別データとしてダウンロードできる形にしていますので、 必要なら使ってください。
この段階で、以前に書いたgrep による全文検索を使って検索することができます。 単に grep による検索も可能です。 これは R というディレクトリ内にあるファイルから、「スキル」で始まる行を探し、その行内に「ハートBOXを」という記述があった場合に表示せよというコマンドです。
grep -r '^スキル' R/* | grep 'ハートBOXを'

「スキル」内に「ハートBOXを」という記述があるカードをうまく取り出せていることがわかります。 ただ、コマンドをその都度よく考えなければならず、必ずほしいキャラの名前がファイル名になるなど、使いにくさも伴っています。 もう少し、改良してみましょう(5.pl)。
#!/usr/bin/perl
@dirs = ('R', 'B', 'G', 'Y', 'V');
get_files();
get_info();
foreach $n (keys %file) {
if ($attribute{$n} =~ /^あか/) {
if ($skill{$n} =~ /ハートBOXを/) {
print "$n\n $skill{$n}\n";
}
}
}
exit 0;
sub get_files {
foreach $dir (@dirs) {
opendir(DIR2, "$dir");
@dir2 = readdir(DIR2);
close(DIR2);
foreach $file (@dir2) {
if ($file =~ /^(.+?)\.txt$/) {
$name = $1;
$file{$name} = "$dir/$file";
}
}
}
}
sub get_info {
foreach $nickname (keys %file) {
open(IN, %file{$nickname});
while (<IN>) {
chomp;
if ($_ =~ /^正式名: *(.+)/) {
$name{$nickname} = $1;
} elsif ($_ =~ /^コスト: *(.+)/) {
$cost{$nickname} = $1;
} elsif ($_ =~ /^たいりょく: *(.+)/) {
$power{$nickname} = $1;
} elsif ($_ =~ /^こうげき: *(.+)/) {
$attack{$nickname} = $1;
} elsif ($_ =~ /^属性: *(.+)/) {
$attribute{$nickname} = $1;
} elsif ($_ =~ /^タイプ: *(.+)/) {
$typeof{$nickname} = $1;
} elsif ($_ =~ /^コンビ: *(.+)/) {
$combination{$nickname} = $1;
} elsif ($_ =~ /^シリーズ: *(.+)/) {
$series{$nickname} = $1;
} elsif ($_ =~ /^総合評価: *(.+)/) {
$ev{$nickname} = $1;
} elsif ($_ =~ /^リーダースキル: *(.+)/) {
$leader{$nickname} = $1;
} elsif ($_ =~ /^スキル: *(.+)/) {
$skill{$nickname} = $1;
} elsif ($_ =~ /^スキル条件: *(.+)/) {
$skill_cond{$nickname} = $1;
} elsif ($_ =~ /^フルパワー: *(.+)/) {
$fullpower{$nickname} = $1;
} elsif ($_ =~ /^フルパワー条件: *(.+)/) {
$fullpower_cond{$nickname} = $1;
} elsif ($_ =~ /^デュアルシフト: *(.+)/) {
$dual{$nickname} = $1;
} elsif ($_ =~ /^デュアルシフト条件: *(.+)/) {
$dual_cond{$nickname} = $1;
} elsif ($_ =~ /^クロスアビリティ: *(.+)/) {
$cross{$nickname} = $1;
} elsif ($_ =~ /^クロスアビリティ条件: *(.+)/) {
$cross_cond{$nickname} = $1;
} elsif ($_ =~ /^とくもり1: *(.+)/) {
$tokumori1{$nickname} = $1;
} elsif ($_ =~ /^とくもり1条件: *(.+)/) {
$tokumori1_cond{$nickname} = $1;
} elsif ($_ =~ /^とくもり2: *(.+)/) {
$tokumori2{$nickname} = $1;
} elsif ($_ =~ /^とくもり2条件: *(.+)/) {
$tokumori2_cond{$nickname} = $1;
} elsif ($_ =~ /^バトルスキル: *(.+)/) {
$battle{$nickname} = $1;
} elsif ($_ =~ /^バトル条件: *(.+)/) {
$battle_cond{$nickname} = $1;
}
}
close(IN);
}
}
実行は B,G などのあるディレクトリに 上の 5.pl を置いて perl 5.pl とします。 長いのでウワッと思う方もあるでしょうが、扱いやすくするためにこうなっているので、実際のところ、問題なのは 7-13 行の部分だけです (毎回、この部分だけ変えて実行)。 ここに、属性が「あか」で、スキルに「ハートBOXを」を含むキャラの、名前と、スキル内容を表示せよという命令が書いてあります。 この結果、ターミナルに次のように表示されます。

$attribute{$n} や $skill{$n} はよく使うので、初めから決めています。 プログラム内では、必要に応じこれらを組み合わせ、表示したい部分も自由に変えられます(以下)。
$n ... ニックネーム(=正式名称)
$file{$n} ... ファイル名
$name{$n} ... 正式名称
$cost{$n} ... コスト
$power{$n} ... たいりょく
$attack{$n} ... こうげき
$recover{$n} ... かいふく
$attribute{$n} ... 属性
$typeof{$n} ... タイプ
$combination{$n} ... コンビ
$series{$n} ... シリーズ
$ev{$n} ... 評価値
$leader{$n} ... リーダースキル
$skill{$n} ... スキル
$skill_cond{$n} ... 〃条件
$sskill{$n} ... 特訓スキル
$fullpower{$n} ... フルパワー
$fullpower_cond{$n} ... 〃条件
$tokumori1{$n} ... とくもり1
$tokumori1_cond{$n} ... 〃条件
$tokumori2{$n} ... とくもり2
$tokumori2_cond{$n} ... 〃条件
$dual{$n} ... デュアルシフト
$dual_cond{$n} ... 〃条件
$cross{$n} ... クロスアビリティ
$cross_cond{$n} ... 〃条件
$battle{$n} ... バトルスキル
$battle_cond{$n} ... 〃条件
たとえば、クロスアビリティが空文字でなく(存在し)、名前が「異邦」で始まらないキャラを羅列するコマンドは以下になります。
if ($cross{$n} ne '' and $n !~ /^異邦/) {
$a .= "$n\n";
}
結果は、
はいから女将のスノヒメ
おめかしスクエアス
うきうきのシグ
聖樹の拳士リャタフー
おばけガードマンのハルトマン
ビブリオガールのラウン
なつやすみのエリサ
ばけにゃんこのミッケーナ
はいいろのレムレス
ほしさゆるクルーク
ホラーナイトのネロ
マーブルコスモのナソス
です。検索にかかる時間は、ぼくの環境では 1秒以下です。 DB_File というモジュールを使えばさらに高速化が可能ですし (SQLite から本格的 DB となりテキスト処理という感じが薄れるが DB_File はいつでも簡単にテキストに戻せる)、 CGI でブラウザでコマンドを書けるように改良もできます(ローカルホスト限定にしたほうがいいです)。
以上、テキスト処理を習得すると、大がかりなシステムを組まなくてもいろんな場面で小回りのきく活用ができ、 能率がアップしてとてもお得という話でした(このシリーズ終わり)。
コメント 記事が気に入ったらいいねしてね!
0
25
🕍 同ジャンル最新記事(-7件)
2025/09/26
2024/02/16