【Unity】2048のピース移動を考える

2019/10/1追記と一部修正


衝突判定を使ったピースの移動処理を作りましたが、
上手く行ったとは、喜べない状況になっております。

新しく、移動処理を考える必要が出てきたので、
非常に悩んでおります。(_ _ ??)/◇ ワカラン・・・


まず、2048のピース移動の条件を整理してみます。
・空きマスにはピースが移動できる
・隣あったピースが同数なら結合する
・隣あったピースが3枚なら移動方向の2つのみ結合する
・列に同じピースが4枚なら進行方向の先頭2枚と後ろ2枚が結合する
・結合後に出来たピースと後ろのピースが同じ番号でも結合しない

こんな感じでしょうか…


以下の条件でピースがどのようにして動くか考えてみます。

条件
・枠の左からポジションを0~3とする
・ピース移動は左へ移動する


実際にピースを置いて判別方法を考えてみます。
2048⑱.jpg
当然、左端なのでピースは動けません。

コードにすると
if(Position==0){停止}

続いて、
2048⑲.jpg
左に空きマスがあるので、動かす事ができます。

コードにすると
if(Position==1){
 if(Position0==空きマス){移動}
       }

しかし、ポジション0にピースが有った場合、
if(Position==1){
 if(Position0==空きマス){移動}
else if{0番ピースと同じか){結合}else{停止}
}

これだけでも分岐が複雑なのですが、
Positionが上がれば、判定する枠数も増えます。

枠数が増えた分、判定も増やさないといけないので、
正直、コードにする事が出来ません。(ノ_<。)うっうっうっ


少し見かたを変えてみる事に
空きマスは何も無い状態なので、飛ばして考えると
隣にあるピースは同じか異なるかの判断だけになります。

空きマスは数をカウントするだけで、
隣のピースが同じなら移動カウントを上乗せすれば、
最終的に何マス移動するか分かりそうです。

ポジション毎に処理が増えると思っていましたが、
空きマスを考えなければ、左のピースが同じかを判断するだけで
済みそうでっす(^・^)



コードを考えてみます。
ピースの有無は、無なら0、有ならピースナンバーを割り当てます。

先にPositionにPieceNoを代入しておく


int temp = 0; //左隣のピースナンバー取得変数
int pos = 0; //空きマスのカウント変数

if (現ポジション >= 1)
{
for (int i = 0; 現ポジション >= i; i++)
{
if (Position[i] == 0)
{
pos++;
}
else if (Position[i] == temp)
{
pos++;
temp = 0;
}
else
{
temp = Position[i];
}
}
}

現Position-pos;

少し説明するとルーブはピースがあるポジションまで回るようにします。
ポジション0番ならループに入らず、1番以上ならループに入る。
欲しい情報は現ポジションから左側なので、
ポジションカウントのiが現ポジションに到達したらループを終了します。

ループ内の判定は、
空きマスならカウント、
ピースがあれば左隣のピースと比較です。

tempにはピースがある場合、何番のピースかをセットします。

ポジション毎にピースの有無とセットを繰り返し、
左側のピース(temp)と比較して同じならposをカウントします。

tempの値がPosition[i]の値と同じならtemp=0としていますが、
生成されたピースが後ろのピースと同じなら結合が発生します。

結合後のピースは後ろから来るピースとは、結合できないので、
temp=0として、ピースは無いものと認識させています。

これでposにカウントされた分だけ移動させれば、
移動処理はできそうです。



下の配列で計算してみます。
2048⑳.jpg
計算コードはPieceManagerに組み込みます。

まず、ポジション1のピースから
ポジションが1以上なので、計算ループに入ります。

ループ一巡目
空きマス(0)なので、posがカウントされます。
ループ二巡目
ポジション1にピース1があるので、tempとの比較になります。
当然、値が違うので、temp = Position[i]のみが実行されます。

ループは現ポジション以下なので、これで終了します。

posカウントは1なので、現ポジション-1となります。


ポジション3のピースは、
一・二巡目は上と同じ事が計算されます。pos=1 temp=1
三巡目
ポジション2は0なので、posがカウントされます。pos=2 temp=1
四巡目
ポジション3にピース1があるので、tempとの比較になります。
二巡目でtemp=1が代入されているので、ピースナンバーと同じになります。
なので、temp=0とpos++が実行されます。

最終的にpos=3となるので、3マス移動する事になります。


これで計算は問題なさそうです。



さて、導入と行きたい所なんですが…

実際に組み込むには、各ピースの位置などを
把握する必要があります。

ピースのポジションを判断して管理するようにbool型変数に置き換えていましたが、
ポジション毎のPieceNoを管理する必要がでてきました。


次回は、管理部分とピースの移動を改良してみます。

上手くいくといいのですが… (´ヘ`;) ハァ



追記
スクリプトが間違っていました。
PieceNoはポジション配列変数に代入する為のもので、
比較にはポジション内の数値を読み取る必要があるので、
PieceNoを使用するとバグります。(°°;)。。うろうろ。。"((;°°)

スクリプトの方も修正しました。
申し訳ないです(_ _(--;(_ _(--; pekopeko


この記事へのコメント