Je conçois du site de jeu où de nombreux joueurs (espérons que des milliers) jouent simultanément certains jeux de cartes les uns avec les autres. Le pont est le pont de carte standard 52. Chaque carte a une combinaison et un rang. Les cartes seront mélangées, affichées, cueillies, commandées, jouées tout le temps. Ma question est que pour Enum:
Laissez chaque carte être un octet 0..51. Donc, une carte occupera très peu d'espace. Vous pouvez représenter une main comme un jeu de 8 octets. Vous pouvez calculer la combinaison et le rang d'une carte donnée très rapidement lorsque le besoin se pose: c'est-à-dire costume (n) = n / 13. Ce sera très efficace. Si vous devez écrire des méthodes pour les cartes, écrivez-le via des méthodes d'extension. P> li>
pour struct:
Non, c'est comme un code de machine à écrire. Une carte est une structure simple, contient très peu de données, est immuable, est petite. Il n'a pas beaucoup de comportement, alors faites-en une structure et de le traiter comme une structure de données passive. Vous pouvez calculer un index dans 0..51 d'une carte donnée très rapidement lorsque le besoin se pose. P> li>
pour la classe:
Non, ce n'est pas une façon de penser orientée objet. Faire une classe de cartes. Rendre immuable. Créez exactement 52 instances. Laissez une piscine de carte tenir ces instances. Alors, quand on a besoin de reine de pique, il demandera à la piscine de la carte pour cela. Il y aura une seule et une seule reine de Spades, même lorsqu'il y a des milliers de jeux qui se passent. Stockez un champ d'index 0..51 dans la carte si vous le souhaitez. p> li>
ul>
J'incline vers la dernière option (classe) mais je ne suis pas sûr. Je ne suis pas très inquiet pour la performance; Je ferai peut-être des erreurs plus graves en cours de route. Ce que je suis inquiet, c'est que tout mon point de vue est peut-être faux; C'est peut-être une décision très facile et j'hésite parce que je manque de la connaissance de la pièce que tout le monde possède. p>
Que pensez-vous? P>
Edit: À propos du comportement des cartes. Je pense qu'une carte ne saura que sur d'autres cartes. Par exemple, il peut définir un ordre partiel sur "qui bat qui dans le pont". Il n'a pas besoin de savoir quoi que ce soit sur le pont. Et ce sera un code côté serveur; Certes, il n'aura pas besoin de savoir se tirer sur l'écran, etc. p> carte code> soit un énum, une structure ou une classe? p>
7 Réponses :
Vous pouvez représenter chaque carte en tant que numéro et les envelopper dans une classe et une classe. Si chaque nombre compris entre 0 et 51 représente une carte, vous pouvez alors avoir une énumération: Vous pouvez également avoir une classe: p> Ou mieux encore, combinez-les. P> public class Card
{
private readonly Suit _suit;
private readonly Value _value;
public Card(int a_nNumber)
{
_suit = (Suit)(a_nNumber / 13); // 0 = Hearts, 1 = Diamonds ...
_value = (Value)(a_nNumber % 13 + 1); // 1 = ace, 2 = two
}
public Suit Suit
{
get { return _suit; }
}
public Value Value
{
get { return _value; }
}
public int ToNumber()
{
return (int)_suit * 13 + ((int)_value - 1);
}
}
public enum Suit
{
Hearts = 0,
Diamonds = 1,
Clubs = 2,
Spades = 3
}
public enum Value
{
Ace = 1,
Two = 2,
Three = 3,
Four = 4,
Five = 5,
Six = 6,
Seven = 7,
Eight = 8,
Nine = 9,
Ten = 10,
Jack = 11,
Queen = 12,
King = 13,
}
Merci. Je suis d'accord dans le principe qu'une carte peut avoir besoin d'être convertie entre un nombre et une structure / classe.
créer un Pour créer un pont, vous pouvez utiliser un struct code> ou class code> pour la carte, la valeur de la carte doit être un Enum code> et la combinaison de la carte est également un Enum code>. p>
class code>, il contient une liste de la carte code> 's, contient des opérations comme shuffle code>, etc., . p>
La seule chose qui convient de mentionner est de définir Enum code> avec les valeurs de l'éteinte 2, car il n'hépasse que d'identifier les combinaisons des cartes dans le pont de l'utilisateur donné.
@Tigran Je ne suis pas sûr de ce que vous obtenez avec cela.
@Matthew: L'idée est que, s'il y a 52 cartes, chacun d'entre eux est présent ou non présent dans un ensemble donné, l'ensemble de cartes peut être représenté comme un seul entiers long. Beau concept, et il y a des moments utiles; Une difficulté est qu'il existe une variété de codages possibles, qui sont utiles à des fins différentes.
@Matthew: Si vous définissez des cartes telles que Enum code>, comment vous identifierez un ensemble de cartes disponibles dans la main de l'utilisateur spécifié? Pour être clair: comment puis-je comprendre si quelqu'un gagne le blackjack? Et qu'en est-il du pont? Ce sont des jeux complètement différents, avec non seulement des règles différentes (ainsi du modèle comportemental), mais également des ensembles de cartes gagnants différents.
Vous pourriez considérer quelle abstraction vous essayez de construire. Si une carte est un objet de bas niveau transmis par d'autres fonctions, un Enum code> peut être plus approprié, mais si vous souhaitez qu'une carte soit capable de draw () code> elle-même ou quoi que ce soit alors vous aurez besoin de quelque chose de plus sophistiqué. Comment la carte va-t-elle s'adapter à votre application? P>
Pourquoi aurez-vous besoin d'une classe? Une structure peut avoir une méthode "Draw".
N'ayez pas besoin d'une classe - était d'être Daft!
Je pense que cette question peut être répondue logiquement. Je vais y jeter un coup d'oeil à partir d'un point de vue orienté objet. Je pense qu'une carte a deux éléments enfants, costume et valeur. Ceux-ci devraient probablement être Avec plusieurs personnes jouant à des jeux avec différents types de jeux, chaque pont devrait savoir quel type de cartes il a et combien. Mais la carte elle-même serait immuable même dans ce cas. P> Enum code>. Une main (classe) devrait probablement contenir une liste de cartes, ce qui me conduit à croire qu'il serait préférable d'avoir une carte comme structure ou classe. Afin de déterminer si une main a une paire, ce serait une fonction de la classe à la main. P>
J'irais avec une classe ou une struct, en utilisant Enums, et placez un constructeur interne dessus:
public class Deck
{
private List<PlayingCard> cards = new List<PlayingCard>();
public Deck()
{
for(var i = 0; i < 4; i++)
{
for (var j = 1 to 13)
{
this.cards.Add(new PlayingCard((CardSuit)i, (CardFace)j));
}
}
}
public void Shuffle() { /* implement me */ }
public PlayingCard GetNextCard() { /* implement me */ }
}
Je ne crois pas que vous posiez vraiment la bonne question ici. Comment représenter votre carte devrait être une question déterminée par ce que vous voulez faire avec vos cartes; En répondant à la question de savoir comment représenter votre carte maintenant, vous vous contractiez automatiquement de manière automatique de la manière dont vous pouvez résoudre d'autres problèmes plus intéressants / difficiles que vous allez à venir ultérieurement. P>
Les types de choses que vous devriez vraiment penser sont comment vous allez mettre en œuvre le comportement de votre programme. Par exemple p>
Que se passera-t-il lorsqu'une "carte" est distribuée? Voulez-vous représenter une carte étant physiquement déplacée entre les entités qui contiennent ces cartes? (Par exemple, le pont, la main d'un joueur, une pile de défausse, la table, etc.), ou voulez-vous que ces entités ne font que référence à un référentiel central de cartes? ou peut-être utiliser un mécanisme de comptage entièrement séparé? p> li>
Comment allez-vous à "commander" des cartes? Les jeux que vous choisissez de mettre en œuvre peuvent avoir des règles différentes (par exemple Ace faible ou élevée? Les costumes royaux ont-ils la même valeur? et même changé au cours du jeu lui-même, il suffit donc d'avoir une seule définition d'une carte basée sur son commande peut ne pas s'avérer une bonne abstraction. P>
Quels types de comportement et de règles de jeu essayez-vous de représenter qui dépendront de la carte? La carte elle-même aura-t-elle des dépendances? P> LI>
est la carte qui va être impliquée dans l'interaction utilisateur, ou est-ce purement un objet logique utilisé par les parties de votre programme qui définit le ou les jeux de carte? P> LI>
Avez-vous pensé à la possibilité d'utiliser différents types de cartes? Vous avez mentionné une classe dans votre question initiale, mais si une carte va définir tout type d'état, de comportement ou d'interagir avec d'autres classes, vous voudrez peut-être d'abord penser à définir une interface de carte avant de vous inquiéter des détails. P > li> ul> li> ul>
Une réponse directe à votre question - je ne pense pas personnellement que vous avez fourni suffisamment d'informations pour que la réponse soit autre chose qu'une opinion basée sur des devinières et des préférences personnelles; C'est bon parce qu'il est généralement difficile de trouver toutes les réponses avant de commencer la mise en œuvre. Vous voudrez peut-être essayer les trois et voir ce qui convient le mieux à vos besoins. Ne contraintes pas votre conception en faisant ce type de décisions à l'avance. P>
Merci. Tous vos points sont corrects. Je suis en train de rêver d'un cadre comme étant aussi agnostique que possible, ce qui n'est peut-être pas aussi fructueux que je pensais.
La question "Comment les cartes traitées" est-elle intéressante. Un seul avantage possible d'utiliser des cartes comme type de référence est que chaque carte pourrait avoir un code> Propriété de type iCardCollection code>, identifiant le icardCollection code> où il réside (Le constructeur d'une carte nécessiterait une référence au iCardCollection code> où il appartiendrait initialement). Les implémentations de iCardCollection CODE> pourraient être écrites de manière à appliquer l'invariant que chaque carte doit à tout moment être toujours dans une seule collection.
La question fondamentale que vous devriez vous demander lorsque vous décidez entre un type de référence ou un type de valeur est bien sûr Vous envisagez de traiter une "carte" comme référence, de la même manière que vous traiteriez un objet physique qui a une identité? Supposons par exemple que vous modélisez Canasta, qui est joué avec deux ponts de carte standard en même temps. Voulez-vous jamais vouloir garder une trace de deux différentes reines de Spades et les traiter comme de manière référentielle différente em>? p>
ou allez-vous les traiter comme valeurs em>, comme vous traiteriez numéros em>? Vous ne dites jamais "Ce numéro six sur ici est différent de ce numéro six là-bas" car les chiffres ne sont différenciés que par leurs valeurs. P>
+1 c'est exact i> point. La question n'est pas référence code> ou valeur code> mais le jeu b> ou modèle de comportement de jeu que vous allez construire.
Merci. Je traiterais les cartes comme des valeurs, comme les chiffres que je suppose. Mais c'est délicat: l'alternative fait un type de référence immuable avec une mémoire de mémoisation, de sorte qu'il n'y aura qu'une reine de pique existence de toute façon. Honnêtement, je ne peux pas voir la différence entre être une valeur et être une référence dans ce cas. (Ou est-ce que c'est le cas qu'il n'y en a pas; un type de référence mémo immuable est toujours sémantiquement équivalent à une valeur de valeur?)
@Aliferhat: correct; Un type de référence commémoré immuable se comporte beaucoup comme un type de valeur. Essentiellement toutes les "cartes" deviennent un singleton. Si la quantité d'informations sur la carte est inférieure à la taille d'une référence, je vois peu de raisons de faire un singleton; Qu'est-ce que l'indirection vous achète?
Je pense que nous pouvons tous convenir que la classe Java-Style Enum fournirait la meilleure mise en œuvre. Ensemble de valeurs distinct, tout en permettant des méthodes. Mélanger cela avec des propriétés C # ... Oh, quelle glorieuse ce serait: /
Ce n'est probablement pas une question constructive pour ce site, car vous demandez aux opinions des gens. Cela dit, le mien se trouve être que votre instinct a raison. : P
Quel type de comportement carte code> ont-ils? Sachez-vous que ce sera face à face ou quelle position il réside sur une table? N'oubliez-vous-t-il de quelle pont it est venu de savoir, par exemple de quelle couleur son dos est?
Je ne pense pas qu'un
CardPool code> est une bonne idée, il ressemble à une optimisation tôt et inutile ...@Jordao je pense qu'une carte sera immuable. Tout changement changeant comme s'il est affronté ou face à face ne sera pas une partie de celui-ci.
Utiliser une bonne séparation des préoccupations; Ce n'est pas le travail de la Deuce de Spades de vous dire qui a gagné ce dernier tour. Si vous souhaitez implémenter les règles du pont, faites un objet que représente les règles du pont. I>
@ Jordão - accepté, c'est la même chose que de faire un "piscine de numéro" et de demander le numéro 10.
@Aliferhat: Bien sûr, a du sens; Mais dépend aussi de vos objectifs, c'est pourquoi j'ai demandé. La question de base que vous devriez vous poser est si les cartes sont Fongtible dans votre conception I>; Tout le reste suivra ...
"C'est comme un code de machine à écrire" - pouvez-vous expliquer cela? Une structure immuable serait un choix fin, car il doit contenir à la fois la conception et la valeur de la plupart des jeux.
@weston mon alter ego qui prend en charge l'option de struct indique à mon alter ego qui prend en charge l'option Enum: "représentant chaque carte (seulement) comme un index dans un bittharraille semble très faible pensée de niveau. Comme le code de la machine, il peut être plus Performant mais cela entraînera un code plus compliqué, cela ne vaut pas la peine. "
@Aliferhat Je vois, je lis cela comme un commentaire sur la structure, dans ce cas, je suis d'accord avec ce que dit cet alter ego!