Jak zaprojektować grę karcianą?

10

Nie mogę wymyślić dobrej architektury dla mojej gry karcianej. Potrzebuję pomocy, aby zrozumieć, w jaki sposób gry są zazwyczaj projektowane.

Najpierw opiszę zasady gry.

Zasady gry

Ustawiać
  • Jest czterech graczy, każdy z nich tworzy drużynę.
  • Każdy gracz otrzymuje 12 przetasowanych kart
  • Na stole znajdują się 4 zaślepione karty (rzeka)
  • Kolejność graczy jest taka

wprowadź opis zdjęcia tutaj

Zakłady
  • Każdy gracz może spasować lub wybrać liczbę większą niż obecny zakład między 100 a 160
  • Zakłady rozpoczynają się od pierwszego gracza i kręgów, aż drużyna przejdzie
  • Gdy gracz spasuje, nie może już obstawiać
  • Zespół, który wygra rundę licytacji, powinien przynajmniej zdobyć punkty równe swojemu zakładowi, aby wygrać
  • Zespół, który przegrał rundę licytacji, nie powinien pozwolić swojemu zespołowi osiągnąć swojego celu

  • Jeśli drużyna, która wygrała rundę licytacji, zdobędzie wszystkie punkty, druga drużyna otrzyma ujemne punkty równe ich zakładowi

  • jeśli drużyna, która przegrała rundę licytacji, zbierze wszystkie punkty, druga drużyna otrzyma podwójne ujemne punkty

Przepływ gry i zbieranie punktów

  • Gracz, który wygrał rundę licytacji ( król ), otrzymuje cztery pozostałe karty na stole.
  • Następnie on / on może zapisać zestaw czterech kart w banku kart drużyny, nawet ich nie zagrywając.
  • Król wybierze garnitur jako kostium władcy i powiadomi o tym innych
  • King rozpoczyna grę, kładąc kartę ze swojej ręki na stole. Każdy inny gracz powinien grać w tej kolejności
    • jeśli mają na ręce ten sam kolor tej karty, muszą zagrać jedną z tych kart
    • jeśli go nie mają, mogą grać w dowolnym kolorze
  • Po tym, jak wszyscy inni gracze rozegrają ręce, zwycięzcą rundy będzie:
    • Ten, który ma najwyższą kartę, jeśli wszystkie karty są takie same
    • Ten, który ma najwyższą kartę „władcy”, jeśli taka istnieje
  • Zwycięzca rundy zbierze karty i umieści je w swoim banku
  • Gracz, który wygrał poprzednią rundę, rozpocznie kolejną rundę
  • Będzie to trwało, dopóki ręka nie będzie pusta

Liczenie punktów

  • Wygrana w każdej rundzie ma 5 punktów. Oznacza to, że każda 4 karty ma co najmniej 5 punktów.
  • Posiadanie asa, 10 lub 5 w banku dodaje 5 punktów

Mój projekt

Klasy

class Card {
   string suit;
   string rank
}
class Deck {
  List cards = [];
  List suits = ['S', 'H', 'D', 'C'];
  List ranks = ['1', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A'];
  private void init(){..}
  void shuffle(){...}
}

class Game{
  Deck deck = new Deck();
  Player player1;
  Player player2;
  Player player3;
  Player player4;
  int _isOn = 0;

  Game(this.player1, this.player2, this.player3, this.player4){
    deck.makeCards();
    deck.shuffle();
    start();
  }

  void start(){
    player1.cards.addAll( deck.cards.getRange(0, 12) );
    player2.cards.addAll( deck.cards.getRange(12, 24) );
    player3.cards.addAll( deck.cards.getRange(24, 36) );
    player4.cards.addAll( deck.cards.getRange(36, 48) );
    deck.cards.removeRange(0, 48);
  }

  String toJson(){
  }

  String toString(){
  }
}
class Player{
  String name;
  int points;
  List cards = [];

  Player(this.name, {this.points});

  String toJson(){}

  String toString(){}
}

Mój problem

Teraz, gdy zdefiniowałem wszystkie te klasy, nie wiem, jak powiązać te definicje z bazą danych (np. Mongo) i kontrolować przebieg gry.

