Domanda

Sto scrivendo una HandConverter di una mano di poker. Questo è il mio primo progetto e sto cercando di farlo fin dall'inizio.

Ho già il maggior numero di parti, come gli elenchi dei giocatori, la loro posizione, Catasta dimensioni, carte per diverse schede, che gioco è in fase di riproduzione e così via, ma io lottano con la rappresentazione delle scommesse, in particolare i diversi rilanci, scommesse e più chiamate dallo stesso giocatore.

Ho trovato alcuni casi in cui la mia soluzione basata caso ingenuo non funziona, ed è davvero complicato e non mi piace che. Come attualmente lavora per NL Hold'em penso che dovrò più soluzioni alternative per fare se voglio implementare giochi come Stud, Razz e così via ospitarci la struttura delle scommesse è probabile che lo stesso.

Per il momento io uso questa rappresentazione e vorrei migliorare in particolare la Round e Action classi. Hai qualche suggerimento per me?

public class HandHistory
{
    public GameInfo GameInfo;
    public TableInfo TableInfo;
    public List<Player> Players;
    public List<Round> Rounds;
    public string rawtext;
    public bool withHero;

}

public Round
{
    public List<Action> Action;
    public string Name;
    public decimal Potsize;
    public ulong Cards; //usually would have used a custom class, 
                        //but I need them in a ulong mask for some library I use
}

public class Action
{
    public Player Player;
    public string Type;
    public decimal Amount;
}

P.S. Sto anche utilizzando un List per memorizzare i diversi turni, c'è modo migliore come ereditare la classe di tondo per Flop, Turn e River per esempio?

È stato utile?

Soluzione

Quando si dice il primo progetto che cosa vuoi dire? Sto indovinando sei uno studente o nuovi alla programmazione.

In base a tale ipotesi vorrei suggerire raccogliendo qualcosa di più semplice e di una storia del poker mano. Come nella programmazione del gioco è irragionevole pensare sul tuo primo colpo di programmazione di un gioco si crea l'ultimo Call of Duty. Si inizia con strappo e sposta da lì.

Se non si desidera avviare più piccolo di Suggerisco di non saltare in codifica. Quando fate che vi permetterà di trascorrere più tempo solo girare le ruote piuttosto che ottenere qualcosa di fatto.

Per esempio si dovrebbe prima passare del tempo la progettazione di che cosa il vostro programma lo farà e ciò che non lo farà. Cercate di essere il più completo possibile. Questo può essere fatto da qualcosa di così complicato utilizzando un programma di UML o semplice come carta e penna.

Vorrei fluire fuori come si desidera una mano al progresso. Informazioni che si desidera monitorare. Una volta che si ha realmente capire questo i dati delle strutture inizieranno a prendere vita.

Dal momento che siete nuovi alla programmazione, vorrei iniziare a scrivere codice di prova. Poi spostarlo al progetto finale. Quello che voglio dire proof of concept è il codice che si sta solo testando un'idea per vedere come funziona. Per esempio, come sarebbe consegnare il lavoro della storia? Si può creare un pò di storia 'finta' e impostare? Idealmente si farebbe test di unità, ma consente di iniziare un po 'più piccolo.

E 'importante sapere che si sta costruendo un programma, proprio come una casa. Hai bisogno di sapere che cosa si vuole fare e non fare (stampe blu). Ciò che ogni passo è. E si costruisce su altri pezzi lentamente. E 'un processo che richiede tempo, ma alla fine è valsa la pena.

Altri suggerimenti

Al posto di una stringa per il vostro Action.Type, è possibile utilizzare un enum:

enum BettingAction
{
   Check,
   Bet,
   Call,
   Raise,
   Fold
}

Schede potrebbe avere un nome migliore, ma io parto dal presupposto che dire le carte comuni. Vorrei fare un elenco di carte, poi il turno e sottoclassi di fiume sarebbe solo hanno sempre e solo una carta nella lista. Vorrei anche suggerire che rappresentano le carte in un modo che abbia senso per voi e poi fare una conversione quando si ha bisogno di interfacciarsi con la libreria.

Non proprio una risposta correlata programmazione; ma gli stili di scommesse per Razz o Stud è diverso da Hold 'em in diversi modi.

.

1) Non ci sono tende; piuttosto antes
2.) L'apertura persona può sia bring-in o completare la puntata
3.) Ci sono più giri di scommesse

Si dispone di un buon inizio. si sarebbe probabilmente desidera creare un List<Hands> che ha List<Rounds> al suo interno. In caso contrario, avrete una lista enorme di giri senza essere in grado di dire quando una parte ha iniziato / finito e un altro ha avuto inizio.

