Четвърта задача
- Краен срок:
- 11.11.2015 17:30
- Точки:
- 6
Срокът за предаване на решения е отминал
Игри с карти
В тази задача ще искаме от вас да имплементирате колоди за три игри с карти + специфични функционалности за всяка игра.
Игрите са: Война, Белот и Сантасе (66).
Уточнения
- Колода == Тесте
- Ще използваме бои и
suits
като синоними -
Стандартна колода - колода с 52 карти, четири бои (
suits
) и 13 ранга (ranks
):Spades: 2 3 4 5 6 7 8 9 10 Jack Queen King Ace Hearts: 2 3 4 5 6 7 8 9 10 Jack Queen King Ace Diamonds: 2 3 4 5 6 7 8 9 10 Jack Queen King Ace Clubs: 2 3 4 5 6 7 8 9 10 Jack Queen King Ace
-
Считаме, че картите от колодата са с гърбове към нас:
- Най-горната карта приемаме за първа карта от колодата
- Най-долната карта приемаме за последна карта от колодата
Карти, бои и рангове
Всяка карта се характеризира със suit
и rank
:
-
Suits
::spades
,:hearts
,:diamonds
и:clubs
-
Ranks
:2
,3
,4
,5
,6
,7
,8
,9
,10
,:jack
,:queen
,:king
,:ace
Имайки предвид горното, ще представим основните компоненти на една колода със следните класове:
- Клас
Card
със следните възможности:- Конструктор, приемащ
rank
иsuit
- Метод
#rank
- връщаrank
-а на картата - Метод
#suit
- връщаsuit
-а на картата - Метод
#to_s
- връща името на картата като низ. Име на карта се дефинира като:<Rank> of <Suit>
. Примери:Ace of Spades
,2 of Clubs
,10 of Hearts
,Jack of Diamonds
Обърнете внимание на главните/малките букви! Важно е!
Две карти трябва да могат да се сравняват с
==
. ТоестCard.new(:queen, :spades) == Card.new(:queen, :spades) # => true
- Конструктор, приемащ
Общи изисквания за всяка колода
- Конструкторът приема опционален аргумент - масив от карти. Първата карта в масива се счита за първа в колодата (най-горна). Ако не бъде подаден този аргумент - считаме, че колодата трябва да съдържа всички възможни за играта карти.
- Имплементира
Enumerable
- Методи:
-
#size
- връща текущия брой на картите в колодата -
#draw_top_card
- премахва най-горната карта от колодата и я връща като резултат -
#draw_bottom_card
- премахва най-долната карта от колодата и я връща като резултат -
#top_card
- връща горната карта без да я премахва от колодата -
#bottom_card
- връща долната карта без да я премахва от колодата -
#shuffle
- разбърква картите в колодата -
#sort
- сортира колодата. Първо поsuit
(в следния ред:Spades
,Hearts
,Diamonds
,Clubs
) и после поrank
(в намаляващ ред). Тоест, ако имаме стандартна колода с 52 карти, то най-горната карта ще бъдеAce of Spades
, а най-долната -2 of Clubs
-
#to_s
- връща имената на всички карти от колодата, всяко на нов ред, като започва от най-горната карта и запазва реда им. Пример (при сортирана колода):Ace of Spades <- Най-горната карта ... Queen of Hearts ... 2 of Diamonds ... Ace of Clubs King of Clubs ... 3 of Clubs 2 of Clubs <- Най-долната карта
-
#deal
- връща обект, представляващ картите в ръката на играч-
#deal
раздава карти от колодата като взима от най-горната към най-долната - Върнатият обект отговаря на метода
#size
, както и на други методи, специфични за всяка игра.#size
връща броя на картите в ръката. Този брой е специфичен за всяка колода.
-
-
Всеки метод, модифициращ колодата, трябва да променя обекта, върху който се изпълнява. Например, #shuffle
не трябва да връща нова колода, а да промени текущата. За подобни методи няма да се интересуваме от върнатата стойност.
Колода за Война
- Име на клас:
WarDeck
- Рангове в нарастващ ред -
2 3 4 5 6 7 8 9 10 Jack Queen King Ace
- Общ брой карти - 52
- Брой карти в ръка - 26 (тук
#deal
ще върне ръка с първите 26 карти от колодата) - Обектът, представляващ картите в ръката на играч, има следните методи:
-
#play_card
- премахва и връща произволна (може да не е случайна) карта от ръката. Няма значение точно коя. -
#allow_face_up?
- връщаtrue
, ако броят на картите в ръката е по-малък или равен на 3 иfalse
в противен случай
-
Колода за Белот
- Име на клас:
BeloteDeck
- Рангове в нарастващ ред -
7 8 9 Jack Queen King 10 Ace
- Общ брой карти - 32
- Брой карти в ръка - 8 (тук
#deal
ще върне ръка с първите 8 карти от колодата) - Обектът, представляващ картите в ръката на играч, има следните методи:
-
#highest_of_suit(suit)
- връща най-силната карта от подадената боя -
#belote?
- дали ръката съдържа двойкаKing
иQueen
от една боя -
#tierce?
- дали ръката съдържа поредица от три карти с последователни рангове от една и съща боя -
#quarte?
- дали ръката съдържа поредица от четири карти с последователни рангове от една и съща боя -
#quint?
- дали ръката съдържа поредица от пет карти с последователни рангове от една и съща боя -
#carre_of_jacks?
- дали ръката съдържа четири валета -
#carre_of_nines?
- дали ръката съдържа четири деветки -
#carre_of_aces?
- дали ръката съдържа четири аса
-
Колода за Сантасе
- Име на клас:
SixtySixDeck
- Рангове в нарастващ ред -
9 Jack Queen King 10 Ace
- Общ брой карти - 24
- Брой карти в ръка - 6 (тук
#deal
ще върне ръка с първите 6 карти от колодата) - Обектът, представляващ картите в ръката на играч, има следните методи:
-
#twenty?(trump_suit)
- дали ръката съдържаKing
иQueen
от една боя, но не са козове -
#forty?(trump_suit)
- дали ръката съдържаKing
иQueen
от една боя и са козове Забележка:trump_suit
указва името на боята, която е коз. Отново като символ.
-
Важни неща
Пуснете си примерните тестове! Така ще сте по-спокойни, че не сте забравили да напишете някой метод.
Много е важно да не се спирате на първото решение, което напишете. Напишете нещо, след което се опитайте да го подобрите. Полезно е за всяко парче код да си задавате следните въпроси:
- Има ли начин да се опрости?
- Дублира ли се логиката на друго място? Ако да - къде би било по-логично да се намира тя?
- Класът, в който се намира, трябва ли да се интересува от тези неща? Ако не - къде би било логично да се премести?
Ограничения
Тази задача има следните ограничения:
- Най-много 80 символа на ред
- Най-много 8 реда на метод
- Най-много 2 нива на влагане
- Най-много 4 аргумента на метод
Ако искате да проверите дали задачата ви спазва ограниченията, следвайте инструкциите в описанието на хранилището за домашните.
Няма да приемаме решения, които не спазват ограниченията. Изпълнявайте rubocop
редовно, докато пишете кода. Ако смятате, че rubocop
греши по някакъв начин,
пишете ни на fmi@ruby.bg, заедно с прикачен код или линк към такъв като
private gist. Ако пуснете кода си публично (например във форумите), ще смятаме
това за преписване.