[linux-l] Designfrage bzgl. Deckverwaltung

Axel Weiß aweiss at informatik.hu-berlin.de
Fr Okt 21 21:00:26 CEST 2005


Kai Kuehne schrieb:
> Eine Karte hat z.B. eine Eigenschaft "Farbe".
> Moegliche Werte sind schwarz, blau, rot... usw.
> Es kommen keine neuen dazu.

Hai Kai,

für solche Fälle haben die Erfinder von C enums vorgesehen.[1]

> Wie wuerdest ihr das in C++ nun machen?
> Mir fallen folgende Moeglichkeiten ein:
>
> 1) Ein enum pro Eigenschaft der Karte

Genau.

> 2) Eine "CardProperty" Klasse mit - z.B. einem const vector fuer
> moeglichen Werte

Willst Du, dem Benutzer Deines Programms die Möglichkeit geben, während 
des Spiels die Farben-Namen zu ändern? Dann brauchst Du Properties.

> 3) Was anderes, was mir noch nicht eingefallen ist..
>
> Bei 1) bekomme ich Zahlen, was imho ziemlich unuebersichtlich wird,
> wenn jede Eigenschaft der Karten-Klasse eine Ganzzahl ist.

Der Prozessor ist froh, wenn er Zahlen sieht ;). Du willst keine Zahlen 
sehen, sondern Namen für die Eigenschaften, die Du bequem abfragen 
kannst. Ich mach Dir das mal schmackhaft...

> Danke fuer Tipps und Ideen.

z.B. in CardDeck.h:

typedef enum Farbe {Rot, Gelb, Blau, Pink} Farbe;
typedef enum Wert {Clown, Rowdy, Kind, Schwester, Bruder} Wert;

struct Card{
	const Farbe farbe;
	const Wert wert;
	// Methoden
};

extern Card cardDeck[];
extern const unsigned numCards;

und in CardDeck.cc:

extern const unsigned numCards(4 * 5);
struct Card cardDeck[numCards(] = {
	{Rot, Clown},
	{Rot, Rowdy},
	...
	{Gelb, Clown},
	...
	{Pink, Schwester},
	{Pink, Bruder}
};

Du kannst die Karten mischen (durch zufälliges Vertauschen), austeilen 
(durch Zuweisung), vom Stapel ziehen (durch Indizieren) usw.

Hast Du eine Karte in der Hand, kannst Du auf die Farben/Werte zugreifen 
	switch (karte.farbe){
	case Rot:
		// was rotes
		break;
	case Gelb:
		...
	}

und sogar eigene Operatoren elegant schreiben (in CardDeck.h):

inline bool operator<(const Farbe &f1, const Farbe &f2){
	union{
		Farbe f;
		int z;
	} farbe1 = {.f: f1},
	farbe2 = {.f: f2};
	return farbe1.w < farbe2.w;
}
inline bool operator<(const Wert &w1, const Wert &w2){
	union{
		Wert w;
		int z;
	} wert1 = {.w: w1},
	wert2 = {.w: w2};
	return wert1.w < wert2.w;
}
inline bool operator<(const Card &c1, const Card &c2){
	return c1.farbe <  c2.farbe ||
	      (c1.farbe == c2.farbe && c1.wert < c2.wert);
}

Der Vorteil ist, dass der Compiler die Möglichkeit hat, maximale 
Überprüfungen vorzunehmen und Dir Deine Lapsusse gleich vorlegt. Denk 
nochmal nach, bevor Du soschweres Geschütz wie Properties auffährst, von 
dem Du bloß Nachteile hast.

Gruß,
			Axel

[1] Kernighan/Ritchie: Programmieren in C. Zweite Ausgabe 1990, S. 39.




Mehr Informationen über die Mailingliste linux-l