0

ゲーム Bejewelled が提示するプログラミングの課題に興味があります。シンプルなゲームのように見えますが、プログラム的には見た目よりも複雑です。

ボードの評価方法のヒントを探していたところ、Simple-Talk の良い人たちによるこの QUIZに出くわしました。彼らは勝利の答えを投稿しましたが、解決策がどのように機能するかを本当に理解できれば、私はタールを塗られて羽ばたきます。マトリックスと、セルの値を行と列と一緒にグループ化することに関係があることがわかりますが、それは私がこれまでに得た限りです。誰かが私のためにそれをもう少し分解できますか?

投稿された解決策 (クイズの詳細は上記のリンクにあります):

--====== Table matches needs to be loaded only once
CREATE TABLE matches(offsetRow1 INT, offsetCol1 INT, offsetRow2 INT, ofsetCol2 INT, directions VARCHAR(20))
-- for horizontal 
INSERT INTO matches VALUES(-1, -1, -1, -2, 'up')
INSERT INTO matches VALUES(-1, -1, -1, 1, 'up')
INSERT INTO matches VALUES(-1, 1, -1, 2, 'up')        
INSERT INTO matches VALUES( 1, -1, 1, -2, 'down')           
INSERT INTO matches VALUES( 1, -1, 1, 1, 'down')
INSERT INTO matches VALUES( 1, 1, 1, 2, 'down')       
INSERT INTO matches VALUES( 0, -2, 0, -3, 'left')     
INSERT INTO matches VALUES( 0, 2, 0, 3, 'right')            
-- for verical
INSERT INTO matches VALUES(-2, -1, -1, -1, 'left')
INSERT INTO matches VALUES(-1, -1, 1, -1, 'left')
INSERT INTO matches VALUES( 1, -1, 2, -1, 'left')
INSERT INTO matches VALUES(-2, 1, -1, 1, 'right')
INSERT INTO matches VALUES(-1, 1, 1, 1, 'right')
INSERT INTO matches VALUES( 1, 1, 2, 1, 'right')
INSERT INTO matches VALUES(-2, 0, -3, 0, 'up')
INSERT INTO matches VALUES( 2, 0, 3, 0, 'down')

--==================================================
;WITH CTE
      AS
  (
  SELECT
        [Row] = CAST( [#] AS INT ),
        [Col] = CAST( [Col] AS INT ),
        [Value]
    FROM bejeweled
        UNPIVOT ([Value] FOR [Col] IN ([1],[2],[3],[4],[5],[6],[7],[8],[9])) unpvt
  )
SELECT DISTINCT T.Row, T.Col, T.Value, directions
  FROM CTE T
      JOIN CTE T1
      ON T.Value = T1.Value
      JOIN CTE T2
      ON T.Value = T2.Value
      JOIN matches
      ON (T1.Row - T.Row) = offsetRow1
    AND (T1.Col - T.Col) = offsetCol1
    AND (T2.Row - T.Row) = offsetRow2
    AND (T2.Col - T.Col) = ofsetCol2
  ORDER BY T.Row, T.Col
4

1 に答える 1

3

アンピボット関数は、元のデータを行列ではなく線形リストに変換します。たとえば、元の列の 1,1 の値は 8 だったので、新しいテーブルの最初の行は 1,1,8 です。同様に、元のテーブルの最初の行の 2 番目の列は 5 だったので、新しいテーブルの 2 番目の行は 1,2,5 です。

「With CTE」は、CTE という名前のメモリ内テーブルを効果的に作成するため、この新しい 3 列、81 行のテーブルは CTE と呼ばれます。

ロジックは内部結合で発生します。CTE のすべてのセルは、値が一致する CTE のすべてのセルに結合され、値が一致するセル自体と再び結合されます。これは、元のテーブルのすべてのセルが、他のすべての 3 項目の一致を認識していることを意味します。つまり、値 '1' (たとえば) を含む 3 つのセルのリストのすべての順列が返されます。

値 2 を見てみましょう。1 つは (6,2) に、もう 1 つは (5,3) に、もう 1 つは (7,3) にあるため、内部結合の可能な値の 1 つは T.Row が 6 になります。 、T.Col は 2、T1.Row は 5、T1.Col は 3、T2.Row は 7、T2.Col は 3 です。これを見ると、(6,2) と (6,3) が交換されていることがわかります。 ) は 3 つを続けて配置します。しかし、JOIN ステートメントはどのようにしてそれを知るのでしょうか?

有効な手は、T1 と T2 の間に T を入れる手です。3 つの組み合わせが一致するかどうかを判断する最も簡単な方法は、オフセットをチェックし、それを動作する相対位置のリストと比較することです。T1 は T (-1,1) の右上にあり、T2 は T (1,1) の右下にあります。(-1,1,1,1) が有効な一致かどうかを確認します。そのため、JOIN 基準に合格し、結果として保持されます。

于 2008-12-17T17:30:04.887 に答える