Je wordt geblinddoekt en krijgt daarna een stapel kaarten in je hand. Dit
moeten niet noodzakelijk alle 52 kaarten uit een standaard kaartspel zijn.
Sommige kaarten van die stapel liggen met hun beeldzijde naar boven, de
andere met hun beeldzijde naar onder. Als we je nu vertellen dat de stapel
exact
Ook al zouden we geblinddoekt het aantal kaarten in de stapel kunnen
tellen, we hoeven eigenlijk zelfs niet te weten hoeveel kaarten er in de
oorspronkelijke stapel liggen. Maar laten we zeggen dat de stapel uit
Als de eerste stapel
Concreet, stel dat we een stapel met 16 kaarten krijgen, waarvan er 7 met
hun beeldzijde naar boven liggen. We verdelen die stapel dan in twee,
waarbij de eerste stapel bestaat uit de eerste 7 kaarten en de tweede
stapel uit de laatste 9 kaarten. Als er in de eerste stapel 3 kaarten met
hun beeldzijde naar boven liggen, dan moeten er in de tweede stapel
Een standaard kaartspel bestaat uit 52 verschillende kaarten die onderverdeeld worden in vier kleuren van elk 13 kaarten: 13 klaveren (♣), 13 ruiten (♦), 13 harten (♥) en 13 schoppen (♠). Klaveren en schoppen zijn zwart, ruiten en harten zijn rood, maar het zijn niet deze fysieke kleuren, maar de soorten die met de term kleur aangeduid worden. Van elke kleur zijn er telkens kaarten met een rang van 2 tot en met 10, een boer, een vrouw, een heer en een aas. Daarnaast bevat een spel soms twee of drie jokers, maar die laten we hier even buiten beschouwing.
We stellen elk van de 52 kaarten van een standaard kaartspel voor als een string die bestaat uit de rang van de kaart, gevolgd door de kleur van de kaart:
rangen: 2, 3, 4, 5, 6, 7, 8, 9, 10, J (boer), Q (vrouw), K (heer) en A (aas)
kleuren: C (klaveren; ♣), D (ruiten; ♦), H (harten; ♥) en S (schoppen; ♠)
Zo stelt AS bijvoorbeeld schoppenaas voor, 10H hartentien en KC klaverenheer. Bovendien leggen we vast dat de voorstelling van een kaart die met zijn beeldzijde naar boven ligt gebruikmaakt van hoofdletters (bijvoorbeeld AS of 10H), en dat de voorstelling van een kaart die met zijn beeldzijde naar onder ligt gebruikmaakt van kleine letters (bijvoorbeeld as of 10h). Merk op dat het laatste karakter van de voorstelling altijd een hoofdletter of een kleine letter is (geen cijfer) die de kleur van de kaart aanduidt.
De lijstvoorstelling van een stapel kaarten bestaat uit een lijst met de voorstellingen van de opeenvolgende kaarten uit de stapel, waarbij de bovenste kaart van de stapel het eerste element van de lijst is. Een stapel hoeft niet noodzakelijk alle 52 kaarten van een kaartspel te bevatten.
Definieer een klasse Stapel die kan gebruikt worden om stapels kaarten voor te stellen, waarbij sommige kaarten met hun beeldzijde naar boven en de andere met hun beeldzijde naar onder liggen. Bij het instantiëren van objecten van de klasse Stapel moet de lijstvoorstelling van de stapel kaarten doorgegeven worden. De klasse mag ervan uitgaan dat de gegeven lijstvoorstelling geldig is, zonder dat dit expliciet moet gecontroleerd worden. Voorts moet de klasse Stapel minstens de volgende methoden ondersteunen:
Een methode beeldzijdeBoven waaraan geen argumenten kunnen doorgegeven worden. De methode moet een natuurlijk getal teruggeven dat aangeeft hoeveel kaarten van de stapel momenteel met hun beeldzijde naar boven liggen.
Een methode splitsen waarmee de stapel kaarten
Een methode omdraaien waarmee een aantal kaarten van de stapel kunnen omgedraaid worden. Een kaart die met zijn beeldzijde naar boven lag, moet na het omdraaien met zijn beeldzijde naar onder liggen. Een kaart die met zijn beeldzijde naar onder lag, moet na omdraaien met zijn beeldzijde naar boven liggen. De posities van de kaarten in de stapel veranderen nooit bij het omdraaien. Aan de methode kan een argument doorgegeven worden dat de posities van de kaarten aanduidt die moeten omgedraaid worden. Daarvoor bestaan de volgende mogelijkheden:
geen argument: alle kaarten van de stapel moeten omgedraaid worden
argument is een integer: geeft positie aan van de ene kaart die moet omgedraaid worden
argument is een collectie (een lijst, een tuple of een verzameling) van integers: geeft posities aan van de kaarten die moeten omgedraaid worden
Hierbij worden de kaarten van boven naar onder genummerd vanaf 0 om hun positie binnen de stapel te bepalen. De methode moet de toestand van de kaarten in de stapel wijzigen (beeldzijde naar boven of naar onder) en moet een verwijzing teruggeven naar het object dat de stapel voorstelt.
De conversie van een object
Zorg er ook voor dat de ingebouwde operator == kan gebruikt worden om te bepalen of twee objecten van de klasse Stapel gelijk zijn. Dit is het geval als de twee stapels evenveel kaarten bevatten die met hun beeldzijde naar boven liggen.
>>> kaarten = Stapel(['AH', '3S', 'KC', '4H', '3D', '10H', '8D', '5D', '7C', 'QS', 'JC', '3H', 'KS', '4C', 'KD', '8S']) >>> print(kaarten) AH 3S KC 4H 3D 10H 8D 5D 7C QS JC 3H KS 4C KD 8S >>> kaarten Stapel(['AH', '3S', 'KC', '4H', '3D', '10H', '8D', '5D', '7C', 'QS', 'JC', '3H', 'KS', '4C', 'KD', '8S']) >>> kaarten.beeldzijdeBoven() 16 >>> kaarten.omdraaien() Stapel(['ah', '3s', 'kc', '4h', '3d', '10h', '8d', '5d', '7c', 'qs', 'jc', '3h', 'ks', '4c', 'kd', '8s']) >>> kaarten.omdraaien(1).omdraaien(4).omdraaien([5, 9]).omdraaien((10, 11, 13)) Stapel(['ah', '3S', 'kc', '4h', '3D', '10H', '8d', '5d', '7c', 'QS', 'JC', '3H', 'ks', '4C', 'kd', '8s']) >>> print(kaarten) ** 3S ** ** 3D 10H ** ** ** QS JC 3H ** 4C ** ** >>> kaarten.beeldzijdeBoven() 7 >>> kaarten1, kaarten2 = kaarten.splitsen(4) >>> print(kaarten1) ** 3S ** ** >>> kaarten1 Stapel(['ah', '3S', 'kc', '4h']) >>> kaarten1.beeldzijdeBoven() 1 >>> print(kaarten2) 3D 10H ** ** ** QS JC 3H ** 4C ** ** >>> kaarten2 Stapel(['3D', '10H', '8d', '5d', '7c', 'QS', 'JC', '3H', 'ks', '4C', 'kd', '8s']) >>> kaarten2.beeldzijdeBoven() 6 >>> kaarten1 == kaarten2 False >>> kaarten3, kaarten4 = kaarten.splitsen() >>> print(kaarten3) ** 3S ** ** 3D 10H ** >>> kaarten3 Stapel(['ah', '3S', 'kc', '4h', '3D', '10H', '8d']) >>> kaarten3.beeldzijdeBoven() 3 >>> print(kaarten4) ** ** QS JC 3H ** 4C ** ** >>> kaarten4 Stapel(['5d', '7c', 'QS', 'JC', '3H', 'ks', '4C', 'kd', '8s']) >>> kaarten4.beeldzijdeBoven() 4 >>> kaarten3 == kaarten4 False >>> kaarten3.omdraaien() Stapel(['AH', '3s', 'KC', '4H', '3d', '10h', '8D']) >>> print(kaarten3) AH ** KC 4H ** ** 8D >>> kaarten3.beeldzijdeBoven() 4 >>> kaarten3 == kaarten4 True
De opeenvolgende statements uit bovenstaande voorbeeldsessie komen overeen met het voorbeeld van de kaartentruc zoals die gegeven werd op het einde van inleiding van deze opgave. Klik op onderstaande afbeelding voor een visuele voorstelling van de opeenvolgende stappen van de kaartentruc.
kaarten = Stapel(['AH', '3S', 'KC', '4H', '3D', '10H', '8D', '5D', '7C', 'QS', 'JC', '3H', 'KS', '4C', 'KD', '8S'])
kaarten.omdraaien()
kaarten.omdraaien(1)
kaarten.omdraaien(4)
kaarten.omdraaien([5, 9])
kaarten.omdraaien((10, 11, 13))
kaarten3, kaarten4 = kaarten.splitsen()
kaarten3.omdraaien()