CODE VS 2.1 をSQLでやるとどうなる4
前回の続きです。今回はパックを回転するするところまでを作ります。
作るのは http://codevswc.jp/jpn/rule.html これです。データは、与えられるInputのサンプルとします。
是非、ルールをよく読んで、「自分なら SQL でこういう方針で作る」
「Javaなら、.Netなら、Rubyなら…… こういう方針で作る」
と想像しながら読んでください。
パックを回転します
回転するには図の様に、Row、Colを変更する必要があります。これは他の言語でもほぼ同じでしょう。もちろん、左上を (0, 0) としたときは変更の必要があるので、お気を付けください。
具体的には図の通りになります。
これは他の言語でもされるように関数にしましょう。
……ですが、SQLでは一つずつ作ることになります。
CREATE FUNCTION ChangeRow (@Rot int, @Row int, @Col int, @Size int) RETURNS int BEGIN DECLARE @Ret int; SET @Ret = CASE @Rot WHEN 1 THEN (@Size - 1) - @Col WHEN 2 THEN (@Size - 1) - @Row WHEN 3 THEN @Col ELSE @Row END; RETURN @Ret; END; CREATE FUNCTION ChangeCol (@Rot int, @Row int, @Col int, @Size int) RETURNS int BEGIN DECLARE @Ret int; SET @Ret = CASE @Rot WHEN 1 THEN @Row WHEN 2 THEN (@Size - 1) - @Col WHEN 3 THEN (@Size - 1) - @Row WHEN @Col END; RETURN @Ret; END;
パックを投下するリストを作る
ルールhttp://codevswc.jp/jpn/rule.html を読むと、パックは横方向(X軸)はマイナスの位置にも落とせます。
ゼロオリジンになっていますので、取り得るパックを落とす位置の一番右端は、
0 - パックのサイズ - 1
となります。
左端は、
盤の幅 - 1
となります。
パックは90°ずつ回した4パターンがあります。
今回のゲーム
パックのサイズ = 4
盤の幅 = 10
ですから、パックを投下するパターンは、
-3 〜 9 = 13通り × 4つの角度 = 52通り
になります。
SELECT xp.Seq AS XPos , rt.Seq AS Rot FROM tf_SequentialNums(-3, 10) AS xp CROSS JOIN tf_SequentialNums(0, 3) AS rt
1つめのパックを落とせる全てのパターンを作ることができます。
SimulationID は 1から採番して 0を実際に採用したアウトプットとします。
投下した時点でTurnはカウントアップされます。
INSERT INTO Turn (GameID, SimulationID, Turn, XPos, Rot) SELECT 0, Rank() OVER(ORDER BY xp.Seq, rt.Seq) , 0 + 1, xp.Seq, rt.Seq FROM tf_SequentialNums(-3, 9) AS xp CROSS JOIN tf_SequentialNums(0, 3) AS rt;
回転したリスト
作成したTurn(シミュレーション用)のデータとパックを結合して、回転後のRow、Colの一覧を見る。
SELECT t.SimulationID, t.Rot , p.Row, p.Col, p.Num , dbo.ChangeRow(t.Rot, p.Row, p.Col, 4) AS tRow -- 回転後のRow , dbo.ChangeCol(t.Rot, p.Row, p.Col, 4) AS tCol -- 回転後のCol FROM Turn t INNER JOIN Pack p --参照されるPackテーブル ON t.GameID = p.GameID -- TurnテーブルのキーのSimulationIDと結合して AND t.Turn = p.Turn -- ないのでSimulationIDの種類数倍になる。
つづく