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

Cosa hanno a che fare Poker, Blackjack, Belot e Préférence con i database?

Come progettare un database sufficientemente flessibile da ospitare diversi giochi di carte molto diversi.

Di recente, abbiamo mostrato come utilizzare un database per archiviare i risultati dei giochi da tavolo. I giochi da tavolo sono divertenti, ma non sono l'unica versione online dei giochi classici in circolazione. Anche i giochi di carte sono molto popolari. Introducono un elemento di fortuna nel gameplay e in un buon gioco di carte c'è molto di più della semplice fortuna!

In questo articolo, ci concentreremo sulla creazione di un modello di dati per memorizzare partite, risultati, giocatori e punteggi. La sfida principale qui è la memorizzazione dei dati relativi a molti giochi di carte diversi. Potremmo anche considerare l'analisi di questi dati per determinare le strategie vincenti, migliorare le nostre capacità di gioco o costruire un avversario AI migliore.

I giochi a quattro carte che useremo nel nostro database

Poiché i giocatori non possono controllare la mano che ricevono, i giochi di carte combinano strategia, abilità e fortuna. Quel fattore fortuna dà a un principiante la possibilità di battere un giocatore esperto e rende i giochi di carte avvincenti. (Questo è diverso da giochi come gli scacchi, che si basano molto su logica e strategia. Ho sentito da molti giocatori che non sono interessati a giocare a scacchi perché non riescono a trovare avversari al loro livello di abilità.)

Ci concentreremo su quattro famosi giochi di carte:poker, blackjack, belot (o belote) e préférence. Ognuno di loro ha regole relativamente complesse e richiede del tempo per padroneggiarlo. Anche il rapporto tra fortuna e conoscenza è diverso per ogni gioco.

Daremo una rapida occhiata alle regole semplificate e alle specifiche per tutti e quattro i giochi di seguito. Le descrizioni dei giochi sono piuttosto scarse, ma abbiamo incluso abbastanza per mostrare le diverse modalità di gioco e le diverse regole che incontreremo durante il processo di progettazione del database.

Blackjack:

  • Mazzo: Da uno a otto mazzi da 52 carte ciascuno; niente carte jolly
  • Giocatori: Dealer e 1 o più avversari
  • Unità utilizzata: Di solito denaro
  • Regole di base: I giocatori ottengono 2 carte che solo loro possono vedere; il dealer riceve due carte, una scoperta e l'altra coperta; ogni giocatore decide di pescare più carte (o meno); il dealer pesca per ultimo. Alle carte sono assegnati valori in punti compresi tra 1 e 11.
  • Possibili azioni del giocatore: Colpisci, stai in piedi, dividi, arrenditi
  • Goal e condizioni di vittoria: La somma delle carte di un giocatore è maggiore di quella del dealer; se un giocatore supera 21, quel giocatore perde.

