In het spelletje Dr. Eureka zijn alle spelers assistent-wetenschappers. Ze moeten proberen om sneller dan hun medespelers de gekleurde ballen in de voorgeschreven volgorde in de proefbuizen te krijgen. Daarbij mogen de ballen niet uit de buizen vallen of met de handen aangeraakt worden.

Dr. Eureka
Een speler van het spelletje Dr. Eureka heeft de materialen op de juiste volgorde in de proefbuizen gekregen, zoals voorgeschreven op de opdrachtkaart.

Als alle spelers klaar zijn om eraan te beginnen, wordt de bovenste opdrachtkaart omgedraaid. Dan proberen alle spelers zo snel mogelijk de gekleurde ballen van de ene in de andere buis te krijgen, zodat ze de volgorde krijgen die op de opdrachtkaart staat. Daarbij gelden de volgende regels:

opdracht
Een opdracht kan voltooid worden met alle reageerbuizen rechtopstaand (A) of door één buis omgekeerd neer te zetten (B).

De volgorde van de proefbuizen doet er niet toe (van links naar rechts). Enkel de volgorde van de gekleurde ballen in de proefbuizen (van boven naar onder). Als het helpt mogen de proefbuizen met de hand van plaats verwisseld worden.

Als een speler een bal met de hand raakt, een bal uit een buis laat vallen, of onterecht aankondigt dat de opdracht bereikt werd, dan doet de speler die ronde niet meer mee (dus totdat de anderen deze opdracht af hebben).

Het spel wordt gespeeld met een vast aantal proefbuizen. De proefbuizen hebben een maximale capaciteit die aangeeft hoeveel ballen er maximaal in elke buis passen.

De eerste speler die zijn ballen in de voorgeschreven volgorde in zijn proefbuizen heeft, roept "Eureka!". Als de andere spelers het er mee eens zijn dat hij de opdracht op een correcte manier voltooid heeft, dan krijgt hij de opdrachtkaart die 1 punt waard is.

De spelers laten de ballen in hun proefbuizen zoals ze na de vorige ronde zaten. De ballen worden dus niet opnieuw in een bepaalde startpositie geplaatst. Alle buizen moeten echter rechtop gezet worden voordat een nieuwe opdrachtkaart wordt omgekeerd. Als alle spelers klaar zijn, begint de volgende ronde met het omdraaien van een nieuwe opdrachtkaart. De eerste speler die 5 punten heeft, wint het spel.

Opgave

Definieer een klasse Eureka waarmee kan gesimuleerd worden hoe de spelers van Dr. Eureka de gekleurde ballen over hun proefbuizen kunnen verdelen. Om te kunnen verwijzen naar de verschillende proefbuizen, worden de buizen van links naar rechts genummerd vanaf 0.

Bij het aanmaken van een simulatie (Eureka) moet een string (String) doorgegeven worden die de configuratie van de gekleurde ballen over de verschillende proefbuizen beschrijft. Daarin wordt elke bal voorgesteld als een hoofdletter die de kleur van de bal aangeeft (dezelfde letters stellen ballen met dezelfde kleur voor). Elke proefbuis wordt beschreven door de opeenvolging van de ballen die erin zitten (opgelijst van onder naar boven). De opeenvolgende proefbuizen worden telkens van elkaar gescheiden door een komma (,). Zo stelt PG,GR,PR bijvoorbeeld de configuratie van drie proefbuizen voor die te zien is in de eerste afbeelding in de inleiding, waarbij de hoofdletter P een paarse bal voorstelt, G een groene bal en R een rode bal.

Bij het aanmaken van een simulatie (Eureka) kan optioneel nog een tweede argument doorgegeven worden: een Object waarmee bijkomende eigenschappen kunnen ingesteld worden. Als deze eigenschappen niet ingesteld worden, dan vallen ze terug op een standaardwaarde:

Daarnaast moet je op een simulatie $$s$$ (Eureka) minstens de volgende methoden kunnen aanroepen:

Voorbeeld

> const spel = new Eureka("RPG,G,PR")
> console.log(spel.toString())
= = = = = =
| | | | | |
|G| | | | |
|P| | | |R|
|R| |G| |P|
=== === ===
> console.log(spel.verplaatsen(0, 1, 1).toString())
= = = = = =
| | | | | |
| | | | | |
|P| |G| |R|
|R| |G| |P|
=== === ===
> console.log(spel.verplaatsen(1, 2, 2).toString())
= = = = = =
| | | | |G|
| | | | |G|
|P| | | |R|
|R| | | |P|
=== === ===
> console.log(spel.verplaatsen(0, 1, 1).toString())
= = = = = =
| | | | |G|
| | | | |G|
| | | | |R|
|R| |P| |P|
=== === ===
> console.log(spel.verplaatsen(2, 1, 1).verplaatsen(2, 0, 1).toString())
= = = = = =
| | | | | |
| | | | | |
|G| |G| |R|
|R| |P| |P|
=== === ===
> console.log(spel.omkeren(2).toString())
= = = = ===
| | | | | |
| | | | | |
|G| |G| |P|
|R| |P| |R|
=== === = =
> spel.equals(new Eureka("RP,RG,PG"))
true
> spel.equals(new Eureka("PR,RG,PG"))
false

> spel.omkeren(100)               // verkeerde positie van buis
Error: ongeldige zet
> spel.omkeren(0)                 // er is al een buis omgekeerd
Error: ongeldige zet
> spel.verplaatsen(0, 1)          // er is een buis omgekeerd
Error: ongeldige zet

> console.log(spel.omkeren(2).toString())
= = = = = =
| | | | | |
| | | | | |
|G| |G| |R|
|R| |P| |P|
=== === ===
> spel.verplaatsen(0, 100)        // verkeerde positie van buis
Error: ongeldige zet
> spel.verplaatsen(100, 0)        // verkeerde positie van buis
Error: ongeldige zet
> spel.verplaatsen(0, 0)          // buis kan je niet in zichzelf overgieten
Error: ongeldige zet
> console.log(spel.verplaatsen(0, 1).toString())
= = = = = =
| | |R| | |
| | |G| | |
| | |G| |R|
| | |P| |P|
=== === ===
> spel.verplaatsen(2, 1)          // buis 1 zit al vol
Error: ongeldige zet
> console.log(spel.verplaatsen(0, 1).toString())
= = = = = =
| | |R| | |
| | |G| | |
| | |G| |R|
| | |P| |P|
=== === ===