ZSI. NMJP – Programowanie Obiektowe (27.II.2003)
                  Program zaliczeniowy ze Smalltalka
                              wersja 1.01

Wstęp

W grze w tysiąca bierze udział 3 graczy. Gracze grają talią składającą
się  z  24  kart: 9-tki, walety, damy, króle, dziesiątki i asy  (karty
podano wg rosnącej siły, tzn. as bije wszystkie inne karty tego samego
koloru,  dziesiątka wszystkie inne karty poza asem itp.).  Gra  składa
się z kolejek i toczy się aż do zdobycia przez (co najmniej) jednego z
graczy 1000 lub więcej punktów (stąd nazwa). Wygrywa ten gracz,  który
w  momencie zakończenia gry ma najwięcej punktów. Każda kolejka składa
się z:
1.  Potasowania i rozdania kart.
2.  Licytacji.
3.  Rozgrywki.
Na  początku  każdej kolejki jeden z graczy tasuje  i  rozdaje  karty.
Karty  rozdawane są następująco: każdy z graczy dostaje po 7  kart,  3
karty zostają (zakryte) na stole.
Podczas  licytacji gracze kolejno deklarują, ile oczek  podejmują  się
zdobyć podczas rozgrywki (ugrać) lub pasują (oczywiście należy podawać
większe  liczby oczek niż poprzedni gracz). Licytację  wygrywa  ten  z
graczy, który zalicytuje największą liczbę oczek. Licytacja kończy się
po  dwu  kolejnych pasach. W każdej kolejce jeden wybrany  gracz  musi
zacząć  licytowanie  od  100  oczek  (niezależnie  od  tego,  czy   ma
odpowiednio silne karty). Dzięki temu zawsze jest określony  zwycięzca
licytacji.  Zwycięzca  licytacji bierze trzy karty  leżące  na  stole,
następnie  daje  po jednej karcie (nie koniecznie  z  tych  trzech  ze
stołu)  obu partnerom. Każda karta ma określoną liczbę oczek  (A:  11,
10:  10, K: 4, D: 3, W: 2, 9: 0). Ponadto, jeśli gracz ma króla i damę
tego  samego  koloru  (co nazywa się w tej grze  meldunkiem),  może  w
czasie rozgrywki wychodząc w jedną z tych kart (ale tylko wychodząc, a
nie  dokładając do karty wychodzącego) zgłosić meldunek, za co dostaje
dodatkowe  punkty  (100 za kiery, 80 za kara, 60 za  trefle  i  40  za
piki).  Zatem gracz może mieć meldunek i nie dostać za niego w  czasie
rozgrywki punktów, jeśli nie uda mu się zgłosić tego meldunku – bardzo
częsta  sytuacja,  gdy  inny gracz ma np. asa i dziesiątkę  w  kolorze
meldunku.

Po  licytacji gracz który ją wygrał, bierze 3 karty ze stołu, a  potem
rozdaje  po  jednej swojej karcie (nie muszą to być  karty  wzięte  ze
stołu)  pozostałym dwóm graczom. Następnie wychodzi w  dowolną  kartę.
Pozostali  gracze  dokładają  po jednej  karcie  (trzeba  dokładać  do
koloru, jeśli się nie ma, to można dołożyć cokolwiek). Ten kto położył
najwyższą  kartę, zbiera wszystkie trzy karty (lewę) i sam wychodzi  w
dowolną  ze swoich kart. Cała rozgrywka składa się z 8 takich  zagrań.
Gracz  wychodzący  może (o ile ma damę i króla w  tym  samym  kolorze)
zgłosić meldunek, musi wówczas wyjść w damę lub króla meldunku.  Kolor
zgłoszony w meldunku staje się kolorem atutowym (na początku rozgrywki
nie  ma  atu,  nowy kolor atu zastępuje stary). Nie ma  znaczenia  kto
wziął  lewę  przy zgłaszaniu meldunku. Nowe atu obowiązuje od  momentu
zgłoszenia  meldunku.  Karta koloru atu bije  wszystkie  karty  innych
kolorów  (ale  nie można dokładać karty w kolorze atu  dopóki  ma  się
karty w tym kolorze, w który wyszedł gracz kładący pierwszą (z trzech)
kartę pojedynczego zagrania).

Po  zakończeniu  rozgrywki  każdy  gracz  sumuje  wartości  wszystkich
wziętych przez siebie kart oraz zgłoszone przez siebie meldunki. Gracz
który  wygrał licytację dopisuje sobie zalicytowaną liczbę punktów  (o
ile  zdobył  tyle co zalicytował lub więcej punktów) lub  odejmuje  tę
liczbę  punktów  (o  ile zdobył ich mniej niż zalicytował),  pozostali
gracze  dopisują  sobie  tyle punktów ile  ugrali.  (Np.  gracz  który
zalicytował 130 a ugrał 200, dopisuje sobie 130, zaś gdyby  ugrał  129
to musiałby doliczyć sobie -130.)

Zadanie

