Wenn Sie ein Star Trek-Fan sind, wissen Sie wahrscheinlich, dass Captain Kirk und Mr. Spock häufig eine Schachvariante namens Tri-Dimensional Chess oder 3D-Schach spielen, ein Spiel, das dem Standardschach ähnelt, aber bemerkenswerte Unterschiede aufweist. In diesem Artikel erstellen wir ein Datenmodell für eine 3D-Schachanwendung, mit der Spieler gegeneinander antreten können. Beamen Sie uns hoch, Scotty!
Das Konzept von 3D-Schach
Während Schach selbst bereits ein komplexes Spiel ist, kann das Kombinieren von Brettern und mehreren Figurensätzen die Komplexität des Spiels erheblich erhöhen.
Beim 3D-Schach werden Bretter in parallelen Schichten gestapelt, und für bestimmte Figuren gelten spezielle Bewegungsregeln, je nachdem, wo sie sich befinden. Beispielsweise können Bauern auf dem mittleren Brett das Verhalten einer Dame nachahmen. Teile können auch von einem Brett zum anderen bewegt werden, wobei bestimmte Einschränkungen gelten, und die Bretter selbst können sich sogar bewegen und drehen. Kein Wunder, dass Kirk und Spock 3D-Schach so sehr mochten – es erfordert ziemlich viel taktisches Geschick!
Tridimensionales Schach weicht auch in den Eigenschaften seiner Bretter vom Standardschach ab. Beim 3D-Schach gibt es sieben verschiedene Bretter mit unterschiedlichen Eigenschaften. Drei dieser Bretter sind 4x4, während die restlichen vier Bretter 2x2 sind. Sie können diese kleineren Bretter verschieben.
Unser Datenmodell wird hoffentlich alles abdecken, was wir brauchen, um eine Partie 3D-Schach in einer Web-App zu spielen. Wir gehen davon aus, dass sich alles bewegen kann und dass Bretter denselben Figuren unterschiedliche Bewegungsbeschränkungen auferlegen können. Dies sollte ausreichen, um alle möglichen 3D-Schachvarianten abzudecken. Lassen Sie uns direkt in das Datenmodell springen!
Das Datenmodell
Unser Datenmodell besteht aus drei Abschnitten:
- Spieler und Spiele
- Spiel-Setup
- Übereinstimmungen
Wir werden nun jeden dieser Bereiche ausführlicher besprechen.
Abschnitt 1:Spieler und Spiele
Alles in unserem Modell hat entweder direkt oder indirekt mit Spielen zu tun. Natürlich geht ein Spiel nicht ohne Spieler!
Die Liste aller Spieler wird im player
Tisch. In unserem Modell sind Spieler alle registrierten Benutzer unserer Anwendung. Für jeden Spieler speichern wir die folgenden Informationen:
first_name
undlast_name
– den Vor- und Nachnamen des Spielers.user_name
– der vom Spieler ausgewählte Benutzername, der eindeutig sein muss.password
– ein Hashwert des Spielerpassworts.nickname
– der Bildschirmname des Spielers, der wie sein Benutzername eindeutig sein muss.email
– die E-Mail-Adresse des Spielers, die er während des Registrierungsprozesses bereitstellt. Der zum Abschließen des Registrierungsvorgangs erforderliche Code wird an diese E-Mail gesendet.confirmation_code
– der Code, der an die E-Mail-Adresse des Spielers gesendet wurde, um seinen Registrierungsprozess abzuschließen.confirmation_date
– der Zeitstempel, wann der Spieler seine E-Mail-Adresse bestätigt hat. Dieses Attribut speichert NULL, bis der Spieler seine E-Mail bestätigt.current_rating
– die aktuelle Bewertung des Spielers, berechnet auf der Grundlage seiner Leistung gegen andere Spieler. Die Spieler beginnen mit einem gewissen Anfangswert, und ihre Wertungen werden je nach Rängen ihrer Gegner und deren Spielergebnissen steigen oder fallen.
Das result
table ist ein Wörterbuch, das die Werte aller möglichen eindeutigen Spielergebnisse speichert, nämlich „in_progress“, „draw“, „win“ und „lose“.
Die vielleicht wichtigste Tabelle im gesamten Datenmodell ist game
, das Informationen zu jedem 3D-Schachspiel speichert. In diesem Modell gehen wir davon aus, dass zwei menschliche Spieler gegeneinander antreten und dass sie ihren aktuellen Spielstatus speichern und zu einem späteren Zeitpunkt fortsetzen können (z. B. wenn sie einen Zug pro Tag machen möchten, in In diesem Fall melden sich die Spieler bei der App an, sehen den letzten Zug ihres Gegners, denken an ihren eigenen Zug, führen ihren Zug aus und melden sich dann ab). Wir speichern die folgenden Werte in dieser Tabelle:
player_id_1
undplayer_id_2
– Verweise auf denplayer
Tabelle, die beide Teilnehmer eines Spiels bezeichnet. Wie bereits erwähnt, gehen wir davon aus, dass ein Spiel ausschließlich zwischen zwei menschlichen Spielern stattfindet.number_of_moves
– gibt die Anzahl der Züge an, die bisher im aktuellen Spiel ausgeführt wurden. Wenn das Spiel beginnt, wird diese Zahl auf 0 gesetzt und erhöht sich jedes Mal um 1, wenn ein Spieler einen Zug macht.player_id_next
– ein Hinweis auf den Spieler, der im aktuellen Spiel den nächsten Zug machen muss.result_id_1
undresult_id_2
– Verweise auf dasresult
Tabelle, die das Ergebnis des Spiels für jeden Spieler speichert.player_1_points_won
undplayer_2_points_won
– geben die Anzahl der Punkte an, die die Spieler entsprechend dem Ergebnis des Spiels erhalten haben.
Wir werden im Abschnitt „Matches“ gegen Ende dieses Artikels besprechen, wie Spieler alle Züge im Auge behalten können. Fürs Erste fahren wir mit der Spieleinrichtung fort.
Abschnitt 2:Spielaufbau
Der Abschnitt Spielaufbau enthält eine Beschreibung aller Bretter und Figuren im 3D-Schach sowie eine Liste aller legalen Züge, die Spieler ausführen können.
Wie bereits erwähnt, umfasst 3D-Schach oft mehr als ein Brett. Diese Platten können die Standardabmessungen von 8 x 8 mit festen Positionen einhalten, aber das muss nicht der Fall sein. Die Liste aller Boards wird im board
Tisch. Für jedes Board speichern wir einen eindeutigen board_name
, die starting_position
des Boards in Bezug auf unsere gewählten 3D-Koordinaten und alle zusätzlichen details
.
Als Nächstes definieren wir alle möglichen Arten von Figuren, die auf unseren Schachbrettern erscheinen könnten. Dazu verwenden wir den piece_type
Wörterbuch. Zusätzlich zu seinem Primärschlüssel enthält dieses Wörterbuch nur einen eindeutigen Wert, type_name. Für ein Standard-Schachspiel erwarten wir in diesem Wörterbuch die Werte „Bauer“, „Turm“, „Springer“, „Läufer“, „König“ und „Dame“.
Die Liste aller einzelnen Figuren, die in einer 3D-Schachpartie verwendet werden, ist im piece
Tisch. Für jedes Stück speichern wir die folgenden Informationen:
piece_name
– ein eindeutiger Name, der den Stücktyp und seine Startposition beschreibt.starting_position
– ein Wert, der das genaue Brett und Feld angibt, auf dem die Figur ursprünglich positioniert ist.board_id
– ein Verweis auf das Brett, auf dem die Figur ursprünglich positioniert ist.piece_type_id
– eine Referenz, die den Typ des Stücks angibt.
Schließlich verwenden wir den move_type
Tabelle, um die Liste aller möglichen Züge zu speichern, die die Figuren auf unseren Brettern machen können (sowie alle Züge, die die Bretter selbst machen können). Erinnern Sie sich an die Einleitung, dass bestimmte Bretter spezielle Bewegungsregeln für ihre Figuren anwenden. Für jeden Zug definieren wir Folgendes:
type_name
– ein Name, den wir verwenden, um den ausgeführten Zug zu bezeichnen, der kein eindeutiger Wert ist (z. B. können wir so oft wie nötig „Bauern um 1 Feld vorrücken“ haben).piece_type_id
– ein Hinweis auf die Art der bewegten Figur. Wenn dieser Wert zufällig NULL ist, betrifft die Bewegung ein ganzes Brett und keine bestimmte Figur.board_id
– bezeichnet das Brett, auf dem dieser Zug stattfinden wird (wenn sich eine Schachfigur bewegt). Wenn sich das Brett selbst bewegt, stellt dieser Wert natürlich das Brett dar, das bewegt wird. Zusammen mit zwei vorangegangenen Attributen bildet dies den eindeutigen Schlüssel für diese Tabelle.is_piece_move
undis_board_move
– angeben, ob ein Zug eine Schachfigur oder ein Brett betrifft. Nur eines dieser Flags darf für einen bestimmten Zug auf wahr gesetzt werden.
Da es zu viele Figurenbewegungen und Rotationen zu berücksichtigen gibt, werden wir nicht alle diese Möglichkeiten in unserer Datenbank speichern. Stattdessen speichern wir einfach die Zugnamen und implementieren die eigentliche Logik in der Anwendung selbst. Zum Beispiel definieren wir, dass Bauern entweder ein einzelnes Feld vorrücken, zwei Felder von ihrer Startposition aus vorrücken, Figuren diagonal beanspruchen, von einem Brett zum anderen ziehen und als Dame auf dem zentralen Brett ziehen können. Wir haben also fünf mögliche Zugtypen für Bauern definiert, abhängig von dem Brett, auf dem sie platziert sind, und ihrer aktuellen Position.
Abschnitt 3:Spiele
Wir sind fast fertig! Der letzte Abschnitt unseres Modells heißt Matches und enthält drei neue Tabellen, die wir verwenden, um den Bewegungsverlauf in einem 3D-Schachspiel zu verfolgen. Die verbleibenden Tabellen sind nur Kopien anderer Tabellen aus unserem Datenmodell, wodurch sich überschneidende Beziehungen vermieden werden. In diesem Bereich speichern wir auch die aktuellen Positionen aller Bretter und ihrer Teile. Lassen Sie uns gleich eintauchen.
Der move
Tabelle ist eigentlich die komplexeste Tabelle in diesem Abschnitt. Es enthält die Liste aller während eines Spiels ausgeführten Züge. Diese Tabelle zeigt den Spielern die Liste aller Züge an, die später zur Überprüfung oder Analyse des Spiels verwendet werden können. Für jeden Zug speichern wir Folgendes:
game_id
– ein Verweis auf dasgame
in dem der Umzug durchgeführt wurde.player_id
– ein Verweis auf denplayer
der den Zug gemacht hat.move_in_the_game
– die Ordnungszahl des Zuges. Diese Zahl, kombiniert mit der Startposition einer Figur und allen anderen Zügen, kann verwendet werden, um das gesamte Spiel nachzubilden. Die Idee ist, dass Spieler das Spiel nach Abschluss simulieren können, damit sie die Ergebnisse des Spiels analysieren können.piece_id
– ein Verweis auf daspiece
das wurde verschoben. Dies macht es einfach, die Bewegung eines Stücks von Anfang bis Ende zu verfolgen (hauptsächlich zu Analysezwecken).piece_type_id
– ein Hinweis auf die Art der bewegten Figur. Während die Referenz einer Figur immer konstant bleibt, kann sich ihr Typ während des Spiels ändern (z. B. wenn ein Bauer umgewandelt wird). Wenn wir das Board verschieben, enthält dieses Attribut den Wert NULL.board_id
– ein Verweis auf dasboard
an dem der Umzug stattgefunden hat.move_notation
– eine vereinbarte Notation, die wir verwenden, um Züge darzustellen.
Die verbleibenden zwei Tabellen ermöglichen es uns, eine Momentaufnahme des aktuellen Spielstatus in der Datenbank zu speichern, was hilfreich ist, wenn die Spieler das Spiel zu einem späteren Zeitpunkt fortsetzen möchten.
Die current_board_position
wird verwendet, um die Position aller Bretter in unserem 3D-Koordinatensystem zu speichern. Dies ist für 3D-Schachspiele notwendig, bei denen mindestens ein Brett seine Position ändern kann. Für jeden Datensatz in dieser Tabelle speichern wir einen Verweis auf das zugehörige Spiel und Brett sowie die Notation der Position eines Bretts. Zwei spezifische Attributpaare, game_id
+ board_id
und game_id
+ position_notation
, bilden die eindeutigen Schlüssel für diese Tabelle.
Unsere letzte Tabelle ist current_piece_position
, das Verweise auf das zugehörige Spiel, eine bestimmte Figur, den Typ der Figur und eine Positionsnotation für die Figur speichert. Wir haben wieder zwei Attributpaare, die als eindeutige Schlüssel für diese Tabelle dienen:die game_id
und piece_id
Paar und die game_id
und position_notation
Paar.
Schlussfolgerung
Das war es mit diesem Datenmodell – wir sind stolz darauf, ankündigen zu können, dass Captain Kirk und Mr. Spock jetzt 3D-Schach auf einem Computer spielen können!
Haben Sie Vorschläge zur Verbesserung unseres Datenmodells? Fühlen Sie sich frei, Ihre Kommentare unten zu hinterlassen. Lebe lang und erfolgreich ??