タンク・チェンジをゲームにする 外観・イベントリスナの追加までの続きです。今回は戦車を移動させる処理を実装します。

戦車を選択する処理

広場の上に表示されている戦車の画像がクリックされたときにおこなわれる処理を示します。

クリックされたら対応する位置にある戦車の番号をチェックします。青なら 0 ~ 2、赤なら 3 ~ 5、戦車がない位置であれば -1 です。

つぎにすることが移動させたい戦車の選択(phase が 0 なら青、2 なら 赤)である場合であれば選択された位置をグローバル変数 selectedPosition に保存し、phase を次に移すとともに選択されたことがわかるように効果音を鳴らします。

戦車を選ぶタイミングでなかったり、適切な戦車を選べていない場合は、ユーザーに操作が間違っていることを知らせるための文字列を表示し、効果音を鳴らします。

戦車を選択するフェイズで移動先を選んでしまった場合や移動のフェイズで移動できない場所を選択するという間違った操作がされたときにおこなわれる処理を示します。

この場合は間違いを指摘するメッセージを表示して効果音を鳴らします。戦車を移動させるときに不正な操作をした場合もこの処理がおこなわれます(戦車の選択に戻ってやり直すことになる)。

戦車を移動させる処理

ゲームでは移動させたい戦車を選択したらつぎに移動先を選択することになります。ここからは移動させる処理を示します。

その前にこれに関係する処理をする関数を示します。

sleep は第一引数で与えられた時間(単位:ミリ秒)だけ待機する関数です。

getTankPosition は第一引数で与えられた番号の戦車の位置を返す関数です。グローバル変数 matTanks から引数で渡れた値があるかを探しているだけです。

戦車は移動可能か?

CanMoveTank は srow 行 scol 列目にある戦車がgrow 行 gcol 列目に移動できるかを返す関数です。二次元配列を斜めにたどっていって他の戦車にぶつかることなく目的地にたどり着けるかを調べています。移動後に敵の戦車と向かい合ってしまうと撃ち合いが発生して移動できないのですが、この判定処理は移動後におこないます。処理を分けることに特別な意味はなく単なる演出上のこだわりです。

流れるように戦車を移動させる

戦車を移動させる処理を示します。一瞬で移動するのではなく流れるように移動させるために待機処理をいれて少しづつ移動させています。

戦車が撃たれた場合の判定とその後の処理

移動が完了したらその先は敵の射程範囲内で撃たれてしまうかもしれません。その場合は効果音を鳴らして戦車をもとの位置に戻し、その位置には移動できない旨を表示させます。

isDead関数によって移動した戦車が撃たれた場合、その戦車はもとの位置に戻します。戻す処理は滑るように移動する処理はせず一瞬で移動させます。

戦車が撃たれてしまう場所に移動させてしまったときに移動できない旨を表示する処理を示します。同じタイミングで効果音も鳴らしています。

クリア判定とクリア時の処理

クリア判定とクリア時の処理を示します。戦車の位置が開始時と完全に入れ替わっているかどうかがわかればよいので2次元配列 matTanks に記録されている戦車の番号を調べています。一番上の行と下の行をそれぞれ別に集めてソートし、前者が 3,4,5 であり、後者が 0,1,2 であればクリアしていることになります。

クリア時はクリアまでに何手でかかったかを表示したかを表示します。コードにあるとおり、クリアまでの最短は18手です。

参考:タンク・チェンジの問題を解く(Cマガ電脳クラブ 第127回)

そのあとスタートボタンを再表示させて降参ボタンを非表示にします。そしてignoreClick フラグをセットして広場や戦車をクリックしても反応しないようにします。

移動先をクリックしたときの処理

これまでに定義してきた関数をつかって移動先をクリックしたときの処理を実装します。phase が 1 と 3 のときだけ移動の処理をおこないます。それ以外のときは不正な操作です。

次回はギブアップしたときに正解手順を示す処理を実装します。