Zaimplementuj w Smalltalku klasy służące do przeprowadzania  symulacji
gry  w  1000.  Należy uwzględnić metody potrzebne do  tasowania  kart,
rozdawania  kart  i  przeprowadzania  licytacji  i  rozgrywki.  Należy
wyróżnić  (co  najmniej)  klasy:  Karta,  Gra  i  Gracz.  Należy   też
przewidzieć następujące rodzaje graczy:
·    losowy:  z  prawdopodobieństwem 0.5 zgłasza  liczbę  oczek  o  10
  większą od dotąd wylicytowanej,
·    optymista: jeśli suma oczek, które na pewno uda mu się ugrać  bez
  meldunków  plus  suma punktów za wszystkie posiadane  meldunki  jest
  większa bądź równa dotąd wylicytowanej liczbie oczek + 10, to zgłasza
  liczbę oczek większą od dotąd wylicytowanej o 10, wpp. pasuje,
·    ostrożny: jeśli suma oczek, które na pewno uda mu się zdobyć  bez
  meldunków plus suma punktów za te posiadane meldunki, do których ma (w
  tym samym kolorze) asa i dziesiątkę jest większa bądź równa od dotąd
  wylicytowanej liczby oczek + 10, to zgłasza liczbę oczek większą  od
  dotąd wylicytowanej o 10. wpp. pasuje.
(Powyższe  zasady nie dotyczą oczywiście rozpoczynania licytacji,  tam
gracz rozpoczynający musi zalicytować 100).
Podczas  rozgrywki każdy z graczy dokłada kartę do koloru (o  ile  ma,
wpp. w kolorze atu, a jeśli i takiej nie ma to dowolną) tak, aby o ile
to możliwe przebić dotąd wyłożone karty. Wychodząc jako pierwszy gracz
wybiera  meldunek, a jak nie ma to jedną z najwyższych swoich  kart  w
atu  (lub  jeśli nie ma) w jednym z pozostałych kolorów.  Gracz  który
wygrywa  licytacje  oddaje  partnerom dwie najsłabsze  karty  (to  nie
zawsze jest optymalna strategia).

Symulacja  powinna polegać na rozegraniu dla zadanych 3 graczy  jednej
gry  w  tysiąca  z  wypisaniem  przebiegu poszczególnych  licytacji  i
rozgrywek   oraz  liczby  punktów  poszczególnych  graczy  po   każdej
rozgrywce. Ograniczamy liczbę rozgrywek do co najwyżej 20 (czyli po 20-
tej  przerywamy symulację, nawet jeśli jeszcze nikt nie osiągnął  1000
punktów).

Zadanie  należy  oddać  w  postaci pakietu z komentarzem  zawierającym
przykładowe wywołanie symulacji.

Wskazówki

Być   może  warto  zaimplementować  następujące  metody  (nie   musisz
implementować dokładnie takich metod, to tylko wskazówka):
·   Gracz>>rozdaj: talia dla: gracz1 oraz: gracz2
  tasuje karty z talii i rozdaje je (wg zasad) sobie i dwu pozostałym
  graczom, jako wynik daje kolekcję (Set) trzech pozostałych po rozdaniu
  kart.
·   Gracz>>ileLicytujesz: aktualnaLiczbaOczek
  zgodnie z rodzajem gracza, na podstawie jego kart i zadanej jako
  parametr dotąd wylicytowanej liczby oczek zgłasza nową (wyższą) liczbę
  oczek (wynik metody) lub pasuje (wtedy wynikiem metody jest nil). Ta
  metoda nie jest wywoływana na samym początku licytacji (bo wtedy i tak
  rozpoczynający gracz musi zadeklarować 100).
·   Gracz>>ileOczekWeźmieszNaPewno
  jako wynik daje liczbę oczek, które gracz ugra na pewno bez meldunków,
  wynik jest liczony w następujący (bardzo przybliżony) sposób: w każdym
  kolorze liczymy ile mamy po kolei najsilniejszych kart (np. dla A, 10,
  D mamy 2: A i 10), następnie sumujemy liczby oczek tych kart.
·   Karta>>punktyZaMeldunek
  jako wynik daje liczbę punktów przyznawaną za zgłoszenie meldunku w
  kolorze podanej jako parametr karty.
·   Gracz>>weźTrzyKarty: karty iDajDwiedla: gracz1 oraz: gracz2
  bierze trzy karty, a następnie daje dwie najniższe ze wszystkich
  swoich partnerom.
·   Gracz>>zagranieZ: gracz1 oraz: gracz2
  zagrywa jedną ze swoich kart, pozostali gracze dokładają po jednej, a
  następnie wszystkie trzy wyłożone karty są przekazywane temu kto
  zgodnie z regułami gry położył najwyższą kartę.
·   Gra>>wyższa: karta1 od: karta2
  jako wynik daje true, jeśli pierwsza karta, uwzględniając aktualne
  atu, jest wyższa, false wpp. Zadbaj o to, by gra wiedziała jakie jest
  atu).