さくら美緒(さくら・みお)

今号の問題
あなたは魔法使い。もちろんプログラミングの腕もウィザード級です。そんなあなたがライバルと対決することになりました。マップ上にある「魔法の要素」をうまく集めてライバルを倒すプログラムを作成してください。今回は,カコミ記事「ゲームのルール」に従って移動ができるまでとします。

キャラクタを移動させるアルゴリズム

 アルゴリズムを作っていて一番うれしいと感じるのは,「自分で作ったアルゴリズムが動くところを見る」ときではないでしょうか? 日本IBM主催で大会が開かれた「Robocode」がその代表的なものでしょう。Javaで仮想的なロボットを制御するアルゴリズムを記述し,対戦させるゲームです。アルゴリズムを組み立てたら,さっそくその内容を試せますし,アルゴリズムが悪ければゲームに負けてしまいます。こうして楽しみながらトライ&エラーでアルゴリズムを組み立てられるところから,新人研修などで最近よく使われているようです。

 本連載では,いろいろなアルゴリズムを紹介してきました。これまでの集大成として今回と次回の2回を使って,プログラム同士を対戦させるゲームを取り上げてみます。

 今回の対戦ゲームが動作する仕組みを表したのが図1です。ゲームの進行,魔法攻撃の当たり判定,キャラクタの位置やダメージなどの管理などはすべてゲームの進行をつかさどるモジュール(以下ゲーム・システムと呼びます)の関数で実行します。ゲームのプレーヤ(プログラマ)は,自分で管理するデータを初期化する関数や,キャラクタを移動したり魔法を唱えたりといった1回のターンにおける行動を決める関数だけを用意します。ゲーム・システムが必要に応じてこれらの関数を呼び出すことで,ゲームを進めていくわけです。

図1●今回のゲームが動作する仕組み
図1●今回のゲームが動作する仕組み

 ゲーム・システムはこちらで用意しましたので,プレーヤはキャラクタ移動などのアルゴリズムだけを記述すれば済むようになっています。連載目次ページからダウンロードして,気軽に取り組んでみてください。

ゲームのルール

●盤面

縦10×横20のマス目で区切られています。1マスごとに魔法の原料となる要素が1~5個存在します。要素には取り出す順番などの制限はありません。いつでも好きなものを取り出せます。要素が0になったら,1~5までのランダムなターンの期間後,ランダムな数だけ補充されます。

●キャラクタ

上下左右に1マスずつ進めます。魔法の要素を10だけ持てます。攻撃によるダメージを3受けると負けです。互いの位置は「周囲を調べる」か「風の魔法」で居場所を探らないとわかりません。

●魔法

火…要素一つでファイア・アロー(指定したマスに1ダメージ)
   要素二つでドラゴン・ファイア(上下左右各1マスに1ダメージ)

水…要素一つでダメージを1だけ回復
   要素二つでダメージを2だけ回復

木…要素一つで1ターンだけ攻撃を防ぐ
   要素二つで3ターンだけ攻撃を防ぐ

風…要素一つで1方向を5マスぶん調べる
   要素二つで1方向を10マスぶん調べる

土…要素一つで耐久力1の障害物(ダメージ1で破壊)を作成
   要素二つで耐久力2の障害物(ダメージ2で破壊)を作成

●ゲームの流れ

(1)ゲームを始める前に,各プレーヤはそれぞれ盤面の左半分,右半分の領域の好きな場所にキャラクタを置きます。配置が終わったらゲーム開始です。

(2)ゲームは「相手の番」「自分の番」「相手の番」…と交代で進むターン制です。自分のターンになったら,「移動」「魔法を使う」「魔法の要素を得る」「周囲を調べる」のいずれかを選んで実行します。実行結果が得られたら,相手のターンに移ります。

(3)「移動」は,上下左右いずれか1マスを選んで移動します。障害物がある方向には進めません。

(4)「魔法を使う」は,持っている魔法の要素を使って魔法を唱えます。攻撃する魔法や特定の方向を調べる魔法,障害物を作成する魔法の場合は位置や方向を指定します。

(5)「魔法の要素を得る」は,今いるマスにある魔法の要素を,キャラクタが持てる限界までいくつでも取り出せます。

(6)「周囲を調べる」は,自分のターンを1~5回放棄し,その数のぶんだけ上下左右にあるマス目の様子を調べます。

(7)相手にダメージを3与えるか,100ターン過ぎてダメージが少ない方を勝ちとします。

ゲームを有利に進めるためにどうすればいいかを考える

 ゲームで勝利を得るためには,何よりもまずルールを熟知することが大切です。カコミ記事「ゲームのルール」を眺めてみると,このゲームのポイントはだいたい以下のようになるでしょう。

・魔法の要素を効率よく集める

 相手を攻撃したり防御をするためには,各地点にある魔法の要素を集めないといけません。ゲームを有利に進めるには,効率よくマップ上を移動して魔法の要素を集めながら進んでいく必要があります。

・限られた要素を限られたポケットへ詰め込む

 プレーヤが操作できるキャラクタは,魔法の要素を最大10個しか持てません。マップに魔法の要素が豊富にあっても詰め込むには限界があります。その一方で,プレーヤ側に余裕があっても必ずしも目的の要素が得られるとは限りません。そうなると,使いたい魔法があって,それに合わせてマップ上を移動して要素を集めていく「目的型」か,マップ上をまわって,最も多く集めた要素に基づいて使う魔法を決める「成り行き型」という2通りの考え方が生まれると思います。

・敵がどこにいるかを推測する

 このゲームでは,そのままでは相手がどこにいるのかがわかりません。攻撃するためには相手の居場所を知る必要があります。魔法で調べたり,周囲を調べる行動を指示することで相手の位置を探っていきます。相手も移動していることを考えると,ある程度移動先を予測しながら攻撃することになります。

・敵に見つからないように移動する

 とはいえ,じっとしたままでは自分の居場所を相手に推測されてしまいます。相手に見つけられないように,適度に移動していくことが必要です。

・戦略を立てながら行動するアルゴリズムを考える

 こうしていろいろな戦略を立てて,それに合わせてアルゴリズムを組み立てていきます。相手もまた戦略を立ててくるので,それを見極めて対抗策を立てることも必要でしょう。いろいろなことを同時に考えていくと奥が深いものです。今回は,こうした中から移動に関する処理を中心に作成してみます。