  • Gdzie powinna iść cała ta logika?
  • Jak powinienem zachować stan w scenariuszu serwer / klient?

Uwaga:

Używam Dart do programowania tego, ale nie potrzebuję, aby odpowiedzi były pisane w Dart.

Mohsen
źródło
Jeśli ktoś patrzy na twój kod i używa go jako punktu wyjścia, pamiętaj, że powinieneś wybrać A lub 1 w szeregach, ale nie uwzględniaj obu.
Ben

Odpowiedzi:

10

Popełniasz tutaj klasyczny błąd. Ktoś kazał ci stworzyć aplikację internetową do gry karcianej, a ty próbujesz ustalić, jak zrobić to wszystko na raz. Takie podejście dezorientuje nawet najlepszych programistów, ponieważ badania wykazały, że możesz zatrzymać tylko 7 informacji dostępnych w twoim umyśle na raz. Próba żonglowania bardziej wymaga intensywnej koncentracji i nie możesz oczekiwać, że tak utrzymasz.

Staraj się raczej skoncentrować na pisaniu biblioteki gier karcianych, tak jakby ktoś chciał zadzwonić do twojej biblioteki, aby zagrać w nią. Wygląda na to, że masz doskonały start w swoim modelu. To dobrze, ale musisz stworzyć Gameinterfejs, za pomocą którego dzwoniący mogą wykonywać ruchy i tak dalej.

Spodziewałbym się, że w grze pojawi się kilka nowych metod, takich jak:

getPlayers()        // Get all player info
getCurrentPlayer()  // Get information about the active player in his turn (hand, money to bet with, etc.)
fold()              // Current player folds and current player changes
bet(float amount)   // Current player bets and current player changes

Krótko mówiąc, wszystko, co musisz wiedzieć, aby uruchomić grę, możesz to zrobić, używając swojego obiektu Game. Dopiero gdy to zrobisz, przejdziesz do kroku 2.

Napisz osobną klasę, której jedynym celem jest przyjmowanie przychodzących żądań, zastosuj je Gamei odeślij dane wyjściowe do użytkownika. Jeśli chcesz przekonwertować Gamedane wyjściowe na JSON, robisz to poza, Gameponieważ nie jest to celem Game!

Aby zachować te informacje, możesz utworzyć inną klasę, która zapewnia interfejs dla MongoDB. Klasa ta nie wiedziałaby o istnieniu Gamei żadna nie Gamewiedziałaby o istnieniu tej klasy.

Krótko mówiąc, skup się na poszczególnych komponentach, a wszystko będzie dobrze. Zaczynasz się mylić, gdy próbujesz wziąć pod uwagę zbyt wiele aspektów podczas pisania programu. Jak kiedyś powiedział mi mądry profesor: „ Wiedz i zaakceptuj fakt, że pierwszy program, który napiszesz dla projektu, zostanie przepisany w całości do końca ”.

Neil
źródło
Poza tym liczba ta wynosi od 3 do 9 w zależności od osoby - mogę zrobić 4 lub 5 w zależności od tego, jak jestem czujny. Zwykle test polega na spojrzeniu na wiązkę kropek i ustaleniu, ile z nich możesz postrzegać indywidualnie bez grupowania ich mentalnie - w wieku 6 lat zaczynam automatycznie grupować je na przykład w 3 + 3 i nie mogę ich łatwo rozdzielić .
Izkata,
@Izkata To interesujące. Nie wiedziałem, że istnieje na to test. Czy masz link?
Neil
1
en.wikipedia.org/wiki/… jest, jak sądzę, źródłem.
AakashM
1

Gdzie powinna iść cała ta logika?

Zacznij od umieszczenia go w swojej Gameklasie.

Jest to gra oparta na regułach z ograniczoną liczbą stanów. Modelowałbym to jako maszynę stanu . Wzór państwo pomoże Ci ogromnie.

W końcu będziesz chciał wyodrębnić ten FSM do osobnych klas, ale nie martw się tym na razie.

Jak powinienem zachować stan w scenariuszu serwer / klient?

Nie można odpowiedzieć bez wiedzy na temat konfiguracji. Serializacja obiektu gry i stanów do bazy danych co turę może załatwić sprawę.

Martin Wickman
źródło
Oto artykuł towarzyszący o stanie / FSM, w tym przypadku z książki poświęconej grom: gameprogrammingpatterns.com/state.html
shmup