★前回の記事
前回まででスピンをどこに移動するか求めることができたので、今回はその位置に置けるかどうかを判定する関数を作成します。
ピースがフィールドに置ける条件は、以下の2点を満たすことです。
- ピースがフィールドの外に出ていないこと
- 置こうとする場所にすでに他のピースが置かれていないこと
置ける例↓
置けない例↓
実装
フィールドにスピンが置けるかを判定する、isAllEmpty
関数とisEmpty
関数を定義します。isAllEmpty
は、スピンが置かれるすべてのマスが、フィールドの範囲内でまだピースが置かれていないときにtrue
を返す関数です。
isEmpty
は、place
の位置がフィールドの外でなく、かつまだピースが置かれていないときにtrue
を返す関数です。
はじめに呼び出し側の実装をします。isAllEmpty
でスピンが置けるか判定し、置けなかった場合には処理を中断し、ループの先頭に戻ります。
js/solver.js
const solver = { // 中略 solve : () => { while (solver.solverStack.length > 0) { const {kataminoField, minEmpty, pieceId, spinId, spin, unPlacedPiece} = solver.solverStack.pop() console.log("pieceId", pieceId) console.log("spinId", spinId) const offset = {x: minEmpty.x, y: minEmpty.y - spin[0].y} // 追加ここから if (! solver.isAllEmpty(kataminoField, spin, offset)) { // フィールドの外か、すでにピースが置かれている console.log("フィールドの外か、すでにピースが置かれている") continue } console.log("ピースが置ける") // 追加ここまで } }, // 追加ここから isAllEmpty: (kataminoField, places, offset) => { // TODO 実装 return false }, isEmpty: (kataminoField, place) => { // TODO 実装 return false }, // 追加ここまで }
isAllEmpty
からisEmpty
を呼び出しましょう。Array.every
(
Array.prototype.every() - JavaScript | MDN
)
はコールバックに渡された関数が、配列のすべての要素に対して、true
相当を返すかどうかを判定します。
isEmpty
の引数には、スピンが実際に置かれるマスを渡すので、offsetをそれぞれ加算した値を渡しています。
isAllEmpty: (kataminoField, places, offset) => { return places.every((place) => ( solver.isEmpty(kataminoField, {x: place.x + offset.x, y: place.y + offset.y}) )) },
次に、isEmpty
関数を実装します。まずはplace
の位置がフィールドの内のときにtrue
を返すようにします。JavaScriptの場合は、配列の定義外の範囲を参照するとundefined
が返ってくるので、それで判定します。place.x
もplace.y
もundefined
でなければフィールドの範囲内です。
isEmpty: (kataminoField, place) => { return ( kataminoField[place.x] !== undefined && kataminoField[place.x][place.y] !== undefined ) },
次に、置こうとする場所にすでに他のピースが置かれていないことを判定します。フィールドにピースが置かれているときはそのピースの番号、置かれていないときは-1
なので、ピースが置かれているかどうかは0より小さいかどうかで判定します。
isEmpty: (kataminoField, place) => { return ( kataminoField[place.x] !== undefined && kataminoField[place.x][place.y] !== undefined && kataminoField[place.x][place.y] < 0 ) },
動作確認
動作結果です。コンソールの出力はこのようになっています。
下記の図と対応させてみると、
(pieceId, spinId) = (9, 1), (9, 0), (2, 7), (2, 1), (1, 7), (1, 3), (1, 1)
が初期状態で置けることが分かり、コンソールの出力結果と一致していることが分かります。
★次回の記事
★目次