迷路データの省メモリ化の記事を掲載したところ、壁と通路の太さが同じでは無く、壁が薄い迷路はどのようなデータで持つのが良いのかという質問を受けました。そのリクエストにお応えして、私ならこうするというデータ構造の解説を行います。


  • 自分から見た壁の位置
迷路ですが、壁の有る無しを精査していくと、実は16種類しか存在しない事が分かります。その16種類全てに番号を割り振ります。例えば以下のような感じです。
壁は16種類
格子状の平面迷路であれば、これだけで表現できてしまいます。ということで、テストで作ってみた迷路がこちら。
9x9の迷路を構築
9×9サイズの迷路が81バイトで表現されています。緑色の矢印に注目してください。下側のエリアは壁番号 $06 なので、上に移動できますが、移動先は $0B なので、下には壁があります。振り向くと壁という一方通行を、このようにいとも簡単に作る事が出来ます。この $0B の場所に下から来た場合だけ「ひゅう♪」と効果音を出したり、一瞬画面を点滅させるなどの演出を入れるとより効果的です。

入り口が右上のStartで、出口が左側の広場っぽいところのGoalだと、作る側としては面白いでしょうね。うっかり緑の場所を上方向に進んでしまうと戻れなくなります。ゴールに辿り着くには、またグルリと大回りが必要になります。怪物との遭遇確率が増えるので、HP が持たなくなるかもしれません。このような配置の工夫がまた楽しかったりします。
※ スパイ歴十数年、オレは今初めて緊張している・・・

  • エリア毎の属性情報
壁の情報が16種類と言う事は、データとしては 4bit しか使っていませんので、残りの 4bit を各エリアの属性情報として使用できます。先の効果音を出す演出のトリガとして、フラグを仕込む事も出来ます。4bit なので、全部で16種類です。とりあえず、こんな感じでパラメータ設定してみると良いかもしれません

 $00 = 何もなし  $10 = 階段がある  $20 = 宝箱がある  $30 = 上に破壊出来る壁がある  $40 = 下に破壊出来る壁がある  $50 = 左に破壊出来る壁がある  $60 = 右に破壊出来る壁がある  $70 = 上に扉がある  $80 = 下に扉がある  $90 = 左に扉がある  $A0 = 右に扉がある  $B0 ~ $E0 = 予約  $F0 = 拡張フラグ
※ 2022/06/25 06:30 追記
下に破壊できる壁の属性が無いのは何故?と疑問を頂いたのですが、俯瞰でマップを表示すると、下側に壊れる壁が有ると殆ど分からないので、あえて最初で用意してませんでした。3Dマップ表現とするならば、必要となります。紛らわしかったので追加しておきました。余談ですが、上記マップの $0F の場所を $00 にすると面白いですw
このフラグ構造にしたのは意味があって、マップの描画に必要なモノだけは、そのままデータとして取得できるようにしています。宝箱とか扉等は見えている対象物です。これらは描画が必要なので、即時情報として取り出したいです。それ以外の床が回転するとか、画面がフラッシュするとか、効果音が鳴るとかは、通常の表示には不要な情報なので、全て $F0 拡張フラグとします。この $F0 フラグがあった場合は、別途用意するイベントテーブルを参照すれば良いと思います。

階段や宝箱が、離れた位置から見える必要が無いのであれば、これらも拡張フラグ側に移動させれば良いと思います。その分、通常の描画に必要な情報の定義数が確保できます。あと、扉は開いて前に進んだ後は、自動で閉まっているという仕様となります。開いた扉を開きっぱなしにするのであれば、予約の中から4種類、各方向の開いた扉ステータスを用意して、描画できるようにしなければいけません。同様に壁が破壊されたら、その後は普通の通路になっている必要があります。崩れた表現をしたいのであれば、扉と同様に予約から各方向の崩れた壁を定義する必要があります。

なお、4方向で定義せず、2方向だけで、細い壁に厚みを持たせない方法も、データとして実現出来ると思いますが、描画の事を考えると、その都度エリアを跨ぐ参照が発生するので、あまりオススメしません。特に低速CPUのレトロPCで、迷路構築を考えている場合は、多少の無駄は承知で高速動作にデータを割り振る必要があります。この辺りの省メモリと高速化のバランス取りが、プログラマの腕の見せ所になると思います。

※ アーニャを知ると世界が平和に?

※ 大変恐縮なのですが…息の根止めさせて頂いてもよろしいでしょうか?