Trek willekeurig negen kaarten uit een kaartspel, schud ze en leg ze met hun beeldzijde naar onder in drie stapels van elk drie kaarten. Kies een willekeurige stapel en onthoud wat de onderste kaart van die stapel is. Leg de drie stapels terug op elkaar, maar zorg ervoor dat de gekozen stapel bovenaan ligt.
Het effect van deze stap is dat de gekozen kaart (de kaart die je onthouden hebt) nu altijd als derde kaart op de stapel ligt, geteld vanaf de bovenkant van de stapel.
Stel dat de gekozen kaart schoppen vier is. Dat is four of spades in het Engels. Spel F-O-U-R waarbij je bij elke letter telkens de bovenste kaart van de stapel in je hand op een nieuwe stapel legt die op tafel gevormd wordt. Leg daarna de overige kaarten uit je hand bovenop de stapel van vier kaarten op tafel — zonder ze van volgorde te veranderen — en neem de stapel terug in je hand. Herhaal deze stap nu nog twee keer, telkens met een ander woord. Spel O-F en plaats de overige kaarten opnieuw bovenop deze twee. Spel daarna S-P-A-D-E-S en leg de overige kaarten er bovenop.
Pak nu de stapel terug in je hand en spel M-A-G-I-C, waarbij je de laatste kaart met zijn beeldzijde naar boven legt. Je zal merken dat het inderdaad schoppen vier is.
Opmerkelijk aan deze truc is dat hij telkens de juiste kaart oplevert, van de 10-letterige klaveraas (ace of clubs) tot de 15-letterige ruitenvrouw (queen of diamonds). De uitvinder ervan is de Amerikaanse goochelaar Jim Steinmeyer, die hem publiceerde in zijn boek Impuzzibilities1 uit 2002.
Bij het uitvoeren van de truc blijven de kaarten normaal gezien altijd met hun beeldzijde naar onder liggen, behalve bij het onthullen van de laatste kaart. Ter illustratie houden we bij de demonstratie van de truc in onderstaande video alle kaarten met hun beeldzijde naar boven.
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 (String) die bestaat uit de rang van de kaart, gevolgd door de kleur van de kaart:
rang | naam |
---|---|
2 | TWO |
3 | THREE |
4 | FOUR |
5 | FIVE |
6 | SIX |
7 | SEVEN |
8 | EIGHT |
9 | NINE |
10 | TEN |
J | JACK |
Q | QUEEN |
K | KING |
A | ACE |
kleur | naam |
---|---|
♦ | DIAMONDS |
♣ | CLUBS |
♥ | HEARTS |
♠ | SPADES |
Merk op dat de kleur van een kaart altijd voorgesteld wordt door één karakter. Zo stelt A♠ bijvoorbeeld schoppenaas (ace of spades) voor, 10♥ hartentien (ten of hearts) en K♣ klaverenheer (king of clubs).
Definieer een klasse Kaarten waarmee een stapel van nul of meer kaarten kan voorgesteld worden die willekeurig uit een kaartspel getrokken werden. Een stapel hoeft dus niet noodzakelijk alle 52 kaarten van een kaartspel te bevatten, maar elke kaart mag hoogstens één keer voorkomen. Bij het aanmaken van een nieuwe stapel (Kaarten) moeten de stringvoorstellingen van de kaarten in de stapel doorgegeven worden, opgelijst van boven naar onder. Als er minstens één ongeldige kaart wordt doorgegeven of als eenzelfde kaart meerdere keren wordt doorgegeven, dan moet een Error opgeworpen worden met de boodschap ongeldige kaarten. Een stapel kaarten (Kaarten) is onveranderlijk, dus na het aanmaken wijzigt die nooit meer.
Voorts moet je op een stapel $$s$$ (Kaarten) minstens de volgende methoden kunnen aanroepen:
Een methode toString waaraan geen argumenten moeten doorgegeven worden. De methode moet een stringvoorstelling (String) van stapel $$s$$ teruggeven, die leest als een JavaScript expressie waarmee een stapel met dezelfde kaarten kan aangemaakt worden (zonder het sleutelwoord new).
Een methode at met een parameter index. De methode moet een stapel (Kaarten) met één kaart teruggeven die correspondeert met de kaart die zou teruggeven worden bij een reeks (Array) die de kaarten van $$s$$ van boven naar onder oplijst, en waarop de methode at wordt aangeroepen met het argument dat werd doorgegeven aan index. Als dit niet lukt, dan moet een Error opgeworpen worden met de boodschap ongeldige index.
Een methode slice met twee optionele parameters start en end. De methode moet een stapel (Kaarten) teruggeven die correspondeert met de kaarten die zou teruggeven worden bij een reeks (Array) die de kaarten van $$s$$ van boven naar onder oplijst, en waarop de methode slice wordt aangeroepen met de argumenten die doorgegeven worden aan start en end.
Een methode omkeren waaraan geen argumenten moeten
doorgegeven worden. De methode moet een nieuwe stapel (Kaarten)
teruggeven met dezelfde kaarten als in stapel $$s$$, maar in
omgekeerde volgorde.
Een methode splitsen waaraan nul of meer natuurlijke getallen (Number) moeten doorgegeven worden. Als de som van die getallen niet gelijk is aan het aantal kaarten in stapel $$s$$, dan moet een Error opgeworpen worden met de boodschap ongeldige splitsing. Anders moet een reeks (Array) teruggegeven worden met voor elk gegeven natuurlijk getal $$n$$ een stapel (Kaarten) met de volgende $$n$$ kaarten uit stapel $$s$$.
Een methode toverspreuk waaraan geen argumenten moeten doorgegeven worden. Als stapel $$s$$ niet juist negen kaarten bevat, dan moet een Error opgeworpen worden met de boodschap truc werkt enkel met negen kaarten. Anders moet een string (String) teruggegeven worden met een beschrijving van de derde kaart uit stapel $$s$$ (geteld vanaf de bovenkant van de stapel). Die beschrijving leest als RANG OF KLEUR MAGIC, waarbij de cursieve fragmenten respectievelijk moeten ingevuld worden met de (Engelstalige) naam van de rang en de kleur van de derde kaart uit stapel $$s$$.
Een methode delen waaraan een woord $$w$$ (String) moet doorgegeven worden. De methode moet de nieuwe stapel (Kaarten) teruggeven die bekomen wordt na het uitvoeren van één stap van de kaartentruc die begint met stapel $$s$$ en waarbij de letters van woord $$w$$ gespeld worden. Hierbij mag de methode ervan uitgaan dat woord $$w$$ niet langer is dan het aantal kaarten in stapel $$s$$, zonder dat dit expliciet moet gecontroleerd worden.
Een methode magic waaraan geen argumenten moeten doorgegeven worden. De methode moet een nieuwe stapel (Kaarten) teruggeven die enkel bestaat uit de vijfde kaart van stapel $$s$$ (geteld vanaf de bovenkant van de stapel). Hierbij mag de methode ervan uitgaan dat stapel $$s$$ minstens vijf kaarten bevat, zonder dat dit expliciet moet gecontroleerd worden.
> new Kaarten("9♥", "7♥", "6��", "K♥", "7♠") // ongeldige kleur (6��)
Error: ongeldige kaarten
> new Kaarten("8♥", "3♠", "8♥", "8♣", "K♣") // dubbele kaart (8♥)
Error: ongeldige kaarten
> const kaarten = new Kaarten("7♥", "Q♥", "4♠", "5♠", "J♠", "J♦", "7♣", "2♦", "J♥");
> kaarten.toString()
'Kaarten("7♥", "Q♥", "4♠", "5♠", "J♠", "J♦", "7♣", "2♦", "J♥")'
> kaarten.at(2).toString()
'Kaarten("4♠")'
> kaarten.at(-2).toString()
'Kaarten("2♦")'
> kaarten.at(9)
Error: ongeldige index
> kaarten.slice(2, 5).toString()
'Kaarten("4♠", "5♠", "J♠")'
> kaarten.omkeren().toString()
'Kaarten("J♥", "2♦", "7♣", "J♦", "J♠", "5♠", "4♠", "Q♥", "7♥")'
> kaarten.splitsen(3, 3, 3).map(kaarten => kaarten.toString())
['Kaarten("7♥", "Q♥", "4♠")', 'Kaarten("5♠", "J♠", "J♦")', 'Kaarten("7♣", "2♦", "J♥")']
> kaarten.splitsen(3, 5, 1).map(kaarten => kaarten.toString())
['Kaarten("7♥", "Q♥", "4♠")', 'Kaarten("5♠", "J♠", "J♦", "7♣", "2♦")', 'Kaarten("J♥")']
> kaarten.splitsen(3, 4, 5)
Error: ongeldige splitsing
> kaarten.toString()
'Kaarten("7♥", "Q♥", "4♠", "5♠", "J♠", "J♦", "7♣", "2♦", "J♥")'
> kaarten.toverspreuk()
"FOUR OF SPADES MAGIC"
> kaarten.delen("FOUR").toString()
'Kaarten("J♠", "J♦", "7♣", "2♦", "J♥", "5♠", "4♠", "Q♥", "7♥")'
> kaarten.delen("FOUR").delen("OF").toString()
'Kaarten("7♣", "2♦", "J♥", "5♠", "4♠", "Q♥", "7♥", "J♦", "J♠")'
> kaarten.delen("FOUR").delen("OF").delen("SPADES").toString()
'Kaarten("7♥", "J♦", "J♠", "Q♥", "4♠", "5♠", "J♥", "2♦", "7♣")'
> kaarten.delen("FOUR").delen("OF").delen("SPADES").magic().toString()
'Kaarten("4♠")'