Making「FP3(仮)」その2

Home PC-6001mkII Program etc

 このページでは、基本機能の実装過程を書いています。

Making「FP3(仮)」 Top


2009/05/24:繋がり
 このゲームで一番肝になる、くっつき(2つ繋がり)と岩変化(3つ以上繋がり)の処理について考える。

 「2つ繋がり」は後にして、まず「3つ以上繋がる」というのはどう判定するか。まず「3つだけ繋がる」という状況を考えると、以下のパターンがある。
■■■
■■

 これらを判定する場合、大きく以下の2つのどちらかを満たせれば良い。
  1. 「上下左右に一方向にだけ同じ種類のコマがある」パターンが2つある
  2. 「上下左右に二方向にだけ同じ種類のコマがある」パターンが1つある
 さて、これが「4つ」になるとどうなるか。以下のパターンで試してみる。
■■■■
■■■
■■■
 ■
■■
■■
■■
 ■■

 さて困った。先ほどの条件1では四角のパターンが該当しないし、条件2では凸型のパターンが該当しない。

 仕方ないので、これらを判定できるように条件を少し緩和してみる。
  1. 「上下左右に一方向以上同じ種類のコマがある」パターンが3つ以上ある
  2. 「上下左右に二方向以上同じ種類のコマがある」パターンが1つ以上ある
 とりあえずこんなものか。コマが2つだけ繋がっている場合と1つも繋がっていない場合は...該当せず、と。
 直感の部分もあるが、条件3よりも条件4の方が簡単そうなので、こちらでいきたいと思う。

 一応、5つ繋がったパターンでも試してみるか。

■■■■■
■■■■
■■■■
 ■
■■■
  ■■
■■■
■■
■■■
■ ■
■■■


■■■

■■■
 ■

■■■
  ■
 ■
■■■
 ■
■■
 ■■
  ■

 ...よし、大丈夫そうだ。条件4で行こう。

 あとは、2つ繋がったパターンだ。これを後回しにしたのは訳がある。3つ以上繋がったパターンを排除すれば、2つ繋がりの条件は簡単になるからだ。

 3つ以上繋がったパターンを処理した後だと、上下左右のどこかに同じ種類のコマがあればそれだけで2つ繋がりという事がわかる。

 あとは、これをマシン語で表現するだけだ。

2009/05/28:岩変化実装
 5/24で考えた岩変化処理をマシン語で実装してみる。

 主な処理としては、画面データ内の各キャラクタのあるアドレスについて以下を実行することにする。
  1. アドレスにあるキャラ番号を取得
  2. キャラ番号が08H未満の場合はフルーツではないので次のキャラに移動
  3. 上下左右で同じ種類のフルーツ(08H以上で、かつ8で割った余りが同じ)があるかを調べる
  4. 上下左右にある同じ種類のフルーツの数が0 or 1なら次のキャラに移動
  5. 中心となるキャラと、上下左右にある同じ種類のキャラクタを岩変化候補として80Hだけプラスしたキャラ番号に変更する
 最後に、全ての岩候補キャラ(キャラ番号80H以上)を岩(01H)に変える。

 っと。とりあえず出来たので、試してみる。まずは全部同じフルーツの場合。
画面 画面

 ...予定と違う。

 PC-6001VWのモニタモードでステップ実行していくと、一部アドレスを戻すのを忘れていた事がわかった。早速修正してアセンブルを行う。

画面

 よし、これでOK。次は、横長や縦長の同種キャラを含めて何度か調べてみる。
画面 画面

 まあ、岩変化部分はこんなものかな?

2009/05/30:くっつき実装
 引き続き、縦または横に2つ並んだときのくっつき処理を実装する。

 各コマで、自分の右と同じ種類のフルーツなら横長、自分の下と同じ種類のフルーツなら縦長のキャラクタに変更する。
 割とあっさり完成したので、またランダムにフルーツを配置して動作を確かめてみる。
画面 画面

 フルーツが縦長や横長に代わる様子は、思ったより楽しい。

 後は移動処理と手詰まり処理位かな?

2009/06/01:手詰まり判定実装
 続いて、手詰まり処理を考える。

 手詰まりの条件を改めて言うと、「一画面内に同種のフルーツが2つ以下」になる事だ。つまり、各フルーツの個数を数えてどれか一つでも合計数が1または2であれば手詰まりの条件が成り立つことになる。という事で、実装してみよう。