Credo che probabilmente è necessario definire i vostri tipi di azione, e poi le cose probabilmente comincerà a cadere in luogo. Ecco cosa avrei per i tipi:

Controlla
Bet
piegare
chiamare
Sollevare (essenzialmente una chiamata e la scommessa)

Potrebbe anche voler pensare sull'implementazione di qualcosa come "Azione Prima" sulla Class Action; come ogni giocatore reagisce all'azione prima di loro.

Si potrebbe anche voler affrontare alcune sfumature del gioco; in cui il giocatore di scommesse 500 e il giocatore B va all in per 250; dal momento che, tranne in questo caso, la chiamata deve corrispondere la puntata precedente.

Il termine Round è un po 'ambigua. BettingRound rende più evidente. Non vedo la necessità di avere le carte, nome e Pentola qui. Pentola è una funzione delle azioni e delle modifiche in tutto il giro di puntate. Posti a sedere rappresentano il gioco un po 'meglio di una lista di giocatori non in quanto ciò permette di rappresentare lo stato del gioco (dimensioni degli stack, ecc) un po' di più, ovviamente. Non vedo la necessità di rendere il flop, river esplicitamente assegnati a turni - basta usare una lista di carte e alcune convenzioni. per esempio. prime tre carte al flop = ... primo giro di puntate = flop. Utilizzare alcuni metodi di estensione per comodità di riferimento al flop holdem. Utilizzare la versione ulong delle schede tramite la conversione quando si ha bisogno di usarlo, piuttosto che ingombrano il vostro modello di dominio.

Questo è come io vedo il modello di un particolare gioco individuale (vale a dire 1 flop, fiume, girare ecc). C'è ancora un sacco di lavoro da fare per modellare tutti i giochi (ad esempio giochi limitare l'uso piccola puntata / grande scommessa, invece di tende per definire la posta in gioco).

Scheda public class     {         Suit Suit pubblica;         Classifica Classifica pubblica;         pubblico ULONG ToCardMask ();     }

public enum Suit
{
    Clubs,
    Diamonds,
    Hearts,
    Spades
}

public enum Rank
{
    Ace,
    Deuce,
    Trey,
    //...
    Jack,
    Queen,
    King
}

public class Game
{
    public GameInfo GameInfo;
    public TableInfo TableInfo;
    public List<BettingRound> BettingRounds;
    public List<Card> CommunityCards;
    public string Rawtext;
    public bool WithHero; //??
}

public static class GameExtensions
{
    public static BettingRound Flop(this Game game)
    {
        return game.BettingRounds[0];
    }

    public static List<Card> FlopCards(this Game game)
    {
        return game.CommunityCards.Take(3).ToList();
    }
}

public class GameInfo
{
    public GameType GameType;
    public GameBettingStructure BettingStructure; // Limit, PotLimit, NoLimit
    public Stakes Stakes; // e.g. { $1, $2 }
    public long Id;
    public List<Seat> Seats;
}

enum GameType // prob change to a class for extensibility
{
    HoldEm,
    Razz,
    StudHi,
    StudHiLo,
    OmahaHi,
    OmahaHiLo
}

enum GameBettingStructure
{
    Limit,
    PotLimit,
    NoLimit
}

class Stakes // probably needs some tweeking for stud games (e.g. bring-in ...)
{
    public Money Ante;
    public List<Money> Blinds;
}

public class Seat
{
    public Player Player;
    public Money InitialStackAmount;
    public Money FinalStackAmount; // convienience field can be calculated
    public List<Card> Hand;
}

class Money
{
    public decimal Amount;
    public Unit Unit;
}

enum Unit
{
    USD,
    EUR,
    AUD,
    TournamentDollars
}

public class Player
{
    public string Name;
}

public class TableInfo
{
    public string Name;
}

public class BettingRound
{
    public List<BettingAction> BettingActions;
}

public class BettingAction
{
    public abstract Money PotSizeAfter();
    public byte SeatNumber;
}

public class Fold : BettingAction { }
public class Call : BettingAction { }
public class BringIn : BettingAction { }
public class Complete : BettingAction { }
public class Bet : BettingAction
{
    public Money Amount;
}

public class Raise : Bet { }

invece di sottoclassi rotonda in FlopRound TurnRound etc, vorrei utilizzare un attributo Street a turno, e all'interno di azione pure.

static public enum Via {PREFLOP, flop, turn, FIUME};

...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top