ピースを置く場所の算出 (KATAMINOを解くプログラムを作成する)

★前回の記事

yucatio.hatenablog.com

スタックからフィールドとスピン情報を取得することができたので、ピースが置けるか判定していきます。 minEmptyのマスに重なるようにピースを置くのでした。 minEmptyは、フィールドのピースが置かれていないマスのうち、1番上の行で1番左にあるマスです。 置くスピンの一番上の左端とminEmptyを重ねます。これ以外のマスを重ねようとしてもすでにあるピースと重なってしまったり枠の外に出たりしてしまいます。(ただしスピンの1番上の左端を重ねたからと言って必ずしも他のピースと重ならないわけではないです)

f:id:yucatio:20190722133606p:plain:w300

minEmptyと重なるようにピースを置いた例↓フィールドからはみ出していて、他のピースとも重なっている

f:id:yucatio:20190722133621p:plain:w280

minEmptyと重なるようにピースを置いた例↓フィールド内に収まっていて、他のピースとも重なっていない

f:id:yucatio:20190722133633p:plain:w250

幸いな事に、spinの1番上の1番左にあたる場所はspin[0]です。これは2次元配列からリストを作成した時に、1番上の列の左からリストにしていったためです。 スピンをminEmptyと重なるように移動します。

x方向(下方向)にはminEmpty.xぶん移動します。y方向(右方向)にはminEmpty.y - spin[0].yぶん移動します。

f:id:yucatio:20190722135720p:plain

実装

コードにしていきます。spinの移動量をoffsetという変数に格納します。

js/solver.js

const solver = {
  solverStack : [], 

  // 中略

  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} // 追加

      console.log("offset", offset)
    }
  },
}

pieceの各値にoffsetを足したものが実際のピースが置かれる場所になります。

例えば、以下のスピンは、

f:id:yucatio:20190722133926p:plain

リストの表現は

[
  {x: 0, y: 1},
  {x: 1, y: 1},
  {x: 2, y: 0},
  {x: 2, y: 1},
  {x: 2, y: 2}
}

です。

nextEmpty{x: 2, y: 1}のとき、offset{x: 2, y: 0}なので、 実際にピースが置かれる場所は、各配列の要素に{x: 2, y: 0}を足して、

[
  {x: 2, y: 1},
  {x: 3, y: 1},
  {x: 4, y: 0},
  {x: 4, y: 1},
  {x: 4, y: 2}
}

となります。

動作確認

実行結果です。以下のようになっていれば成功です。offsetの値が表示されました。

f:id:yucatio:20190722094926p:plain

以上でピースを置く場所の算出ができました。


★次回の記事

yucatio.hatenablog.com

★目次

yucatio.hatenablog.com