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).