robozzle like 42を思い出しながら実装してみたやつです
renderFunction(0)を実行する非同期関数renderFunction(0)を実行中に呼び出されることを防ぐため、.disabled = trueでボタンを半透明にし、実行できなくする- 操作回数上限である
timeoutを考慮し、time = 0しておく - 前回の
run()時の変更を上書きするためflag = falseしておく renderFunction(0)が実行しおわるまで待つ- 実行し終わったら操作終了の原因が
timeoutかどうかを確認する(timeoutが原因だったらalertで通知しinit()で初期化) - コンソールに
Endを出力 - 最後に
.disabled = falseでもう一度実行できるようにする
- 実行し終わったら操作終了の原因が
- Run時のレンダリングはF1(
f[0])のみ recursive関数に引数(f[i], 0, f[i]の長さ)を渡し呼び出す
fi[j]が実行可能か判定し、順次実行していく関数(以下、操作終了の条件)- 操作回数が設定された
timeoutを超えている fiの長さとjが一致する(0はじまりなので一致したら範囲外)flagが立っている(Runしてから一度Game clearかRange overしている)
- 操作回数が設定された
starが0のときnを1カウントアップし、flagを立て、操作終了することで次のレベルに進む処理を行うboardの外へアクセスしたか、tiles[y][x]が-1のときf[i]の入力以外を現在のレベルへ初期化し、flagを立て、操作終了する- 操作終了の条件に当てはまらず、かつ移動元のタイルが操作条件に当てはまる色のとき、
await sleep(speed)とmoveRocket(command)を実行する。そうでなければ、今回の操作を待ち時間(await sleep(speed))ごとスキップしてawait recursive(fi, j+1, len)を実行する(再帰)。
commandに応じて操作を変える(f[i][j]がとりうる値を参照)- 移動先のタイルに星があれば星なしに変え、
starから1引く(以下タイル番号)0:赤色1:緑色2:青色3:赤色/星あり4:緑色/星あり5:青色/星あり
yはy軸の増減分(commandとrocketRotateから自動割り出し)xはx軸の増減分(commandとrocketRotateから自動割り出し)
"board"board[y][x]のとき対応したタイル番号を示しているboard[y][x]が-1のときは、範囲外となる
"point"- Rocketの初期座標(
y, x)と向き(rotate) - 常に
[y, x, rotate]の形式になる
- Rocketの初期座標(
"fn"f[i]に入力できるコマンドの数- 常に
[f1, f2, f3]の形式になる
"timeout"- 無限ループを回避するための、操作回数上限
- 常に
[command, condition]の形式になる j回目の操作ではconditionの条件をみたしたときにcommandを実行できる。command(操作)-1: 動かない0: 直進1: 右90度方向転換2: 左90度方向転換3: 赤にぬりかえ4: 緑にぬりかえ5: 青にぬりかえ6: f1実行7: f2実行8: f3実行
condition(操作条件)-1: 操作条件なし0: タイルが赤のとき操作可能1: タイルが緑のとき操作可能2: タイルが青のとき操作可能
// LEVEL[0]
f[0] = [[0, 2], [1, 0], [1, 0], [6, 0]];- レベルアップ時に
fの枠が更新されない問題を解決