作るのは http://codevswc.jp/jpn/rule.html これです。
所謂、「落ちゲー」をSQLで作るにはどうしたらよいか?ということになります。
かなり複雑でルールを良く読み込まないの理解できないでしょう。
是非、よく読んで、「自分なら SQL でこういう方針で作る」
「Javaなら、.Netなら、Rubyなら…… こういう方針で作る」
と想像しながら読んでください。
悩んでいます(苦笑)
Javaでやったとき、パックや盤の左上を原点(0, 0)として、それぞれRow, Col(行, 列)としてコーディングしたのですが、一番底の位置がゼロでないのが、どうもしっくりこなかった。
で、SQLでするのに左下を原点(0, 0)としようと思ったのですが、左下だとこれまたRow, Col(行, 列)と呼んではしっくりこない。
左下を原点とすると(X, Y)としないとしっくりこないが、そうすると元のRow, Col(行, 列)で言うとCol, Row(列, 行)と逆になることになって、これまたしっくりこない。
どうするのが一般的なのでしょうか?
私はゲームをほとんど作ったことがないのでよく分かりませんので、おかしいと思った人はコメントや、Twitterで絡んでください。
とりあえず、左下を原点、Row, Col(行, 列)としますので、しっくりこない人は適当に読み替えてください。
テーブル
欲張って、SimulationID というのを付けています。実際に問題を解くにはSimulationIDだけでは足りないと思うけれど……。
データは 0 以外の数字をPackテーブルに突っ込みます(ここのコードは単純なINSERTなので解説しません)。
それを、1ターン毎にBoardテーブルに追加していくことでゲームを再現します。
CREATE TABLE Pack
(
GameID int DEFAULT 0 NOT NULL,
Turn int DEFAULT 0 NOT NULL,
Row int DEFAULT 0 NOT NULL,
Col int DEFAULT 0 NOT NULL,
Num int DEFAULT 0 NOT NULL
, PRIMARY KEY (GameID, Turn, Row, Col)
);
CREATE TABLE Board -- Chain単位で保存する
(
GameID int DEFAULT 0 NOT NULL,
SimulationID money DEFAULT 0 NOT NULL,
Turn int DEFAULT 0 NOT NULL,
Chain int DEFAULT 0 NOT NULL,
Row int DEFAULT 0 NOT NULL,
Col int DEFAULT 0 NOT NULL,
Num int DEFAULT 0 NOT NULL
, PRIMARY KEY (GameID, SimulationID, Turn, Chain, Row, Col)
);
CREATE TABLE Deleted -- なくても良い。ステップで考えるときに必要
(
GameID int NOT NULL,
SimulationID money NOT NULL,
Turn int NOT NULL,
Chains int NOT NULL,
Row int NOT NULL,
Col int NOT NULL
, PRIMARY KEY (GameID, SimulationID, Turn, Chains, Row, Col)
);
CREATE TABLE Turn -- 記録する
(
GameID int DEFAULT 0 NOT NULL,
SimulationID money DEFAULT 0 NOT NULL,
Turn int DEFAULT 0 NOT NULL,
XPos int DEFAULT 0 NOT NULL,
Rot int DEFAULT 0 NOT NULL,
Ereases int DEFAULT 0 NULL,
Chains int DEFAULT 0 NULL,
FireCounts int DEFAULT 1 NULL,
CurScore money DEFAULT 0 NULL,
TotalScore money DEFAULT 0 NULL
, PRIMARY KEY (GameID, SimulationID, Turn)
);
CREATE TABLE Game -- パラメータで渡しても良い気もする
(
GameID int DEFAULT 0 NOT NULL,
Width int NULL,
Height int NULL,
MaxTurn int NULL,
PackSize int NULL,
Sums int NULL,
P_Point int NULL,
A_Point int NULL,
B_obs int NULL,
Th int NULL,
Memo text NULL
, PRIMARY KEY (GameID)
);
そのほかに必要なテーブル。
CREATE TABLE Direction4 -- 4方向にチェックするときように4レコード保存
(
Angle int NOT NULL,
RowOffset int NULL,
ColOffset int NULL,
Memo nvarchar(8) NULL
, PRIMARY KEY (Angle)
);
CREATE TABLE Direction8 -- 8方向にチェックするときように8レコード保存
(
Angle int NOT NULL,
RowOffset int NULL,
ColOffset int NULL,
Memo nvarchar(8) NULL
, PRIMARY KEY (Angle)
);
Direction4 には、上、右上、右、右下、つまり、RowOffset, ColOffset をそれぞれ、(1, 0)(1, 1)(0, 1)(-1, 1) を登録する。
Direction8 には、上、右上、右、右下、下、左下、左、左上、つまり、RowOffset, ColOffset をそれぞれ、(1, 0)(1, 1)(0, 1)(-1, 1)(-1, 0)(-1, -1)(0, -1)(1, -1) を登録する。
(つづく)