Kasper — het huisspook — heeft in de ruïnes van de burcht een oud fototoestel gevonden. Daarmee heeft hij alles vastgelegd wat hij bij het rondspoken graag laat verdwijnen … en hij wil zelf ook wel eens in het niets oplossen! Maar er is iets vreemd aan de hand met de foto's: gek genoeg blijken de voorwerpen vaak de verkeerde kleur te hebben. Soms is de groene fles wit, dan weer blauw. De foto's zijn zo verwarrend dat hij niet meer weet wat hij moet wegtoveren. Wie kan het juiste voorwerp noemen en laten verdwijnen?

Geesten staan centraal in het gezelschapsspel vlotte geesten, maar het is vooral ook een spel voor de vlotte geest. Het wordt gespeeld met 2 tot 8 spelers (vanaf 8 jaar), 5 fysieke voorwerpen en 60 speelkaarten (die foto's van de voorwerpen voorstellen). Elk voorwerp heeft twee unieke eigenschappen: een unieke kleur en een unieke vorm. Er is een rode stoel, een blauw boek, een groene fles, een grijze muis en een wit spook.

Elke speelkaart bevat de weergave van 2 voorwerpen. Een voorwerp op een speelkaart heeft niet noodzakelijk dezelfde kleur als het corresponderende fysieke voorwerp.

Bij aanvang van het spel worden de 5 fysieke voorwerpen op tafel gezet, zodat alle spelers er goed bij kunnen. De speelkaarten worden geschud en als een gedekte stapel op tafel gelegd. De startspeler (bijvoorbeeld de jongste speler of de speler die het laatst in een burcht of kasteel geweest is) draait de bovenste speelkaart zodanig om dat alle spelers de kaart tegelijkertijd zien. Iedere speler probeert nu zo snel mogelijk het fysieke voorwerp van tafel te grijpen dat op deze speelkaart in de juiste kleur is afgebeeld. Voor de speelkaarten hieronder zijn dat respectievelijk het blauwe boek (links), de grijze muis (midden) en de groene fles (rechts).

Als geen van de twee voorwerpen op de speelkaart in de juiste kleur is afgebeeld, dan moeten de spelers het fysieke voorwerp van tafel grijpen dat qua vorm niet op de kaart is afgebeeld en waarvan de kleur ook niet op de kaart te zien is. De linker speelkaart hieronder toont bijvoorbeeld een blauw spook en een grijze stoel. Deze fysieke voorwerpen staan niet als dusdanig op tafel. Daarom moeten de spelers de groene fles grijpen, omdat zowel de fles als de kleur groen niet op de speelkaart te zien zijn. Om dezelfde reden moeten de spelers ook voor de rechter speelkaart hieronder de groene fles grijpen.

Wie als eerste het juiste fysieke voorwerp op tafel heeft gegrepen, legt als beloning de omgedraaide kaart voor zich op tafel en draait daarna de volgende kaart van de gedekte stapel om.
Per ronde mag een speler niet meer dan 1 voorwerp grijpen. Wie een verkeerd voorwerp heeft gegrepen, moet 1 van zijn kaarten (voor zover hij die heeft) aan de winnaar van de ronde geven. Het is dus goed mogelijk dat de winnaar van de ronde naast de omgedraaide kaart nog meer kaarten wint.
Het spel is afgelopen als de gedekte stapel kaarten is opgebruikt. De speler die de meeste kaarten voor zich heeft, is de winnaar.
Definieer een klasse Voorwerp waarmee voorwerpen met een bepaalde kleur en een bepaalde vorm kunnen voorgesteld worden. Bij het aanmaken van een nieuw voorwerp (Voorwerp) moeten twee strings (String) doorgegeven worden die resp. de kleur en de vorm van het voorwerp beschrijven. Als er geen twee strings doorgegeven worden, dan moet een Error met boodschap ongeldig voorwerp opgeworpen worden.
Op elk voorwerp $$v$$ (Voorwerp) moet je een methode toString kunnen aanroepen (zonder argumenten), die een string (String) teruggeeft met een JavaScript-expressie om een nieuw voorwerp (Voorwerp) aan te maken met dezelfde kleur en dezelfde vorm als voorwerp $$v$$. Het juiste formaat van die expressie kan je bepalen op basis van onderstaande voorbeelden.
Definieer een klasse Collectie waarmee collecties met unieke voorwerpen kunnen voorgesteld worden. Deze uniciteit moet zowel gelden voor de voorwerpen als geheel, als voor hun individuele eigenschappen. Het is dus niet toegelaten dat de collectie twee identieke voorwerpen bevat, of twee voorwerpen met dezelfde eigenschap (dezelfde kleur of dezelfde vorm). De collectie mag ook geen objecten bevatten die geen voorwerp voorstellen. Bij het aanmaken van een nieuwe collectie (Collectie) moeten de voorwerpen (Voorwerp; nul of meer) doorgegeven worden die deel uitmaken van de collectie. Als minstens één van de argumenten geen voorwerp (Voorwerp) is of als de uniciteit niet geldt voor de voorwerpen die deel uitmaken van de collectie, dan moet een Error met boodschap ongeldige collectie opgeworpen worden.
Een collectie $$c$$ moet minstens de volgende getters (of objecteigenschappen) ondersteunen:
een getter aantal die het aantal voorwerpen (Number) teruggeeft die deel uitmaken van collectie $$c$$
een getter kleuren die een verzameling (Set) teruggeeft met alle kleuren (String) van de voorwerpen die deel uitmaken van collectie $$c$$
een getter vormen die een verzameling (Set) teruggeeft met alle vormen (String) van de voorwerpen die deel uitmaken van collectie $$c$$
Op elke collectie $$c$$ (Collectie) moet je een methode toString kunnen aanroepen (zonder argumenten), die een string (String) teruggeeft met een JavaScript-expressie om een nieuwe collectie (Collectie) aan te maken met dezelfde voorwerpen (Voorwerp) die deel uitmaken van collectie $$c$$ (in dezelfde volgorde). Het juiste formaat van die expressie kan je bepalen op basis van onderstaande voorbeelden.
Definieer een klasse Kaart waarmee speelkaarten uit een spelletje vlotte geesten kunnen voorgesteld worden. Een speelkaart (Kaart) is een collectie (Collectie) met twee voorwerpen (Voorwerp). Dit betekent dat een speelkaart (Kaart) zich gedraagt als een collectie (Collectie) — en dus dezelfde getters en methoden ondersteunt — met dat verschil dat:
er een Error met boodschap ongeldige kaart (in plaats van ongeldige collectie) opgeworpen wordt als de speelkaart geen geldige collectie is
er een Error met boodschap ongeldige kaart opgeworpen wordt als de speelkaart geen collectie met 2 voorwerpen is
de methode toString een string (String) teruggeeft met een JavaScript-expressie om een nieuwe speelkaart (Kaart) aan te maken, in plaats van een nieuwe collectie (Collectie)
Definieer een klasse Tafel waarmee de vijf fysieke voorwerpen op tafel kunnen voorgesteld worden bij een spelletje vlotte geesten. Deze voorwerpen mogen verschillend zijn van de originele voorwerpen uit het spelletje vlotte geesten: er mag bijvoorbeeld een blauw spook of een roze flamingo op tafel staan. Een tafel (Tafel) is een collectie (Collectie) met vijf voorwerpen (Voorwerp). Dit betekent dat een tafel (Tafel) zich gedraagt als een collectie (Collectie) — en dus dezelfde getters en methoden ondersteunt — met dat verschil dat:
er een Error met boodschap ongeldige tafel (in plaats van ongeldige collectie) opgeworpen wordt als de tafel geen geldige collectie is
er een Error met boodschap ongeldige tafel opgeworpen wordt als de tafel geen collectie met 5 voorwerpen is
de methode toString een string (String) teruggeeft met een JavaScript-expressie om een nieuwe tafel (Tafel) aan te maken, in plaats van een nieuwe collectie (Collectie)
Daarnaast moet je op een tafel $$t$$ (Tafel) ook nog een methode grijp kunnen aanroepen waaraan een speelkaart $$k$$ (Kaart) moet doorgegeven worden. Daarbij moet gelden dat:
de vorm van elk voorwerp op speelkaart $$k$$ correspondeert met de vorm van een fysiek voorwerp op tafel $$t$$
de kleur van elk voorwerp op speelkaart $$k$$ correspondeert met de kleur van een fysiek voorwerp op tafel $$t$$
juist één van deze twee voorwaarden is voldaan
juist één fysiek voorwerp op tafel $$t$$ correspondeert qua vorm én qua kleur met een voorwerp op speelkaart $$k$$
juist één fysiek voorwerp op tafel $$t$$ heeft een vorm en een kleur die niet voorkomt op speelkaart $$k$$
Als het argument dat aan de methode grijp wordt doorgegeven geen speelkaart (Kaart) is of als bovenstaande voorwaarden niet gelden voor speelkaart $$k$$, dan moet een Error met boodschap ongeldige kaart opgeworpen worden. Anders moet de methode het voorwerp (Voorwerp) teruggeven dat je volgens kaart $$k$$ van tafel $$t$$ moet grijpen volgens de regels van het spelletje vlotte geesten: dat is het voorwerp waarvoor de laatste voorwaarde hierboven voldaan is.
> const voorwerp = new Voorwerp("blauw", "boek")
> voorwerp.toString()
'new Voorwerp("blauw", "boek")'
> new Voorwerp(666, "stoel")
Error: ongeldig voorwerp
> new Voorwerp("spook", "pompoen", "paars", "vuil")
Error: ongeldig voorwerp
> const collectie = new Collectie(new Voorwerp("rood", "stoel"), new Voorwerp("blauw", "boek"), new Voorwerp("groen", "fles"))
> collectie.aantal
3
> collectie.kleuren
new Set(["rood", "blauw", "groen"])
> collectie.vormen
new Set(["stoel", "boek", "fles"])
> collectie.toString()
'new Collectie(new Voorwerp("rood", "stoel"), new Voorwerp("blauw", "boek"), new Voorwerp("groen", "fles"))'
> new Collectie(new Voorwerp("paars", "druif"), new Voorwerp("paars", "koe"), new Voorwerp("blauw", "boek"))
> Error: ongeldige collectie
> const kaart = new Kaart(new Voorwerp("blauw", "boek"), new Voorwerp("groen", "stoel"))
> kaart.aantal
2
> kaart.kleuren
new Set(["blauw", "groen"])
> kaart.vormen
new Set(["boek", "stoel"])
> kaart.toString()
'new Kaart(new Voorwerp("blauw", "boek"), new Voorwerp("groen", "stoel"))'
> new Kaart(new Voorwerp("groen", "fles"), new Voorwerp("groen", "muis"))
Error: ongeldige kaart
> new Kaart(new Voorwerp("wit", "spook"), new Voorwerp("grijs", "muis"), new Voorwerp("bruin", "koe"))
Error: ongeldige kaart
> const tafel = new Tafel(new Voorwerp("rood", "stoel"), new Voorwerp("blauw", "boek"), new Voorwerp("groen", "fles"), new Voorwerp("grijs", "muis"), new Voorwerp("wit", "spook"))
> tafel.aantal
5
> tafel.kleuren
new Set(["rood", "blauw", "groen", "grijs", "wit"])
> tafel.vormen
new Set(["stoel", "boek", "fles", "muis", "spook"])
> tafel.toString()
'new Tafel(new Voorwerp("rood", "stoel"), new Voorwerp("blauw", "boek"), new Voorwerp("groen", "fles"), new Voorwerp("grijs", "muis"), new Voorwerp("wit", "spook"))'
> new Tafel(new Voorwerp("oranje", "pompoen"), new Voorwerp("roze", "flamingo"), new Voorwerp("bruin", "koe"), new Voorwerp("geel", "banaan"))
Error: ongeldige tafel
> new Tafel(new Voorwerp("paars", "druif"), new Voorwerp("wit", "spook"), new Voorwerp("bruin", "koe"), new Voorwerp("bruin", "fles"), new Voorwerp("blauw", "boek"))
Error: ongeldige tafel
> tafel.grijp(kaart).toString()
'new Voorwerp("blauw", "boek")'
> tafel.grijp(new Kaart(new Voorwerp("blauw", "spook"), new Voorwerp("grijs", "stoel"))).toString()
'new Voorwerp("groen", "fles")'
> tafel.grijp(new Kaart(new Voorwerp("paars", "spook"), new Voorwerp("wit", "druif")))
Error: ongeldige kaart