Stellen Sie das Kartendeck in C++ Array dar
Dieses Tutorial zeigt eine Darstellung eines Kartenspiels durch C++-Arrays.
Zuerst werden wir Kartendeck-Vorbereitungen diskutieren, gefolgt von möglichen Wegen der Kartendarstellung in C++. Abschließend stellen wir ein praktisches Beispiel für die Darstellung des Kartenspiels vor.
Das Kartenspiel
Ein Standard-Kartenspiel hat vier Suiten oder Typen: Herz, Kreuz, Pik und Karo. Jede Suite hat dreizehn Karten: Ass, 2, 3, 4, 5, 6, 7, 8, 9, 10, Bube, Dame und König; Somit hat das gesamte Deck insgesamt 52 Karten.
Karten haben viele Spiele; wir gehen hierauf jedoch nicht näher ein. In verschiedenen Spielen haben der Bube, die Dame und der König jeweils den Wert von 10, 11 und 12.
In einigen Spielen kann das Ass als 13 oder 1 oder sogar beides betrachtet werden.
Individuelle Kartendarstellung in C++
Wir müssen die Kartentyp-/Suite-Informationen und die Kartennummer/den Kartenwert für jede Karte speichern. Der Kartenwert ist einfach eine Zahl, die in einer ganzzahligen Variablen gespeichert werden kann, während der Kartentyp als Typ-0, Typ-1, Typ-2 und Typ-3 codiert werden kann.
Wir können 0 für Typ-0 speichern (sagen wir, es ist ein Typ für die Herzen). In ähnlicher Weise können wir 1 für Typ-1 für vielleicht Kreuz und so weiter für Pik und Karo speichern.
Schauen wir uns den folgenden Code zur Umsetzung dieses Konzepts an:
// Representation of jack of hearts
int type = 0;
int value = 11;
// Representation of king of club
int type = 1;
int value = 13;
// Representation of three of spade
int type = 2;
int value = 3;
Diese Darstellung kann dazu dienen, beliebige Kartenspiele zu übergeben. Zum Beispiel können wir jetzt die Variable Wert
vergleichen, um zu prüfen, welcher Spieler die höherwertige Karte hat.
Wenn wir überprüfen möchten, welchen Kartentyp der unterberücksichtigte Spieler hat, können wir die Variable Typ
überprüfen.
Kartendeck-Array-Darstellungen in C++
Wir haben die Darstellung für eine einzelne Karte besprochen. Schauen wir uns verschiedene C++-Darstellungen für ein Kartenspiel an.
Darstellung durch parallele Arrays in C++
Um das Kartenspiel darzustellen, können wir zwei parallele Arrays nehmen. Ein Array zum Speichern des Kartentyps und das andere Array zum Speichern des Werts an der entsprechenden Position.
Hier ist die Array-Deklaration und -Initialisierung für diese parallelen Arrays:
int type[52] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
int value[52] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
In diesem Code repräsentieren type[i]
und value[i]
die i-te Karte des Decks.
Darstellung durch Einsatz von Modulus- und Integer-Division in C++
Es gibt noch eine andere intelligente Art der Darstellung, die noch besser ist als dieses Schema. Wir können 0 bis 51 in einem Integer-Array speichern.
Wir können eine ganzzahlige Division und eine Restoperation verwenden, um den Kartentyp und -wert zu erhalten.
Wir weisen den ersten 13 Indizes 0 bis 12 zu. Der arithmetische Divisionsoperator in C++ führt standardmäßig eine ganzzahlige Division durch; Wenn wir also Zahlen von 0 bis 12 durch 13 dividieren, erhalten wir 0 als Kartentyp (d. h. in unserem Fall eine Herzfarbe).
Wenn wir außerdem den Rest einer beliebigen Zahl mit 13 nehmen, erhalten wir 0 bis 12. Dieser Restwert kann als tatsächlicher Wert der Karte dienen.
Daher werden wir den nächsten 13 Indizes 13 bis 25 zuweisen und so weiter für die verbleibenden Karten.
Wenn wir diese Karten wiederum ganzzahlig durch 13 dividieren, erhalten wir einen Wert von 1 (d. h. in unserem Fall einen Kartentyp für die Kreuze). Wenn wir den Rest mit 13 nehmen, erhalten wir wieder 0 bis 12, was den Kartenwert darstellt.
Schauen wir uns einen Beispielcode an, der diese Idee zusammenfasst:
int card[52] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16..., 51};
int type = card[i] / 13;
int value = card[i] % 13;
In dieser Darstellung ist die Raumkomplexität viel besser (d. h. wir müssen nicht zwei parallele Arrays verwenden).
Wenn wir in der vorherigen Darstellung Elemente in einem Array austauschen wollten, mussten wir entsprechende Elemente im zweiten Array austauschen, um sowohl Typ als auch Wert an den entsprechenden Positionen konsistent zu halten. In dieser zweiten Darstellung können wir mischen, ohne uns darüber Gedanken zu machen.
Der Grund dafür ist, dass nur eine Zahl sowohl den Kartentyp als auch den Wert darstellt.
Die Verwendung von Zahlen wie 10 und 11 verringert die Lesbarkeit des Codes. Um den Code lesbarer zu machen, können wir daher einige Konstanten definieren:
#define JACK 10
#define QUEEN 11
#define KING 12
#define ACE 1
#define HEART 0
#define DIAMOND 1
#define CLUB 2
#define SPADE 3
Jetzt können wir einen Vergleich machen wie:
type = card[i] / 13;
value = card[i] % 13;
... if (type == CLUB)... if (value == JACK)...
Zuletzt können wir ein String-Array zum Drucken der Karte definieren:
string type_name[] = {"Heart", "Diamond", "Club", "Spade"};
string value_name[]{"Ace", "Two", ..., "Jack", "Queen", "King"};
... cout << value_name[value] << "of" << type_name[type] << '\n';
Die Ausgabe wird wie folgt aussehen:
Three of Spade
Jack of Diamond
Queen of Diamond
...
Vollständige C++-Implementierung
Nun müssen die Darstellungen eines Kartenstapels in einem C++-Array klar sein. Um jedoch einen kognitiven Überblick über die Darstellung zu erhalten, kombinieren wir alle oben genannten Codeabschnitte zu einem einzigen, kompilierungsbereiten Code:
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
void Shuffle(int* Deck) {
srand(time(NULL));
int shufflePosition1, shufflePosition2, temp;
int shuffleCount = 100;
for (int i = 0; i < shuffleCount; i++) {
shufflePosition1 = rand() % 52;
shufflePosition2 = rand() % 52;
// swap cards at the shuffle positions
temp = Deck[shufflePosition1];
Deck[shufflePosition1] = Deck[shufflePosition2];
Deck[shufflePosition2] = temp;
}
}
void ShowFirstTenCards(int* Deck, string* TypeName, string* ValueName) {
int valueNamePosition;
int typeNamePosition;
for (int t = 0; t <= 10; t++) {
valueNamePosition = Deck[t] % 13;
typeNamePosition = Deck[t] / 13;
cout << "Position " << t << ": ";
cout << ValueName[valueNamePosition] << " of ";
cout << TypeName[typeNamePosition] << endl;
}
}
int main() {
int Deck[52];
for (int itr = 0; itr <= 51; itr++) {
Deck[itr] = itr;
}
string TypeName[] = {"Heart", "Diamond", "Club", "Spade"};
string ValueName[]{"Ace", "Two", "Three", "Four", "Five", "six", "Seven",
"Eight", "Nine", "Ten", "Jack", "Queen", "King"};
cout << "Top 10 cards before shuffle:" << endl;
ShowFirstTenCards(Deck, TypeName, ValueName);
Shuffle(Deck);
cout << "\nTop 10 cards After shuffle:" << endl;
ShowFirstTenCards(Deck, TypeName, ValueName);
return 0;
}
Das obige Codebeispiel ist eine einfache Implementierung, um einen Kartenstapel darzustellen und Mischoperationen durchzuführen. Bevor wir auf die Details eingehen, schauen wir uns die Ausgabe an.
Ausgang:
Top 10 cards before shuffle:
Position 0: Ace of Heart
Position 1: Two of Heart
Position 2: Three of Heart
Position 3: Four of Heart
Position 4: Five of Heart
Position 5: six of Heart
Position 6: Seven of Heart
Position 7: Eight of Heart
Position 8: Nine of Heart
Position 9: Ten of Heart
Position 10: Jack of Heart
Top 10 cards After shuffle:
Position 0: Queen of Diamond
Position 1: Eight of Spade
Position 2: Five of Heart
Position 3: King of Diamond
Position 4: Nine of Heart
Position 5: Eight of Heart
Position 6: Seven of Heart
Position 7: Seven of Diamond
Position 8: six of Spade
Position 9: Ace of Club
Position 10: Two of Heart
Das obige Programm hat drei Hauptcodesegmente:
- Der Fahrercode (
main()
) - Die Funktion
ShowFirstTenCards()
- Die
Shuffle()
-Funktion
Beginnen wir mit der Erörterung von Codesegmenten von oben nach unten. Der Haupttreibercode erstellt drei Arrays:
Deck
-Array: Zum Speichern der Suite-Informationen der Karten und ihrer Nennwerte gemäß der im vorherigen Abschnitt beschriebenen Methode.TypeName
: Zum Speichern der Namen der vier verfügbaren Suiten.ValueName
: Um englische Namen für die Nennwerte zu speichern, um die Ausgabe dezenter darzustellen.
Nach den wichtigen Deklarationen übergab der Treibercode die drei Arrays als Argument an die Methode ShowFirstTenCards()
. Diese Methode verwendet dann die Wert- und Farbumwandlungsstrategie, um die ersten zehn Karten des Decks anzuzeigen.
Danach ruft die Treiberfunktion die Funktion Shuffle()
mit dem Array Deck
als Argument auf. Diese Shuffle()
-Funktion wählt zufällig zwei Positionen aus dem Bereich [0-51] aus und tauscht den Inhalt an diesen Positionen.
Es wiederholt den gleichen Vorgang hundertmal, um eine gute Mischung zu gewährleisten.
Darüber hinaus verwendet die Funktion shuffle()
den aktuellen UNIX-Zeitstempel als Startwert (in der Funktion srand()
) für die Funktion rand()
, um sicherzustellen, dass der Shuffle bei verschiedenen Aufrufen eindeutig bleibt.
Wenn wir diesen Zeitstempel nicht als Startwert an die Funktion rand()
übergeben, dann erzeugt rand()
immer dieselbe Sequenz für die zufällige Position, was für diese Wahrscheinlichkeitsspiele unerwünscht ist. Mehr über die Funktion rand()
und ihren Seed finden Sie hier.