本を読む

読書やコンピュータなどに関するメモ

どう書く?org「麻雀ゲーム1」をSQLで考えるメモ

 ゲームとしてのアルゴリズムはよくわかりませんが、データ構造はいろいろ考えられそうです。

 とりあえず、SQLの勉強として、SQLでモデル化した場合について途中まで考えたメモを残してみます。文法はとりあえずどのRDBMSともつかないものです。勉強中なので、おかしな箇所あったらご指摘ください。なお、この場合、SQLでモデル化することに実用的な意味はないと思います。

データの表現

 全体を牌のテーブルとして考えてみます。

CREATE TABLE pais (
    id INTEGER NOT NULL,

    paitype_id INTEGER NOT NULL,        -- → paitypes
    paitype_num INTEGER,

    location_id INTEGER NOT NULL,       -- → locations
    location_num INTEGER
);

 paitypesはこんな感じで。

CREATE TABLE paitypes (
    id INTEGER NOT NULL,
    name VARCHAR(5)
);

-- 萬子、索子、筒子
INSERT INTO paitypes (id, name) VALUES (0, 'MAN');
INSERT INTO paitypes (id, name) VALUES (1, 'SOU');
INSERT INTO paitypes (id, name) VALUES (2, 'PIN');
-- 風牌
INSERT INTO paitypes (id, name) VALUES (3, 'TON');
INSERT INTO paitypes (id, name) VALUES (4, 'NAN');
INSERT INTO paitypes (id, name) VALUES (5, 'SHA');
INSERT INTO paitypes (id, name) VALUES (6, 'PEI');
-- 三元牌
INSERT INTO paitypes (id, name) VALUES (7, 'HAKU');
INSERT INTO paitypes (id, name) VALUES (8, 'HATSU');
INSERT INTO paitypes (id, name) VALUES (9, 'CHUN');

 locationsはこんな感じで。

CREATE TABLE locations (
    id INTEGER NOT NULL,
    name VARCHAR(7)
);

-- 山
INSERT INTO locations (id, name) VALUES (0, 'YAMA');
-- 手牌
INSERT INTO locations (id, name) VALUES (1, 'TON');
INSERT INTO locations (id, name) VALUES (2, 'NAN');
INSERT INTO locations (id, name) VALUES (3, 'SHA');
INSERT INTO locations (id, name) VALUES (4, 'PEI');
-- 河
INSERT INTO locations (id, name) VALUES (5, 'TON_HOU');
INSERT INTO locations (id, name) VALUES (6, 'NAN_HOU');
INSERT INTO locations (id, name) VALUES (7, 'SHA_HOU');
INSERT INTO locations (id, name) VALUES (8, 'PEI_HOU');

 あとは136牌をINSERT。

 なお、リーチもドラも鳴きも、問題文にないので対応していません。

洗牌、山積

2. 牌をかき混ぜてから山を作成する機能.

 開門とかは問題文にないので、単なる連番を振ります。

 これはpaisからORDER BY rand()とかのランダム順でSELECTした結果に対し、location_idを0にして、location_numに連番を振ることで実現できます。連番を振るのが面倒なRDBMSの場合には、location_numを設定せず、以降の配牌や自摸のときにORDER BY rand()とかのランダム順を使うことになるでしょう。

配牌

 これは、paisとlocationsをjoinして、location_idが'YAMA'なものをORDER BY location_numのLIMIT 13(親は14)を取り出し、UPDATEでlocation_idとlocation_numを手牌のものに変えてやれば実現できます。

3. 手牌を理牌する機能

 この要件は、location_numで表現できています。手牌を表示する場合は、paisにpaitypesとlocationsをjoinしてWHEREでプレイヤーの手配に絞ってSELECTするだけで実現できます。

自摸、打牌

4. 山から牌を取る操作.
5. 手配を切る操作 (ツモ切りで構いません).
6. 河を保存する機能.

 配牌と同じ方法で山から1つを取り出します。ツモ切りということなので、そのままlocation_idをプレイヤーの河に書き変えます。location_numで順番を付けておくとよいでしょう。河の表示は、paisにpaitypesとlocationsをjoinしてWHEREでプレイヤーの河に絞ってSELECTするだけで実現できます。

まとめ

  • 136牌のテーブルとして表現する
  • 牌ごとに場所の情報を持つ
  • 牌の移動はUPDATEで実現する

 …書いてみると、なんかすごいあたりまえですね。

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

http://emasaka.blog65.fc2.com/tb.php/527-38aff978

 | HOME | 

Categories

Recent Entries

Recent Comments

Recent Trackbacks

Appendix

emasaka

emasaka

フリーター。
連絡先はこのへん

Monthly


FC2Ad