はかせのラボ

私の頭の中を書いていく雑記ブログです

落ちモノパズル Tスピン作ろうとしたら設計の壁に打ちのめされた

あいさつ

どうも、はかせです。
今回は前回完成しきらなかったスーパーローテーションの続きと
Tスピン判定を付けようとした話です。

Iミノのスーパーローテーション

Iミノは他のミノとは少し違った動きをします。
他のミノはほぼ全てが同じ動きをしていました。(0度と180度の時は反転)
対してIミノは結構例外的動きが多いです。

理由としては他のミノは3×3で表現可能で中心を回すことが出来ました。
ですが、Iミノだけは4×4で表現せねばならず
正確に中心を回すことができません。
なのでIミノの回転は中心2マスを中心として回します。

結果として動きが他のミノに比べてぐちゃぐちゃしてきます。
本当はこういった問題は設計段階で気づき
対応可能な設計にするべきなのですが、
私の設計能力不足により設計レベルでの対応が不可能でした。

なので無理やりですが全ての回転パターンに対して
どこにどこのピースが対応するか
switch文+if文の暴力で全て手書きで対応しました。
((ノД`)シクシク)

参考サイトにあるIミノのスーパーローテーション時の動きを
全てどこがどこに何マス動いているか表に書き出し、
全てプログラムに直で書いています。

もちろん全ての対応を真心こめて丁寧に打ち込んだので
Iミノの動きに関しては間違いないです(´;ω;`)

Tスピンの壁

さて汗と涙を流しつつスーパーローテーションを作ったので
次はTスピンです。
色々調べたり聞いたところ動き自体はTミノを
スーパーローテーションで動かし隙間にキレイに差し込んで消すことのようです。
またこの消し方をしたときは専用エフェクトとともにボーナススコアが入るようです。

判定手順は
①最後の操作が回転であること
②4隅に3個以上ピースがある

②の図
f:id:hakase0274:20190215232404p:plain
図の赤丸のところにほかのピースが
3つ以上あれば判定するってことみたいです。

ちなみに
f:id:hakase0274:20190215232536p:plain
この青丸のところにほかのピースが
あるとTスピンミニっていう別物になるらしいです。

さてではこの判定を付けていきましょう!

・・・・・・・・
どこに?

はい今回私が躓いたところです。
(Iミノの手書きは躓いたんじゃなくて泣いただけ(´;ω;`))

この判定を
テトリミノ本体に持たせるのか?
テトリミノ回転クラスに持たせるのか?
盤面管理クラスに持たせるのか?

これで悩み結果どれを選んでも色々めちゃくちゃになりそうだという結論に至りました。

テトリミノに持たせた場合

これはすごく楽です。
テトリミノは自分のピースの情報と盤面管理クラスへの参照を持っているので
脳死で実装できます。
ただ問題は
そのあとでボーナススコアはどうするのか?
というのと
①テトリミノの状態に応じてのピース更新
②テトリミノの移動インターフェースの提供

という2つの責任を持ってしまっている
(これも設計ミスですねorz)
テトリミノクラスにこれ以上責任を増やすのはいかがなものだろうかという
設計的な疑問というか問題があります。

テトリミノ回転クラスに持たせた場合

これはちょっとアクセスがめんどくさいです。
というのもこのクラスはテトリミノクラスが公開している
回転させる処理をプレイヤーの入力を受けてキックしているクラスだからです。

回転のさせ方で判定できるスーパーローテーションとは異なり
周囲のピースの有無によって判定するTスピンでは現在のテトリミノの
ピース4つ全ての位置とその周辺情報が必要となりますが、
現在の私のプログラムでは回転クラスはこれらの情報にアクセスする術がありません

盤面管理クラスに持たせた場合

これもある意味簡単です。
名前の通りこのクラスは全てのピースの情報を握っています。
なので当たり前のように必要なピース情報は全て握っています。

ただ持っているのはピース情報だけなのです。
Tスピン判定には最後の操作が回転かという判定もあります。
今現状の作りだと盤面管理クラスがこの判定を行うためには
処理前と後の盤面を常に保持し計算し続けるという
なかなかバカにならないくらいコストを食いそうなことをしなければなりません。

またテトリミノと同じく負う責任が多くなってしまうという設計的に
辛い問題があります。

あとがき

今回は私自身が私の設計能力不足に打ちのめされる話でした。

正直何をどうしてもどっかで無理が生じてひずみが生まれてしまうのが
今の状態です。
多分どこも無理せず作るためには設計段階からやり直さなければ無理そうです。
ただそこにかかるコストもバカにならないのと
近い未来これを誰かに見せるというタイミングがやってくるので
時間的余裕もありません。

なのでどっか1ヶ所だけじゃなくてみんなで少しずつ無理するみたいな感じで
少しでも無理やり感を減らせないかと無い頭を全力でぶん回しています。

それでは今回はこの辺でノシ

今回作ったものはgithubに上げました
github.com