4

私は次のようなゲームテーブルを持っています:

CREATE TABLE game_piece(
  x Integer,
  y Integer,
  type Integer
);

各 (x,y) は 1 個しか持てません。グリッドの表現 (数字は型):

1235
1134
9678

接続されているとは、次のように垂直または水平に原点のすぐ隣にある必要があることを意味します。

 C   C=connected
COC  O=origin
 C

まともな解決策があれば、データベースのグリッド全体を取得してPythonで実行する必要なく、グリッド上のどこかに接続された3つのピースがあるかどうかを確認したいと思います。提案?

4

5 に答える 5

1

「接続」とは、隣接していることを意味すると仮定します。つまり、(5,3,1234) と (4,3,1234) が接続されます。

そのため、できることは、テーブルをそれ自体に 2 回結合することです。各結合は、前の結合に依存し、条件は次のとおりです。

on  nextPiece.type = lastPiece.type
and (nextPiece.x in (lastPiece.x - 1, lastPiece.x + 1)
or  nextPiece.y in (lastPiece.x - 1, lastPiece.x + 1))

これは、対角線が隣接しているとは見なさないことに注意してください。

この手法の問題点は、重複が返されることです。レコード A がレコード B に接続されている場合、A と B の両方が結果セットに表示されます。2 回参加しているため、3 つの重複が表示されます...select distinct一致が見つかったかどうかだけに関心がある場合は、実行できますが、一般的に、クエリはどちらの方法でも特に高速ではありません (グリッドの大きさと人口のまばらさ)。

EDIT Braibaのソリューション(および以下のコメント)を参照してください:私は間違いを犯しました:P

于 2012-07-12T07:43:39.890 に答える
0

接続の意味によっては、データベース全体をダンプする必要はなく、4方向に2つだけダンプする必要があります。

select x, y, 
from game_piece 
where (
       (x between origin_x - 2 AND origin_x + 2 AND y = origin_y) 
    OR (y between origin_y - 2 AND origin_y + 2 AND x = origin_x)
      ) 
 AND type = the_type;

origin_xorigin_yはチェックしたいピースの座標です。

それはあなたがチェックしなければならない1から8個の間をダンプします。

ゲームテーブルが非常に大きい場合は、x列とy列にインデックスを追加する必要があります。そうしないと、役に立たない場合があります。

それが役に立てば幸い。

M。

于 2012-07-12T07:44:57.657 に答える
0

このソリューションを使用できます:

SELECT 1
FROM game_piece
WHERE
    (x = $o_x AND y IN ($o_y + 1, $o_y - 1)) OR
    (y = $o_y AND x IN ($o_x + 1, $o_x - 1))
GROUP BY type
HAVING COUNT(1) = 3

$o_xそして$o_y、それぞれ originX および originY 入力パラメータです。

原点に (垂直または水平のいずれかで) 接続されている同じタイプのピースがちょうど 3 つある場合、これは を返し1ます。それ以外の場合は、空の結果セットを返します。


編集:

グリッド上に 2 つ以上の同じ隣接するタイプを持つピースがあるかどうかを調べるために試すことができること:

SELECT COUNT(1) > 0 AS doesExist
FROM
(
    SELECT 1
    FROM game_piece p
    INNER JOIN game_piece o ON
         p.type = o.type AND (
             (p.x = o.x AND p.y IN (o.y + 1, o.y - 1)) OR
             (p.y = o.y AND p.x IN (o.x + 1, o.x - 1))
         )
    GROUP BY p.type, o.x, o.y
    HAVING COUNT(1) > 1
) a

11 つ以上のピースがある場合とそうでない場合はどちらが返され0ます。

于 2012-07-12T08:01:22.517 に答える
0

これにより、さまざまな接続タイプの数が返されます。

select count(distinct type) as connections
from game_piece
where ((y = $y and x between $x - 1 and $x + 1)
  or (x = $x and y between $y - 1 and $y + 1))
and (x != $x or y != $y) -- exclude the origin itself
于 2012-07-12T07:47:01.337 に答える