私は現在、テトリスのような単純なゲームを持っていて、解決できない問題に遭遇しました。
テトリスとは異なりがある場合、単一の落下形状は、I落下する必要のある複数の、潜在的に連動形状を有しています。最終的な位置を計算する必要があります。以下を検討してください。
緑の形状の最終的な位置を計算するには、別の正方形またはボードの端に当たるまで、すべての正方形をスキャンします。できた
複数の単純な形状の場合は、ボードを上に向かって作業します。したがって、赤は移動する必要がないことがわかり、オレンジは1つ下がり、緑は3つ下がります。できた
連動する緑と赤の形の扱い方がわかりません。#2のロジックを使用すると、空中で「スタック」してしまいます。緑の形状を下にスキャンすると、赤に遭遇して移動しません。赤の場合も同様です。解決策は、2つの形状を1つとして扱うことです。
#3と同様に、このシナリオでは、オブジェクトを1つとして扱うことで成功させることもできます。
#3や#4とは異なり、オレンジのシェイプは1スクエアの高さに浮き上がるため、シェイプを1つとして扱うことができませんでした...
問題#6の別のバリエーション。
ますます複雑なシナリオで織り交ぜる多くの図形がある他のシナリオも考えられますが、上記で問題の最も基本的な部分がカバーされていると思います。
私がまだ出会っていない/考えていないエレガントな解決策があるように感じます。洞察、アイデア、またはリソースに非常に感謝します。
解決
私が思いついた解決策は確かにエレガントです、以下の@ user35958の答えに基づいて、次の再帰関数(疑似コード)を作成しました
function stop(square1, square2){
// Skip if we're already stopped
if(square1.stopped){
return;
}
// Are we comparing squares?
if(!square2){
// We are NOT comparing squares, simply stop.
square1.stopped = true;
} else {
// Stop IF
// square1 is directly above square2
// square1 is connected to square2 (part of the same complex shape)
if(square1.x == square2.x && square1.y == (square2.y+1) || isConnected(square1, square2)){
square1.stopped = true;
}
}
// If we're now stopped, we must recurse to our neighbours
stop(square1, squareAbove);
stop(square1, squareBelow);
stop(square1, squareRight);
stop(square1, squareDown);
}
ソリューションの各パスを示すアニメーションGIF
要約すると:
- 正方形を「停止」すると、次も停止します。
- その上の任意の正方形。常に。
- 接続されている隣接する正方形(つまり、同じ形状)。
- 一番下の行全体を停止し、関数は四角形を繰り返します。
- すべての正方形が止まるまで繰り返します。
- 次に、アニメーション化します。