画面 画面

 途中コーディングミスもあったが、うまく機能しているようだ。

2009/06/13:移動処理
 メインとなる処理の残り一つ、移動処理について考える。

 TOMの移動自身は、押されたカーソルキーによって変えれば良いので特に難しくない。面倒なのは、移動先のキャラクタによる移動処理だ。

 キャラクタと移動方向によるパターンは、ざっとこれだけある。

移動先キャラ移動方向動作
空白上下左右そのまま移動
壁/ドア(閉)上下左右移動せず
ドア(開)上下左右面クリア
上下左右さらに一つ先が空白:岩とTomを移動
それ以外:移動せず
フルーツ(通常)上下左右さらに一つ先が空白:フルーツとTomを移動
それ以外:移動せず
フルーツ
(縦長上/下)
上下さらに二つ先が空白:フルーツ(上下とも)とTomを移動
それ以外:移動せず
フルーツ
(縦長上)
左右さらに一つ先が空白、かつ一つ先の一つ下が空白
 :フルーツ(上下とも)とTomを移動
それ以外:移動せず
フルーツ
(縦長下)
左右さらに一つ先が空白、かつ一つ先の一つ上が空白
 :フルーツ(上下とも)とTomを移動
それ以外:移動せず
フルーツ
(横長左/右)
左右さらに二つ先が空白:フルーツ(左右とも)とTomを移動
それ以外:移動せず
フルーツ
(横長左)
上下さらに一つ先が空白、かつ一つ先の一つ右が空白
 :フルーツ(左右とも)とTomを移動
それ以外:移動せず
フルーツ
(横長右)
上下さらに一つ先が空白、かつ一つ先の一つ左が空白
 :フルーツ(左右とも)とTomを移動
それ以外:移動せず

 この通りのパターンで判定処理を愚直に作っていけばいいのだが、もうちょっと処理をまとめたいとことだ。

2009/06/14:移動処理実装
 昨日考えた移動方法の実装だ。

 この辺りは面倒な部分なのでどうにも食指が動かなかったが、やる気のあるタイミングを見計らって、とりあえず一気に書き上げる。

 さて、一面の面データにて実行...動かない。まあ、一発で動くとはそもそも思っていない。キーが押されてからの処理をステップ実行して確認すると、キー入力の直後に行ったキーバッファクリア処理が、入力キーの情報を消したようだ。という事で修正。

 次は壁...TOMが表示されない。動けない時にTOMのアドレスを元に戻し損ねていたようなので修正。

 次は岩...押せない。なんかボロボロだなあ。別の用途で使用していたAレジスタの値を戻していなかったので修正。

 次は通常フルーツ...岩に変わってしまった。あ、岩と共通処理にしたけど移動時に岩のキャラクタを書いてたんだっけ...。修正。

 次は縦長フルーツ...縦方向はOK。横方向は...岩3つに変わってしまった。実際に押していない側のフルーツの消去するためのアドレス更新をしてなかった。その後にTOMを表示する処理も抜けていたので、合わせて修正。

 次は横長フルーツ...縦方向はOK。横方向は...OK。

 これで普通に操作できるかな?改めて一面で操作を試してみよう。

画面

 こんなものかな?そういえば、フルーツを全て岩に変えたというクリア条件判定も必要だったな。それはまた今度。

2009/06/23:戻り値その1
 せっかく、今回USR()関数を使っているのだから、BASICに結果を返すようにしてみようか。戻り値を入れたら、音を出すときの分岐が簡単になるはずだ。

 とりあえずはこんな感じかな?
  • キー入力&移動:クリア(2), 岩 or フルーツを押した(1), それ以外(0)
  • 表示処理:くっつき発生(2), 岩変化(1), それ以外(0)
  • 手詰まり判定:ドアが開いた(2), 手詰まり(1), それ以外(0)

 とりあえず、手詰まり判定の部分のみ実装してみる。

画面

 この戻り値を応用すれば、多分BASICで効果音を鳴らすのも簡単になるだろう。って、この調子じゃ6月中に終わらないな...。


その1 Making「FP3(仮)」 その3