|
|
前回に引き続き,プログラム同士を対戦させるゲームのアルゴリズムを考えます。前回は,目的地に向かってキャラクタを移動させる方法などを紹介しました。今回は,敵を攻撃するアルゴリズムを追加して,実際に対戦できるようにします。これまで本連載で得た知識をフル動員して,アルゴリズムを考えましょう。
前回の連載をご覧になっていない人のために,ゲームのルールを簡単に説明しておきましょう。ゲームの内容は縦10×横20の盤面上にいる二人の魔法使いを対戦させるものです(図1)。魔法使いは,ターンごとに「移動する」「魔法を使う」「魔法の要素を得る」「周囲を調べる」のいずれかの行動をとることができます。魔法には,相手を攻撃する火の魔法,ダメージを回復する水の魔法,マップの特定の方向に何があるかを調べる風の魔法などがあります*1。
![]() |
図1●対戦ゲームの実際の画面(Windows版) |
ゲームのプレーヤは,各ターンでどのような行動をとるかを決めるプログラムを記述し,それらを対戦させることになります。ゲームの進行をつかさどる部分(ゲーム・システムと呼びます)はこちらで用意しましたので,プレーヤはアルゴリズム部分を記述するだけでOKです。ゲーム・システムはコマンドライン版のほかに,グラフィックスで経過が表示されるWindows版も用意しています。連載目次ページからダウンロードしてお好みの方をお使いください。
敵を攻撃する際の戦略を考える
目の前の問題に対して,アルゴリズムをどう組み立てればいいかさっぱりわからない,ということは意外に多いものです。今回の敵を攻撃するアルゴリズムもその一つかもしれません。そのようなときはまず,「AがBになる」といったアルゴリズムを適用することで達成される「目的」を考え,それを「あるものが別のものになる」といった何かしらの「変化」として捉えてください。そして,その変化を起こすまでの道のりを「処理の流れ」としてイメージします。
とはいえ,処理の流れは場合によっていろいろなものがあり,そこで迷ってしまうかもしれませんね。その場合は例外的な場合を無視して「最も典型的な処理の流れ」を一つだけ考えてみてください。スタートとゴールを決めて,そこに至るまでの道筋を一つだけ決めてやります。あとはその道筋を小さく分割して,その塊を連ねることで処理を進められるようにイメージします。この方法で今回の問題を考えてみましょう。
まず,このゲームでは「敵を攻撃して勝つ」ことが目的になります。その目的のためには「相手を攻撃する」「相手に攻撃されないようにする」ことが必要です。さらに,「相手を攻撃する」ためには「魔法の要素を得なくてはならない」「相手の位置を知らなくてはいけない」などなど,一つのことから派生していろいろなことが出てきます。これらを一度に全部考えるのは大変です。そこで,一つの戦略を決めて,それに従って考えることにしましょう。
戦略を決めるにあたって,このゲームには考慮すべきいくつかの制限があります。
- 敵の位置を確実に知る方法がない。周囲を調べたり攻撃が命中したりして敵の位置がわかっても,次のターンで敵が移動すると,推測するしか手がなくなってしまう。
- 持てる要素の数に限りがある。さらに,要素がなくなったときにすぐ近くに求める要素が見つかる保証もない。
- ターンを消費せずに周りを調べる方法がない。魔法を使って調べる場合で1ターン,「周囲を調べる」行動をとる場合は調べる距離ぶんの回数のターンを消費する。
こうした点を考えると,敵を見つけたときにたまたま攻撃に使う火の要素を持っていたら攻撃する,といった行き当たりばったりの方法は,あまり得策ではありません。火の要素がなくなったために次の攻撃までに間が空いてしまったりすると,その間に敵が移動して位置がわからなくなってしまうからです。それよりも,あらかじめ火の要素をため込んでおき,敵を見つけたら連続して攻撃する方が効果的でしょう。敵は1ターンで1歩しか進めませんから,一定の範囲にダメージを与える魔法*2を使えば毎ターン攻撃を命中させることも難しくありません。
小学生のころにやった雪合戦を思い出してください。魔法の要素を集めながら相手に攻撃する,というのは,雪合戦で雪を集めながら相手にぶつけるのとよく似ていますね。雪合戦では,最初に雪球をある程度作っておいてから集中的に攻撃するという戦略をとることがあります。これと同じことをこのゲームでもしようというわけです。
最初は攻撃するための魔法の要素を移動しながら集めていきます。要素が十分たまったら魔法で攻撃を行います。要素が尽きたら移動してまた集めます。これを繰り返すことで敵と戦っていくのです。