Database
 sql >> Datenbank >  >> RDS >> Database

Was haben Poker, Blackjack, Belot und Préférence mit Datenbanken zu tun?

Wie man eine Datenbank gestaltet, die flexibel genug ist, um mehrere sehr unterschiedliche Kartenspiele aufzunehmen.

Kürzlich haben wir gezeigt, wie eine Datenbank zum Speichern von Brettspielergebnissen verwendet werden kann. Brettspiele machen Spaß, aber sie sind nicht die einzige Online-Version klassischer Spiele. Auch Kartenspiele sind sehr beliebt. Sie führen ein Glückselement in das Spiel ein, und in einem guten Kartenspiel steckt viel mehr als nur Glück!

In diesem Artikel konzentrieren wir uns auf den Aufbau eines Datenmodells zum Speichern von Spielmatches, Ergebnissen, Spielern und Spielständen. Die größte Herausforderung besteht hier darin, Daten zu vielen verschiedenen Kartenspielen zu speichern. Wir könnten auch in Betracht ziehen, diese Daten zu analysieren, um Gewinnstrategien zu bestimmen, unsere eigenen Spielfähigkeiten zu verbessern oder einen besseren KI-Gegner zu bauen.

Die vier Kartenspiele, die wir in unserer Datenbank verwenden werden

Da die Spieler die Hand, die ihnen ausgeteilt wird, nicht kontrollieren können, kombinieren Kartenspiele Strategie, Geschicklichkeit und Glück. Dieser Glücksfaktor gibt einem Anfänger die Chance, einen erfahrenen Spieler zu schlagen, und macht Kartenspiele süchtig. (Dies unterscheidet sich von Spielen wie Schach, die stark auf Logik und Strategie beruhen. Ich habe von vielen Spielern gehört, dass sie nicht am Schachspielen interessiert sind, weil sie keine Gegner auf ihrem Könnensniveau finden.)

Wir konzentrieren uns auf vier bekannte Kartenspiele:Poker, Blackjack, Belot (oder Belote) und Préférence. Jeder von ihnen hat relativ komplexe Regeln und erfordert einige Zeit, um sie zu beherrschen. Auch das Verhältnis von Glück vs. Wissen ist bei jedem Spiel anders.

Wir werfen einen kurzen Blick auf die vereinfachten Regeln und Besonderheiten für alle vier Spiele unten. Spielbeschreibungen sind ziemlich spärlich, aber wir haben genug eingefügt, um die verschiedenen Spielmodi und die verschiedenen Regeln zu zeigen, denen wir während des Datenbankdesignprozesses begegnen werden.

Blackjack:

  • Deck: Ein bis acht Decks mit jeweils 52 Karten; keine Jokerkarten
  • Spieler: Dealer und 1 oder mehr Gegner
  • Verwendete Einheit: Normalerweise Geld
  • Grundregeln: Die Spieler erhalten 2 Karten, die nur sie sehen können; der Dealer erhält zwei Karten, eine offen und die andere verdeckt; jeder Spieler entscheidet, mehr Karten zu ziehen (oder nicht); der Dealer zieht zuletzt. Karten haben zugewiesene Punktwerte von 1 bis 11.
  • Mögliche Spieleraktionen: Hit, Stand, Split, Surrender
  • Ziel- und Siegbedingung: Die Summe der Karten eines Spielers ist größer als die des Dealers; Wenn ein Spieler über 21 geht, verliert dieser Spieler.