Poker (Texas Hold'Em):

  • Mazzo: Standard (noto anche come seme francese) mazzo da 52 carte; niente carte jolly. Le carte sono spesso di colore rosso e nero.
  • Giocatori: Da due a nove; i giocatori distribuiscono a turno
  • Unità utilizzata:solitamente chip
  • Regole di base: Ogni giocatore inizia ricevendo due carte; i giocatori piazzano le loro scommesse; tre carte vengono distribuite scoperte al centro del tavolo; i giocatori piazzano nuovamente le loro scommesse; una quarta carta viene posta al centro ei giocatori scommettono nuovamente; quindi viene piazzata la quinta e ultima carta e l'ultimo giro di scommesse è completato.
  • Possibili azioni del giocatore: Passa, chiama, rilancia, Small Blind, Big Blind, Reraise
  • Obiettivo: Combina la migliore mano possibile di cinque carte (dalle due carte nella mano del giocatore e dalle cinque carte al centro del tavolo)
  • Condizione di vittoria:di solito per vincere tutte le fiches sul tavolo

Belot (variante croata di Belote):

  • Mazzo: Di solito il tradizionale mazzo da 32 carte tedesco o ungherese; niente carte jolly
  • Giocatori: Da due a quattro; di solito quattro giocatori in coppia di due
  • Unità utilizzata: Punti
  • Regole di base: Per una partita a quattro giocatori, ogni giocatore riceve sei carte in mano e due carte coperte; i giocatori prima fanno un'offerta per il seme di briscola; dopo aver determinato la briscola, prendono le due carte coperte e le mettono in mano; segue un round di dichiarazione, durante il quale vengono annunciate alcune combinazioni di carte per punti aggiuntivi; il gioco continua finché tutte le carte non sono state utilizzate.
  • Possibili azioni del giocatore: Passare, Bid Suit, Dichiarazione, Throw Card
  • Gol per la mano: Per vincere più della metà dei punti
  • Condizione di vittoria: Sii la prima squadra a segnare 1001 punti o più

Preferenza:

  • Mazzo: Molto spesso un mazzo da 32 carte tradizionale tedesco o ungherese; niente carte jolly
  • Giocatori: Tre
  • Unità: Punti
  • Regole di base: A tutti i giocatori vengono distribuite 10 carte; due carte “gattino” o “artiglio” sono poste al centro del tavolo; i giocatori determinano se vogliono fare un'offerta su un seme; i giocatori decidono di giocare o meno.
  • Possibili azioni del giocatore: Passa, dichiara il seme, gioca, non giocare, lancia la carta
  • Obiettivo: Dipende dalla variante di Préférence in riproduzione; nella versione standard, l'offerente deve vincere un totale di sei prese.
  • Condizione di vittoria: Quando la somma dei punteggi di tutti e tre i giocatori è 0, vince il giocatore con il minor numero di punti.

Perché combinare database e giochi di carte?

Il nostro obiettivo qui è progettare un modello di database in grado di memorizzare tutti i dati rilevanti per questi quattro giochi di carte. Il database potrebbe essere utilizzato da un'applicazione Web come luogo in cui archiviare tutti i dati rilevanti. Vogliamo memorizzare le impostazioni di gioco iniziali, i partecipanti al gioco, le azioni intraprese durante il gioco e il risultato di una singola mano, mano o presa. Dobbiamo anche tenere presente il fatto che a una partita possono essere associati uno o più accordi.

Da ciò che memorizziamo nel nostro database, dovremmo essere in grado di ricreare tutte le azioni che hanno avuto luogo durante il gioco. Useremo i campi di testo per descrivere le condizioni di vittoria, le azioni di gioco e i loro risultati. Questi sono specifici per ogni gioco e la logica dell'applicazione web interpreterà il testo e lo trasformerà secondo necessità.

Una rapida introduzione al modello




Questo modello ci consente di archiviare tutti i dati di gioco rilevanti, inclusi:

  • Proprietà del gioco
  • Elenco di partite e partite
  • Partecipanti
  • Azioni di gioco

Poiché i giochi differiscono in molti modi, useremo spesso varchar(256) tipo di dati per descrivere proprietà, mosse e risultati.

Giocatori, partite e partecipanti

Questa sezione del modello è composta da tre tabelle e viene utilizzata per memorizzare i dati sui giocatori registrati, le partite giocate e i giocatori che hanno partecipato.

Il player la tabella memorizza i dati sui giocatori registrati. Il username e email gli attributi sono valori univoci. Il nick_name l'attributo memorizza i nomi delle schermate dei giocatori.

La match la tabella contiene tutti i dati di corrispondenza rilevanti. Generalmente, una partita è composta da una o più carte distribuite (note anche come round, mani o prese). Tutte le partite hanno regole stabilite prima dell'inizio del gioco. Gli attributi sono i seguenti:

  • game_id – fa riferimento alla tabella contenente l'elenco dei giochi (poker, blackjack, belot e préférence, in questo caso).
  • start_time e end_time sono i tempi effettivi in ​​cui una partita inizia e finisce. Nota che il end_time può essere NULL; non avremo il suo valore fino alla fine del gioco. Inoltre, se una corrispondenza viene abbandonata prima che sia terminata, il end_time il valore può rimanere NULL.
  • number_of_players – è il numero di partecipanti necessario per iniziare il gioco
  • deck_id – fa riferimento al mazzo utilizzato nel gioco.
  • decks_used – è il numero di mazzi utilizzati per giocare. Di solito questo valore sarà 1, ma alcuni giochi utilizzano più mazzi.
  • unit_id – è l'unità (punti, fiches, denaro, ecc.) utilizzata per segnare il gioco.
  • entrance_fee – è il numero di unità necessarie per partecipare al gioco; questo può essere NULL se il gioco non richiede che ogni giocatore inizi con un determinato numero di unità.
  • victory_conditions – determina quale giocatore ha vinto la partita. Useremo il varchar tipo di dati per descrivere la condizione di vittoria di ogni partita (cioè prima squadra a raggiungere 100 punti) e lasciare che l'applicazione lo interpreti. Questa flessibilità lascia spazio per aggiungere molti giochi.
  • match_result – memorizza il risultato della partita in formato testo. Come con victory_conditions , lasceremo che l'applicazione interpreti il ​​valore. Questo attributo può essere NULL perché riempiremo quel valore nello stesso momento in cui inseriamo il end_time valore.

Il participant la tabella memorizza i dati su tutti i partecipanti a una partita. Il match_id e player_id gli attributi sono riferimenti alla match e player tavoli. Insieme, questi valori formano la chiave alternativa della tabella.

La maggior parte dei giochi ruota quale giocatore fa un'offerta o gioca per primo. Di solito nel primo round, il giocatore che gioca per primo (il primo giocatore) è determinato dalle regole del gioco. Nel round successivo, il giocatore a sinistra (o talvolta a destra) del giocatore iniziale originale andrà per primo. Useremo il initial_player_order attributo per memorizzare il numero ordinale del giocatore di apertura del primo round. Il match_id e il initial_player_order gli attributi formano un'altra chiave alternativa perché due giocatori non possono giocare contemporaneamente.

Il score l'attributo viene aggiornato quando un giocatore finisce una partita. A volte questo avverrà nello stesso momento per tutti i giocatori (ad es. in belot o préférence) ea volte mentre la partita è ancora in corso (ad es. poker o blackjack).

Azioni e tipi di azioni

Quando pensiamo alle azioni che i giocatori possono compiere in un gioco di carte, ci rendiamo conto che dobbiamo memorizzare:

  • Qual ​​è stata l'azione
  • Chi ha eseguito quell'azione
  • Quando (in quale accordo) è avvenuta l'azione
  • Quale/e carta/e sono state utilizzate in quell'azione

Il action_type table è un semplice dizionario che contiene i nomi delle azioni del giocatore. Alcuni valori possibili includono pescare carte, giocare carte, passare carte a un altro giocatore, fare check e rilanciare.

Nell'action tabella, memorizzeremo tutti gli eventi accaduti durante un affare. Il deal_id , card_id , participant_id e action_type_id sono riferimenti alle tabelle che contengono i valori di mano, partecipante carta e tipo_azione. Nota che il participant_id e card_id possono essere valori NULL. Ciò è dovuto al fatto che alcune azioni non sono fatte dai giocatori (es. il dealer pesca una carta e la mette a faccia in su), mentre alcune non includono le carte (es. un rilancio nel poker). Dobbiamo memorizzare tutte queste azioni per poter ricreare l'intera partita.

Il action_order attributo memorizza il numero ordinale di un'azione in-game. Ad esempio, un'offerta di apertura riceverà un valore 1; l'offerta successiva avrebbe un valore 2, ecc. Non possono verificarsi più di un'azione contemporaneamente. Pertanto, il deal_id e action_order gli attributi insieme formano la chiave alternativa.

La action_notation l'attributo contiene una descrizione dettagliata di un'azione. Nel poker, ad esempio, possiamo memorizzare un rilancio azione e un importo arbitrario. Alcune azioni potrebbero essere più complicate, quindi è consigliabile memorizzare questi valori come testo e lasciare che l'applicazione lo interpreti.

Offerte e ordini di offerte

Una partita è composta da una o più carte distribuite. Abbiamo già discusso del participant e il match tabelle, ma le abbiamo incluse nell'immagine per mostrare la loro relazione con il deal e deal_order tabelle.

Il deal la tabella memorizza tutti i dati di cui abbiamo bisogno su una singola istanza di corrispondenza.

Il match_id l'attributo mette in relazione quell'istanza con la corrispondenza appropriata, mentre start_time e end_time denota l'ora esatta in cui l'istanza è iniziata e quando è stata completata.

Il move_time_limit e il deal_result gli attributi sono entrambi campi di testo utilizzati per memorizzare i limiti di tempo (se applicabile) e una descrizione del risultato di quell'affare.

Nel participant tabella, il initial_player_order l'attributo memorizza l'ordine del giocatore per l'istanza della partita di apertura. La memorizzazione degli ordini per i turni successivi richiede una tabella completamente nuova:il deal_order tabella.

Ovviamente, deal_id e participant_id sono riferimenti a un'istanza di corrispondenza e a un partecipante. Insieme, formano la prima chiave alternativa nel deal_order tavolo. Il player_order l'attributo contiene valori che denotano gli ordini che i giocatori hanno partecipato a quell'istanza della partita. Insieme a deal_id , costituisce la seconda chiave alternativa in questa tabella. Il deal_result attributo è un campo di testo che descrive il risultato della partita per un singolo giocatore. Il score memorizza un valore numerico relativo al risultato dell'offerta.

Semi, gradi e carte

Questa sezione del modello descrive le carte che utilizzeremo in tutti i giochi supportati. Ogni carta ha un seme e un valore.

Il suit_type table è un dizionario che contiene tutti i tipi di seme che useremo. Per suit_type_name , utilizzeremo valori come "semi francesi", "semi tedeschi", "semi svizzero-tedeschi" e "semi latini".

Il suit la tabella contiene i nomi di tutti i semi contenuti in specifici tipi di mazzo. Ad esempio, il mazzo francese ha semi chiamati "Spades", "Hearts", "Diamonds" e "Clubs".

Nella rank dizionario, troveremo carte con valori noti come "Asso", "Re", "Regina" e "Fante".

La card la tabella contiene un elenco di tutte le carte possibili. Ogni carta apparirà in questa tabella solo una volta. Questo è il motivo per cui suit_id e rank_id gli attributi formano la chiave alternativa di questa tabella. I valori di entrambi gli attributi possono essere NULL perché alcune carte non hanno un seme o un valore (es. carte jolly). La is_joker_card è un valore booleano autoesplicativo. Il card_name attributo descrive una carta per testo:"Asso di picche".

Carte e mazzi

Le carte appartengono ai mazzi. Poiché una carta può apparire in più mazzi, avremo bisogno di un n:n relazione tra la card e deck tabelle.

Nel deck tabella, memorizzeremo i nomi di tutti i mazzi di carte che vogliamo utilizzare. Un esempio di valori memorizzati nel deck_name gli attributi sono:"Mazzo standard da 52 carte (francese)" o "Mazzo da 32 carte (tedesco)".

Il card_in_deck la relazione viene utilizzata per assegnare le carte ai mazzi appropriati. Il card_iddeck_id pair è la chiave alternativa del deck tavolo.

Proprietà della partita, mazzi e unità utilizzate

Questa sezione del modello contiene alcuni parametri di base per iniziare una nuova partita.

La parte principale di questa sezione è il game tavolo. Questa tabella memorizza i dati sui giochi supportati dall'applicazione. Il game_name contiene valori come "poker", "blackjack", "belot" e "préférence".

Il min_number_of_players e max_number_of_players sono il numero minimo e massimo di partecipanti a una partita. Questi attributi fungono da limiti per il gioco e vengono mostrati sullo schermo all'inizio di una partita. La persona che avvia la corrispondenza deve selezionare un valore da questo intervallo.

La min_entrance_fee e il max_entrance_fee attributi denota l'intervallo del biglietto d'ingresso. Ancora una volta, questo si basa sul gioco in corso.

In possible_victory_condition , memorizzeremo tutte le condizioni di vittoria che potrebbero essere assegnate a una partita. I valori sono separati da un delimitatore.

L'unit il dizionario viene utilizzato per memorizzare ogni unità utilizzata in tutti i nostri giochi. Il unit_name l'attributo conterrà valori come "punto", "dollaro", "euro" e "chip".

Il game_deck e game_unit le tabelle usano la stessa logica. Contengono elenchi di tutti i mazzi e le unità che possono essere utilizzati in una partita. Pertanto, il game_iddeck_id coppia e il game_idunit_id coppia forma chiavi alternative nelle rispettive tabelle.

Punteggi

Nella nostra applicazione, vorremo memorizzare i punteggi di tutti i giocatori che hanno partecipato ai nostri giochi di carte. Per ogni partita viene calcolato e memorizzato un unico valore numerico. (Il calcolo si basa sui risultati del giocatore in tutte le partite di un singolo tipo.) Il punteggio di questo giocatore è simile a un grado; consente agli utenti di sapere all'incirca quanto è bravo un giocatore.

Torna al processo di calcolo. Creeremo un n:n relazione tra il player e game tavoli. Questo è il player_score tavolo nel nostro modello. Il player_id e il score_id ” insieme formano la chiave alternativa della tabella. Il "score viene utilizzato per memorizzare il valore numerico menzionato in precedenza.

Ci sono una varietà di giochi di carte che usano regole, carte e mazzi molto diversi. Per creare un database che memorizzi i dati per più di un gioco di carte, dobbiamo fare alcune generalizzazioni. Un modo per farlo è utilizzare campi di testo descrittivi e lasciare che l'applicazione li interpreti. Potremmo trovare modi per coprire le situazioni più comuni, ma ciò complicherebbe esponenzialmente la progettazione del database.

Come mostrato in questo articolo, puoi utilizzare un database per molti giochi. Perché dovresti farlo? Tre motivi:1) puoi riutilizzare lo stesso database; 2) semplificherebbe l'analisi; e questo porterebbe a 3) la costruzione di avversari IA migliori.