sql >> データベース >  >> RDS >> Database

ポーカー、ブラックジャック、ベロット、プレフェレンスはデータベースと何の関係がありますか?

    いくつかの非常に異なるカードゲームに対応するのに十分な柔軟性のあるデータベースを設計する方法。

    最近、データベースを使用してボードゲームの結果を保存する方法を示しました。ボードゲームは楽しいですが、オンライン版のクラシックゲームはこれだけではありません。カードゲームも大人気です。彼らはゲームプレイに運の要素を導入し、良いカードゲームには運以上のものが含まれています!

    この記事では、ゲームの試合、結果、プレーヤー、スコアを保存するためのデータモデルの構築に焦点を当てます。ここでの主な課題は、さまざまなカードゲームに関連するデータを保存することです。また、このデータを分析して、勝利戦略を決定したり、自分のプレイスキルを向上させたり、より優れたAI対戦相手を構築したりすることも検討できます。

    データベースで使用する4つのカードゲーム

    プレイヤーは配られるハンドをコントロールできないため、カードゲームは戦略、スキル、運を組み合わせたものです。その運の要素は、初心者に経験豊富なプレーヤーを打ち負かす機会を与え、それはカードゲームを中毒性にします。 (これは、論理と戦略に大きく依存するチェスのようなゲームとは異なります。多くのプレーヤーから、スキルレベルで対戦相手を見つけることができないため、チェスをプレイすることに興味がないと聞いています。)

    ポーカー、ブラックジャック、ベロ(またはベロテ)、プレフェレンスの4つの有名なカードゲームに焦点を当てます。それぞれに比較的複雑なルールがあり、習得するには時間がかかります。運と知識の比率もゲームごとに異なります。

    以下の4つのゲームすべての簡略化されたルールと詳細を簡単に見ていきます。ゲームの説明はかなりまばらですが、ゲームプレイのさまざまなモードと、データベース設計プロセス中に遭遇するさまざまなルールを示すのに十分なものが含まれています。

    ブラックジャック:

    • デッキ: それぞれ52枚のカードからなる1〜8枚のデッキ。ジョーカーカードはありません
    • プレーヤー: ディーラーと1人以上の対戦相手
    • 使用単位: 通常はお金
    • 基本ルール: プレイヤーは自分だけが見ることができる2枚のカードを手に入れます。ディーラーは2枚のカードを受け取ります。1枚は表向きでもう1枚は裏向きです。各プレイヤーは、より多くのカードを引くかどうかを決定します。ディーラーが最後に引きます。カードには、1から11の範囲のポイント値が割り当てられています。
    • 可能なプレーヤーアクション: ヒット、スタンド、スプリット、降伏
    • 目標と勝利の条件: プレイヤーのカードの合計は、ディーラーのカードよりも多くなります。いずれかのプレーヤーが21を超えると、そのプレーヤーは負けます。

    ポーカー(テキサスホールデム):

    • デッキ: 標準(フレンチスーツとも呼ばれます)52枚のカードデッキ。ジョーカーカードはありません。カードの色はほとんどの場合赤と黒です。
    • プレーヤー: 2から9;プレイヤーは交代で取引します
    • 使用単位:通常はチップ
    • 基本ルール: 各プレイヤーは2枚のカードを配られることから始めます。プレーヤーは賭けをします。テーブルの真ん中で3枚のカードが表向きに配られます。プレーヤーは再び賭けをします。 4枚目のカードが真ん中に置かれ、プレーヤーは再びベットします。次に、5枚目の最後のカードが配置され、最後の賭けが完了します。
    • 可能なプレーヤーアクション: フォールド、コール、レイズ、スモールブラインド、ビッグブラインド、リレイズ
    • 目標: 5枚のカードの可能な限り最高の手札を組み合わせます(プレーヤーの手札の2枚のカードとテーブルの真ん中の5枚のカードから)
    • 勝利条件:通常、テーブル上のすべてのチップを獲得するため

    Belot(Beloteのクロアチア語版):

    • デッキ: 通常、伝統的なドイツ語またはハンガリー語の32枚のカードデッキ。ジョーカーカードはありません
    • プレーヤー: 2〜4;通常、2人1​​組で4人のプレーヤー
    • 使用単位: ポイント
    • 基本ルール: 4人のプレイヤーのゲームの場合、各プレイヤーは6枚のカードを手札に、2枚のカードを裏向きに手に入れます。プレーヤーは最初にトランプスーツに入札します。トランプが決定された後、彼らは2枚の裏向きのカードを取り、それらを手札に置きます。宣言ラウンドが続き、その間に特定のカードの組み合わせが追加ポイントとして発表されます。すべてのカードが使用されるまでプレイは続きます。
    • 可能なプレーヤーアクション: パス、ビッドスーツ、宣言、スローカード
    • 手の目標: 半分以上のポイントを獲得するには
    • 勝利条件: 1001ポイント以上を獲得した最初のチームになる

    プレフェレンス:

    • デッキ: ほとんどの場合、伝統的なドイツ語またはハンガリー語の32枚のカードデッキ。ジョーカーカードはありません
    • プレーヤー: 3つ
    • 単位: ポイント
    • 基本ルール: すべてのプレイヤーに10枚のカードが配られます。 2枚の「キティ」または「タロン」カードがテーブルの中央に配置されます。プレーヤーは、スーツに入札するかどうかを決定します。プレイヤーはプレイするかどうかを決定します。
    • 可能なプレーヤーアクション: パス、スート、プレイ、プレイしない、カードを投げる
    • 目標: プレイされているプレフェレンスの変種によって異なります。標準バージョンでは、入札者は合計6つのトリックを獲得する必要があります。
    • 勝利条件: 3人のプレーヤーのスコアの合計が0の場合、ポイント数が最も少ないプレーヤーが勝ちます。

    データベースとカードゲームを組み合わせる理由

    ここでの私たちの目標は、これら4つのカードゲームに関連するすべてのデータを格納できるデータベースモデルを設計することです。データベースは、関連するすべてのデータを格納する場所としてWebアプリケーションで使用できます。初期のゲーム設定、ゲーム参加者、プレイ中に実行されたアクション、および単一の取引、ハンド、またはトリックの結果を保存したいと思います。また、試合には1つ以上の取引が関連付けられている可能性があるという事実にも留意する必要があります。

    データベースに保存されているものから、ゲーム中に発生したすべてのアクションを再現できるはずです。テキストフィールドを使用して、勝利条件、ゲームアクション、およびそれらの結果を説明します。これらは各ゲームに固有であり、Webアプリケーションロジックがテキストを解釈し、必要に応じて変換します。

    モデルの簡単な紹介




    このモデルにより、以下を含むすべての関連するゲームデータを保存できます。

    • ゲームのプロパティ
    • ゲームと試合のリスト
    • 参加者
    • ゲーム内アクション

    ゲームはさまざまな点で異なるため、 varchar(256)を頻繁に使用します プロパティ、移動、および結果を記述するデータ型。

    プレーヤー、試合、参加者

    モデルのこのセクションは3つのテーブルで構成され、登録されたプレーヤー、プレイされた試合、参加したプレーヤーに関するデータを保存するために使用されます。

    プレーヤー テーブルには、登録済みのプレーヤーに関するデータが格納されます。 ユーザー名 およびemail 属性は一意の値です。 nick_name 属性はプレーヤーのスクリーン名を保存します。

    一致 テーブルには、関連するすべての一致データが保持されます。通常、マッチは1つ以上のカードディール(ラウンド、ハンド、トリックとも呼ばれます)で構成されます。すべての試合には、プレーが始まる前にルールが設定されています。属性は次のとおりです。

    • game_id –ゲームのリスト(この場合は、ポーカー、ブラックジャック、ベロット、プレフェレンス)を含むテーブルを参照します。
    • start_time およびend_time 試合が開始および終了する実際の時間です。 end_timeに注意してください NULLにすることができます。ゲームが終了するまで、その価値はありません。また、試合が終了する前に試合が中止された場合、 end_time 値はNULLのままにすることができます。
    • number_of_players –ゲームを開始するために必要な参加者の数です
    • deck_id –ゲームで使用されるデッキを参照します。
    • Decks_used –はゲームをプレイするために使用されるデッキの数です。通常、この値は1になりますが、一部のゲームでは複数のデッキを使用します。
    • unit_id –は、ゲームのスコアリングに使用される単位(ポイント、チップ、お金など)です。
    • entry_fee –ゲームに参加するために必要なユニットの数です。ゲームで各プレーヤーが設定されたユニット数で開始する必要がない場合、これはNULLになる可能性があります。
    • Victory_conditions –どのプレーヤーが試合に勝ったかを決定します。 varcharを使用します 各ゲームの勝利条件(つまり、100ポイントに到達した最初のチーム)を記述し、それを解釈するためにアプリケーションを離れるデータ型。この柔軟性により、多くのゲームを追加する余地があります。
    • match_result –一致の結果をテキスト形式で保存します。 Victory_conditionsと同様 、アプリケーションに値を解釈させます。 end_time を挿入すると同時にその値を入力するため、この属性はNULLになる可能性があります。 値。

    参加者 テーブルには、試合のすべての参加者に関するデータが格納されます。 match_id およびplayer_id 属性はma​​tchへの参照です およびplayer テーブル。これらの値が一緒になって、テーブルの代替キーを形成します。

    ほとんどのゲームは、どのプレイヤーが最初に入札またはプレイするかをローテーションします。通常、最初のラウンドでは、最初にプレーするプレーヤー(オープニングプレーヤー)がゲームルールによって決定されます。次のラウンドでは、元のオープニングプレーヤーの左側(場合によっては右側)のプレーヤーが最初に進みます。 initial_player_orderを使用します 最初のラウンドのオープニングプレーヤーの序数を格納する属性。 match_id およびinitial_player_order 2人のプレーヤーが同時にプレイすることはできないため、属性は別の代替キーを形成します。

    スコア プレイヤーが試合を終了すると、属性が更新されます。これは、すべてのプレーヤーにとって同時に行われる場合もあり(たとえば、ベロットやプレフェレンス)、場合によっては、試合がまだ進行中の場合(たとえば、ポーカーやブラックジャック)になります。

    アクションとアクションタイプ

    カードゲームでプレイヤーが実行できるアクションについて考えるとき、次のことを保存する必要があることに気付きます。

    • アクションとは
    • そのアクションを実行したのは誰か
    • (どの取引で)アクションが発生したか
    • そのアクションで使用されたカード

    action_type tableは、プレーヤーのアクションの名前を含む単純な辞書です。考えられる値には、ドローカード、プレイカード、カードを別のプレーヤーに渡す、チェックしてレイズするなどがあります。

    アクション テーブルには、取引中に発生したすべてのイベントが保存されます。 deal_id card_id participant_id およびaction_type_id 取引、カード参加者、およびaction_typeの値を含むテーブルへの参照です。 participant_idに注意してください およびcard_id NULL値にすることができます。これは、一部のアクションがプレーヤーによって行われない(たとえば、ディーラーがカードを引いて表向きに置く)一方で、一部のアクションがカードを含まない(たとえば、ポーカーのレイズ)という事実によるものです。一致全体を再現できるようにするには、これらすべてのアクションを保存する必要があります。

    action_order 属性は、ゲーム内アクションの序数を格納します。たとえば、最初の入札は1の値を受け取ります。次の入札の値は2などになります。同時に複数のアクションを実行することはできません。したがって、deal_id およびaction_order 属性が一緒になって代替キーを形成します。

    action_notation 属性には、アクションの詳細な説明が含まれています。たとえばポーカーでは、レイズを保存できます。 アクションと任意の量。一部のアクションはより複雑になる可能性があるため、これらの値をテキストとして保存し、アプリケーションに解釈を任せることをお勧めします。

    取引と取引注文

    試合は、1つ以上のカード取引で構成されます。 参加者についてはすでに説明しました およびma​​tch 表ですが、取引との関係を示すために画像に含めています。 およびdeal_order テーブル。

    取引 テーブルには、単一の一致インスタンスについて必要なすべてのデータが格納されます。

    match_id 属性はそのインスタンスを適切な一致に関連付け、 start_time およびend_time そのインスタンスが開始された正確な時刻と終了した時刻を示します。

    move_time_limit およびdeal_result 属性は、時間制限(該当する場合)を保存するために使用されるテキストフィールドと、その取引の結果の説明の両方です。

    参加者 テーブル、 initial_player_order 属性は、オープニングマッチインスタンスのプレーヤーの順序を格納します。後続のターンの注文を保存するには、まったく新しいテーブル– deal_order が必要です テーブル。

    明らかに、deal_id およびparticipant_id 一致インスタンスと参加者への参照です。これらは一緒になって、 deal_orderの最初の代替キーを形成します テーブル。 player_order 属性には、プレーヤーがそのマッチインスタンスに参加した注文を示す値が含まれます。 deal_idと一緒に 、このテーブルの2番目の代替キーを形成します。 deal_result 属性は、個々のプレーヤーの試合結果を説明するテキストフィールドです。 スコア 属性には、取引結果に関連する数値が格納されます。

    スーツ、ランク、カード

    モデルのこのセクションでは、サポートされているすべてのゲームで使用するカードについて説明します。各カードにはスーツとランクがあります。

    スーツタイプ tableは、使用するすべてのスーツタイプを含む辞書です。 suite_type_nameの場合 、「フランスのスーツ」、「ドイツのスーツ」、「スイスドイツのスーツ」、「ラテンのスーツ」などの値を使用します。

    スーツ テーブルには、特定のデッキタイプに含まれるすべてのスーツの名前が含まれています。たとえば、フランスのデッキには「スペード」、「ハート」、「ダイヤ」、「クラブ」と呼ばれるスーツがあります。

    ランク 辞書には、「エース」、「キング」、「クイーン」、「ジャック」などの有名なカードの値があります。

    カード 表には、考えられるすべてのカードのリストが含まれています。各カードは、このテーブルに1回だけ表示されます。それがsuit_idが およびrank_id 属性は、このテーブルの代替キーを形成します。一部のカードにはスーツやランクがないため、両方の属性の値がNULLになる可能性があります(ジョーカーカードなど)。 is_joker_card 自明のブール値です。 card_name 属性は、カードをテキストで説明します:「スペードのエース」。

    カードとデッキ

    カードはデッキに属します。 1枚のカードが複数のデッキに表示される可能性があるため、 n:nが必要になります カード間の関係 およびデッキ テーブル。

    デッキ テーブルには、使用するすべてのカードデッキの名前を保存します。 deck_nameに保存されている値の例 属性は、「標準の52カードデッキ(フランス語)」または「32カードデッキ(ドイツ語)」です。

    card_in_deck リレーションは、カードを適切なデッキに割り当てるために使用されます。 card_id deck_id ペアはデッキの代替キーです テーブル。

    一致するプロパティ、デッキ、使用するユニット

    モデルのこのセクションには、新しいゲームを開始するためのいくつかの基本的なパラメータが含まれています。

    このセクションの主要部分は、ゲームです。 テーブル。このテーブルには、アプリケーションでサポートされているゲームに関するデータが格納されています。 game_name 属性には、「poker」、「blackjack」、「belot」、「préférence」などの値が含まれています。

    min_number_of_players およびmax_number_of_players 試合の参加者の最小数と最大数です。これらの属性はゲームの境界として機能し、試合の開始時に画面に表示されます。試合を開始する人は、この範囲から値を選択する必要があります。

    min_entrance_fee およびmax_entrance_fee 属性は入場料の範囲を示します。繰り返しますが、これはプレイ中のゲームに基づいています。

    possible_victory_conditionで 、試合に割り当てることができるすべての勝利条件を保存します。値は区切り文字で区切られます。

    ユニット 辞書は、すべてのゲームで使用されるすべてのユニットを格納するために使用されます。 unit_name 属性には、「ポイント」、「ドル」、「ユーロ」、「チップ」などの値が格納されます。

    game_deck およびgame_unit テーブルは同じロジックを使用します。試合で使用できるすべてのデッキとユニットのリストが含まれています。したがって、 game_id deck_id ペアとgame_id unit_id ペアは、それぞれのテーブルで代替キーを形成します。

    スコア

    このアプリケーションでは、カードゲームに参加したすべてのプレーヤーのスコアを保存します。ゲームごとに、1つの数値が計算されて保存されます。 (計算は、単一タイプのすべてのゲームでのプレーヤーの結果に基づいています。)このプレーヤーのスコアはランクに似ています。プレーヤーがどれだけ優れているかをユーザーに知らせます。

    計算プロセスに戻ります。 n:nを作成します player間の関係 およびgame テーブル。それがplayer_score です モデルのテーブル。 player_id およびscore_id 」が一緒になって、テーブルの代替キーを形成します。 「スコア 属性は、前述の数値を格納するために使用されます。

    非常に異なるルール、カード、デッキを使用するさまざまなカードゲームがあります。複数のカードゲームのデータを格納するデータベースを作成するには、いくつかの一般化を行う必要があります。これを行う1つの方法は、説明テキストフィールドを使用し、アプリケーションにそれらを挿入させることです。最も一般的な状況をカバーする方法を考え出すことはできますが、それはデータベース設計を指数関数的に複雑にします。

    この記事が示しているように、多くのゲームで1つのデータベースを使用できます。なぜあなたはこれをしますか? 3つの理由:1)同じデータベースを再利用できる。 2)分析を簡素化します。これにより、3)より優れたAI対戦相手の構築につながります。


    1. Oracle Database BLOBからJavaのInputStreamへ?

    2. 一貫性のないMySQLスレーブを再構築する方法は?

    3. PubNub関数のガイド

    4. SQLServerでテーブルレベルのアクセス許可を付与する