Poker (Texas Hold'Em):

  • Deck: Standard (auch als französische Farbe bekannt) 52-Karten-Deck; keine Jokerkarten. Karten sind meistens rot und schwarz.
  • Spieler: Zwei bis neun; Die Spieler handeln abwechselnd
  • Verwendete Einheit:Normalerweise Chips
  • Grundregeln: Jeder Spieler beginnt, indem er zwei Karten ausgeteilt bekommt; Spieler platzieren ihre Wetten; drei Karten werden offen in die Mitte des Tisches gelegt; Spieler platzieren erneut ihre Wetten; eine vierte Karte wird in die Mitte gelegt und die Spieler setzen erneut; dann wird die fünfte und letzte Karte platziert und die letzte Setzrunde ist abgeschlossen.
  • Mögliche Spieleraktionen: Fold, Call, Raise, Small Blind, Big Blind, Reraise
  • Ziel: Kombinieren Sie die bestmögliche Hand aus fünf Karten (aus den zwei Karten in der Hand des Spielers und den fünf Karten in der Mitte des Tisches)
  • Siegbedingung:Normalerweise alle Chips auf dem Tisch gewinnen

Belot (kroatische Variante von Belote):

  • Deck: Normalerweise das traditionelle deutsche oder ungarische 32-Karten-Deck; keine Jokerkarten
  • Spieler: Zwei bis vier; normalerweise vier Spieler in Zweierpaaren
  • Verwendete Einheit: Punkte
  • Grundregeln: Bei einem Spiel mit vier Spielern bekommt jeder Spieler sechs Karten auf die Hand und zwei verdeckte Karten; Spieler bieten zuerst für die Trumpffarbe; nachdem Trumpf bestimmt wurde, nehmen sie die beiden verdeckten Karten und nehmen sie auf die Hand; es folgt eine Deklarationsrunde, in der bestimmte Kartenkombinationen für zusätzliche Punkte bekannt gegeben werden; Das Spiel wird fortgesetzt, bis alle Karten verwendet wurden.
  • Mögliche Spieleraktionen: Passen, Ansagen, Erklärung, Karte werfen
  • Tor für die Hand: Mehr als die Hälfte der Punkte gewinnen
  • Siegbedingung: Erreiche als erstes Team 1001 Punkte oder mehr

Präferenz:

  • Deck: Meistens ein traditionelles deutsches oder ungarisches 32-Karten-Deck; keine Jokerkarten
  • Spieler: Drei
  • Einheiten: Punkte
  • Grundregeln: Alle Spieler erhalten 10 Karten; zwei „Kätzchen“- oder „Krallen“-Karten werden in die Mitte des Tisches gelegt; Spieler bestimmen, ob sie auf eine Farbe bieten möchten; Spieler entscheiden, ob sie spielen oder nicht.
  • Mögliche Spieleraktionen: Pass, Bid Suit, Play, Don't Play, Throw Card
  • Ziel: Hängt von der gespielten Variante von Préférence ab; in der Standardversion muss der Bieter insgesamt sechs Stiche gewinnen.
  • Siegbedingung: Wenn die Summe der Punkte aller drei Spieler 0 ist, gewinnt der Spieler mit der niedrigsten Punktzahl.

Warum Datenbanken und Kartenspiele kombinieren?

Unser Ziel hier ist es, ein Datenbankmodell zu entwerfen, das alle relevanten Daten für diese vier Kartenspiele speichern könnte. Die Datenbank könnte von einer Webanwendung als Speicherort für alle relevanten Daten verwendet werden. Wir möchten anfängliche Spieleinstellungen, Spielteilnehmer, während des Spiels durchgeführte Aktionen und das Ergebnis eines einzelnen Deals, einer Hand oder eines Tricks speichern. Wir müssen auch bedenken, dass mit einem Match ein oder mehrere Deals verbunden sein können.

Aus dem, was wir in unserer Datenbank speichern, sollten wir in der Lage sein, alle Aktionen nachzubilden, die während des Spiels stattgefunden haben. Wir verwenden Textfelder, um Siegbedingungen, Spielaktionen und deren Ergebnisse zu beschreiben. Diese sind für jedes Spiel spezifisch und die Webanwendungslogik interpretiert den Text und transformiert ihn nach Bedarf.

Eine kurze Einführung in das Modell




Dieses Modell ermöglicht es uns, alle relevanten Spieldaten zu speichern, einschließlich:

  • Spieleigenschaften
  • Liste der Spiele und Wettkämpfe
  • Teilnehmer
  • Aktionen im Spiel

Da sich Spiele in vielerlei Hinsicht unterscheiden, verwenden wir häufig varchar(256) Datentyp zur Beschreibung von Eigenschaften, Zügen und Ergebnissen.

Spieler, Spiele und Teilnehmer

Dieser Abschnitt des Modells besteht aus drei Tabellen und wird verwendet, um Daten über registrierte Spieler, die gespielten Spiele und die beteiligten Spieler zu speichern.

Der player Tabelle speichert Daten über registrierte Spieler. Der username und email Attribute sind eindeutige Werte. Der nick_name -Attribut speichert die Bildschirmnamen der Spieler.

Die match Tabelle enthält alle relevanten Spieldaten. Im Allgemeinen besteht ein Spiel aus einem oder mehreren Kartenteilen (auch bekannt als Runden, Hände oder Tricks). Alle Spiele haben festgelegte Regeln, bevor das Spiel beginnt. Die Attribute lauten wie folgt:

  • game_id – Verweist auf die Tabelle mit der Liste der Spiele (in diesem Fall Poker, Blackjack, Belot und Préférence).
  • start_time und end_time sind die tatsächlichen Zeiten, zu denen ein Spiel beginnt und endet. Beachten Sie, dass die end_time kann NULL sein; Wir werden seinen Wert nicht haben, bis das Spiel endet. Auch wenn ein Spiel abgebrochen wird, bevor es beendet ist, wird die end_time Wert kann NULL bleiben.
  • number_of_players – ist die Anzahl der Teilnehmer, die erforderlich ist, um das Spiel zu starten
  • deck_id – bezieht sich auf das im Spiel verwendete Deck.
  • decks_used – ist die Anzahl der Decks, die zum Spielen des Spiels verwendet werden. Normalerweise ist dieser Wert 1, aber einige Spiele verwenden mehrere Decks.
  • unit_id – ist die Einheit (Punkte, Chips, Geld usw.), mit der das Spiel gewertet wird.
  • entrance_fee – ist die Anzahl der Einheiten, die benötigt werden, um dem Spiel beizutreten; Dies kann NULL sein, wenn das Spiel nicht erfordert, dass jeder Spieler mit einer festgelegten Anzahl von Einheiten beginnt.
  • victory_conditions – bestimmt, welcher Spieler das Spiel gewonnen hat. Wir verwenden den varchar Datentyp, um die Siegbedingung jedes Spiels zu beschreiben (d. h. das erste Team, das 100 Punkte erreicht) und es der Anwendung zu überlassen, sie zu interpretieren. Diese Flexibilität lässt Raum für viele Spiele, die hinzugefügt werden können.
  • match_result – speichert das Ergebnis der Übereinstimmung im Textformat. Wie bei victory_conditions , lassen wir die Anwendung den Wert interpretieren. Dieses Attribut kann NULL sein, da wir diesen Wert gleichzeitig mit dem Einfügen von end_time füllen Wert.

Der participant Tabelle speichert Daten über alle Teilnehmer an einem Spiel. Die match_id und player_id Attribute sind Verweise auf den match und player Tische. Zusammen bilden diese Werte den alternativen Schlüssel der Tabelle.

Bei den meisten Spielen rotiert, welcher Spieler zuerst bietet oder spielt. Normalerweise wird in der ersten Runde der Spieler, der zuerst spielt (der Eröffnungsspieler), durch Spielregeln bestimmt. In der nächsten Runde beginnt der Spieler links (oder manchmal rechts) des ursprünglichen Eröffnungsspielers. Wir verwenden die initial_player_order -Attribut zum Speichern der Ordnungszahl des Eröffnungsspielers der ersten Runde. Die match_id und die initial_player_order Attribute bilden eine weitere alternative Tonart, da zwei Spieler nicht gleichzeitig spielen können.

Die score -Attribut wird aktualisiert, wenn ein Spieler ein Match beendet. Manchmal geschieht dies für alle Spieler gleichzeitig (z. B. bei Belot oder Préférence) und manchmal während das Spiel noch läuft (z. B. Poker oder Blackjack).

Aktionen und Aktionstypen

Wenn wir an Aktionen denken, die Spieler in einem Kartenspiel ausführen können, stellen wir fest, dass wir Folgendes speichern müssen:

  • Was die Aktion war
  • Wer hat diese Aktion ausgeführt?
  • Wann (in welchem ​​Geschäft) die Aktion stattfand
  • Welche Karte(n) wurden bei dieser Aktion verwendet?

Der action_type Tabelle ist ein einfaches Wörterbuch, das die Namen der Spieleraktionen enthält. Einige mögliche Werte sind Karte ziehen, Karte spielen, Karte an einen anderen Spieler weitergeben, Prüfen und Erhöhen.

In der action Tabelle speichern wir alle Ereignisse, die während eines Deals passiert sind. Die deal_id , card_id , participant_id und action_type_id sind Verweise auf die Tabellen, die Deal-, Kartenteilnehmer- und action_type-Werte enthalten. Beachten Sie, dass die participant_id und card_id können NULL-Werte sein. Dies liegt an der Tatsache, dass einige Aktionen nicht von Spielern durchgeführt werden (z. B. der Dealer zieht eine Karte und legt sie offen ab), während andere keine Karten beinhalten (z. B. eine Erhöhung beim Poker). Wir müssen all diese Aktionen speichern, um das gesamte Spiel nachstellen zu können.

Die action_order Das Attribut speichert die Ordnungszahl einer Aktion im Spiel. Beispielsweise würde ein Eröffnungsgebot den Wert 1 erhalten; das nächste Gebot hätte einen Wert von 2 usw. Es kann nicht mehr als eine Aktion gleichzeitig stattfinden. Daher die deal_id und action_order Attribute bilden zusammen den alternativen Schlüssel.

Die action_notation Attribut enthält eine detaillierte Beschreibung einer Aktion. Beim Poker können wir zum Beispiel eine Erhöhung speichern Aktion und einen beliebigen Betrag. Einige Aktionen könnten komplizierter sein, daher ist es ratsam, diese Werte als Text zu speichern und es der Anwendung zu überlassen, sie zu interpretieren.

Geschäfte und Geschäftsreihenfolge

Ein Spiel besteht aus einer oder mehreren Kartenausgaben. Wir haben bereits den participant und die match Tabellen, aber wir haben sie in das Bild eingefügt, um ihre Beziehung zum deal und deal_order Tabellen.

Der deal Tabelle speichert alle Daten, die wir über eine einzelne Übereinstimmungsinstanz benötigen.

Die match_id Das Attribut verknüpft diese Instanz mit der entsprechenden Übereinstimmung, während start_time und end_time gibt die genaue Zeit an, zu der diese Instanz gestartet und beendet wurde.

Das move_time_limit und das deal_result Attribute sind sowohl Textfelder zum Speichern von Zeitlimits (falls zutreffend) als auch eine Beschreibung des Ergebnisses dieses Deals.

Im participant Tabelle, die initial_player_order Das Attribut speichert die Spielerreihenfolge für die Eröffnungsspielinstanz. Das Speichern der Aufträge für nachfolgende Runden erfordert eine völlig neue Tabelle – den deal_order Tabelle.

Offensichtlich deal_id und participant_id sind Verweise auf eine Übereinstimmungsinstanz und einen Teilnehmer. Zusammen bilden sie den ersten alternativen Schlüssel in deal_order Tisch. Die player_order -Attribut enthält Werte, die die Reihenfolge der Spieler angeben, die an dieser Spielinstanz teilgenommen haben. Zusammen mit deal_id , es bildet den zweiten alternativen Schlüssel in dieser Tabelle. Das deal_result -Attribut ist ein Textfeld, das das Ergebnis des Spiels für einen einzelnen Spieler beschreibt. Die score -Attribut speichert einen numerischen Wert, der sich auf das Geschäftsergebnis bezieht.

Anzüge, Ränge und Karten

Dieser Abschnitt des Modells beschreibt die Karten, die wir in allen unterstützten Spielen verwenden werden. Jede Karte hat eine Farbe und einen Rang.

Der suit_type table ist ein Wörterbuch, das alle Anzugtypen enthält, die wir verwenden werden. Für suit_type_name verwenden wir Werte wie „Französische Anzüge“, „Deutsche Anzüge“, „Schweizerdeutsche Anzüge“ und „Lateinische Anzüge“.

Der suit Die Tabelle enthält die Namen aller Farben, die in bestimmten Decktypen enthalten sind. Zum Beispiel hat das französische Deck Farben namens „Spades“, „Hearts“, „Diamonds“ und „Clubs“.

Im rank Wörterbuch finden wir bekannte Kartenwerte wie „Ass“, „König“, „Dame“ und „Bube“.

Die card Tabelle enthält eine Liste aller möglichen Karten. Jede Karte erscheint nur einmal in dieser Tabelle. Aus diesem Grund wird die suit_id und rank_id Attribute bilden den alternativen Schlüssel dieser Tabelle. Die Werte beider Attribute können NULL sein, da einige Karten keine Farbe oder keinen Rang haben (z. B. Jokerkarten). Die is_joker_card ist ein selbsterklärender boolescher Wert. Der card_name Attribut beschreibt eine Karte per Text:„Ace of Spades“.

Karten und Decks

Karten gehören zu Decks. Da eine Karte in mehreren Decks vorkommen kann, benötigen wir ein n:n Beziehung zwischen der card und deck Tabellen.

Im deck Tabelle speichern wir die Namen aller Kartendecks, die wir verwenden möchten. Ein Beispiel für Werte, die in deck_name gespeichert sind Attribute sind:„Standard-Deck mit 52 Karten (Französisch)“ oder „Deck mit 32 Karten (Deutsch)“.

Der card_in_deck Die Beziehung wird verwendet, um Karten geeigneten Decks zuzuweisen. Die card_iddeck_id Paar ist der alternative Schlüssel des deck Tisch.

Match-Eigenschaften, Decks und verwendete Einheiten

Dieser Abschnitt des Modells enthält einige grundlegende Parameter zum Starten eines neuen Spiels.

Der Hauptteil dieses Abschnitts ist das game Tisch. In dieser Tabelle werden Daten zu anwendungsunterstützten Spielen gespeichert. Der game_name Attribut enthält Werte wie „Poker“, „Blackjack“, „Belot“ und „Préférence“.

Die min_number_of_players und max_number_of_players sind die minimale und maximale Anzahl von Teilnehmern an einem Spiel. Diese Attribute dienen als Grenzen für das Spiel und werden zu Beginn eines Spiels auf dem Bildschirm angezeigt. Die Person, die den Abgleich initiiert, muss einen Wert aus diesem Bereich auswählen.

Die min_entrance_fee und die max_entrance_fee Attribute bezeichnet den Eintrittspreisbereich. Auch dies basiert auf dem gespielten Spiel.

In possible_victory_condition speichern wir alle Siegbedingungen, die einem Match zugeordnet werden konnten. Werte werden durch ein Trennzeichen getrennt.

Die unit Wörterbuch wird verwendet, um jede Einheit zu speichern, die in all unseren Spielen verwendet wird. Der unit_name Attribut enthält Werte wie „Punkt“, „Dollar“, „Euro“ und „Chip“.

Das game_deck und game_unit Tabellen verwenden die gleiche Logik. Sie enthalten Listen aller Decks und Einheiten, die in einem Match verwendet werden können. Daher ist die game_iddeck_id Paar und die game_idunit_id Paare bilden alternative Schlüssel in ihren jeweiligen Tabellen.

Ergebnisse

In unserer Anwendung möchten wir die Ergebnisse aller Spieler speichern, die an unseren Kartenspielen teilgenommen haben. Für jedes Spiel wird ein einzelner numerischer Wert berechnet und gespeichert. (Die Berechnung basiert auf den Ergebnissen des Spielers in allen Spielen eines einzigen Typs.) Diese Spielerpunktzahl ähnelt einem Rang; es lässt Benutzer ungefähr wissen, wie gut ein Spieler ist.

Zurück zum Berechnungsprozess. Wir erstellen ein n:n Beziehung zwischen dem player und game Tische. Das ist der player_score Tabelle in unserem Modell. Die player_id und die score_id “ bilden zusammen den alternativen Schlüssel der Tabelle. Die „score -Attribut wird verwendet, um den zuvor erwähnten numerischen Wert zu speichern.

Es gibt eine Vielzahl von Kartenspielen, die sehr unterschiedliche Regeln, Karten und Decks verwenden. Um eine Datenbank zu erstellen, die Daten für mehr als ein Kartenspiel speichert, müssen wir einige Verallgemeinerungen vornehmen. Eine Möglichkeit, dies zu tun, besteht darin, beschreibende Textfelder zu verwenden und sie von der Anwendung interpretieren zu lassen. Wir könnten Wege finden, die häufigsten Situationen abzudecken, aber das würde das Datenbankdesign exponentiell verkomplizieren.

Wie dieser Artikel gezeigt hat, können Sie eine Datenbank für viele Spiele verwenden. Wieso würdest du das machen? Drei Gründe:1) Sie können dieselbe Datenbank wiederverwenden; 2) es würde die Analytik vereinfachen; und dies würde zu 3) dem Aufbau besserer KI-Gegner führen.