黄昏より暗きもの、血の流れより赤きもの

読者です 読者をやめる 読者になる 読者になる

黄昏より暗きもの、血の流れより赤きもの

自分の好きな事を好きなように書いて行きます。

迷路ゲーム

問題


N*Nの升目がある。以下のように5*5の升目の迷路において、"1"が移動可能な場所(通路)、"0"が移動不可能な場所(壁)、"S"がスタート地点、"G"がゴール地点とする。このとき、人Aがスタート地点からゴール地点まで、左、右、上、下に1マスずつ動いていくようなゲームを作成せよ。



[要件1]:左、右、上、下と入力するとそれぞれ1マスずつ移動する。

[要件2]:移動先が壁や迷路の場合は、移動する前の地点にとどまる。

[迷路]
1S111
01100
10110
10111
0G100

説明


迷路の仕様として、迷路のステージを5*5の二次元配列boardとして定義している。このとき、配列の値が0ならば移動不可能。1ならば移動可能としている。又原点を基準点とし、スタート地点(s)、現在位置(n)、ゴール地点(g)と位置ベクトルを定義する。
この位置ベクトルを定義した構造体がPointにあたる。このときソースコードの76行目のようにcheck関数により(n)=(g)かどうかを判定し、(n)=(g)ならばゲームを終了とするようにしている。
又各移動方向のベクトルを(v_1)=(0,-1),(v_2)=(1,0),(v_3)=(0,1),(v_4)=(-1,0)と定義する。ユーザーが移動方向を指定すると、vにv_1〜v_4の何れかのベクトルが代入され、移動が開始される。

行った先が移動可能か?


まず(n)=(s)と現在位置をスタート地点にセットして、ゲームを開始する。ここで入力終了後のAの移動先を表す位置ベクトルは(n)+(v)となる。このとき移動先がますの外にはみ出てないかを調べるには、(n)+(v)のx成分又はy成分が0より小さいか?(N-1)より大きくなってないか調べれば良い。このとき(v)=(0,0)と設定すれば、(n)+(v)=(n)+(o)=(n)となって、移動前の位置に留まるので[要件2]は満たせる。また(n)+(v)に対応する配列の値が0ならば留まるようにする事で、壁だと移動できない部分は実装できる。

各関数、変数の仕様



構造体Point:スタート地点、現在位置、ゴール地点を表すベクトル
変数now、変数start、変数goal、変数vec:それぞれ説明の(n)、(s)、(g)、(v)に対応
関数check:Aの現在位置がゴールであるのかを判定する関数。ゴールの場合は1を、そうでない場合は0を返す
関数board_print:迷路の状態を出力する。引数nowに入力された座標値においては、Nを出力し、それ以外は配列boardの値をそのまま出力する

尚、入力後の移動先についてはmain関数にて処理している。

ソースコード



検証


今回は、移動は正常か?移動先が壁や升目よりはみ出る事が無いか?ゴールしたときゲームが終了するか?について検証を行った。移動においては左右上下において無事動作。壁や迷路の外にはみ出る事なく無事動作している。またゴール地点に達したときは、以下のように無事ゲームが終了している。