Een magische machine bestaat uit glazen bellen die bonen kunnen bevatten. De bellen zijn verbonden door grote drukknoppen.
Als er op een knop gedrukt wordt, dan voert de machine achtereenvolgens de volgende twee acties uit:
Als je bij de machine uit bovenstaande figuur bijvoorbeeld op knop B
zou drukken, dan zal er uit de bovenste bel één boon verdwijnen, en komt er in de onderste bel één boon bij.
Schrijf een klasse Machine
waarvan de objecten magische machines voorstellen die zich gedragen zoals beschreven in de inleiding. Initieel hebben de machines nog geen bellen of knoppen, maar tijdens hun levensduur kunnen er nieuwe bellen en/of knoppen aan toegevoegd worden. Om te kunnen verwijzen naar de bellen en knoppen van een machine krijgen deze elk een eigen label, dat wordt voorgesteld als een string. Voorts moeten objecten van de klasse Machine
minimaal de volgende methoden ondersteunen:
nieuweBel
waarmee een nieuwe bel aan de machine kan toegevoegd worden. Aan de methode moeten twee argumenten doorgegeven worden: i) het label van de bel en ii) het aantal bonen dat zich initieel in de bel bevindt. Indien de machine reeds een bel met het opgegeven label bevat, dan moet de methode een AssertionError
opwerpen met de boodschap bel bestaat reeds
.nieuweKnop
waarmee een nieuwe knop aan de machine kan toegevoegd worden. Aan de methode moeten drie argumenten doorgegeven worden: i) het label van de knop, ii) een array met de labels van de bronbellen van de knop en iii) een array met de labels van de bestemmingsbellen van de knop. Indien de machine reeds een knop met het opgegeven label bevat, dan moet de methode een AssertionError
opwerpen met de boodschap knop bestaat reeds
. Indien de machine geen bel heeft die correspondeert een opgegeven bron- of bestemmingsbel, dan moet de methode een AssertionError
opwerpen met de boodschap onbekende bel
.toString
die een stringvoorstelling van de huidige toestand van de machine teruggeeft. Deze voorstelling bevat een afzonderlijke regel voor elke bel (regels worden van elkaar gescheiden door een newline; \n
) die het label van de bel bevat, gevolgd door een dubbelpunt, een spatie en het aantal bonen in de bel. Hierbij worden de bellen in alfabetische volgorde opgelijst volgens hun label.druk
waarmee achtereenvolgens op één of meerdere knoppen van de machine gedrukt wordt. Aan de methode moet het label van een knop of een array met de labels van de knoppen doorgegeven worden waarop achtereenvolgens gedrukt wordt. Indien de machine geen knop heeft met een label dat correspondeert met een opgegeven knop, dan moet de methode een AssertionError
opwerpen met de boodschap onbekende knop
.In bovenstaande omschrijvingen werd niet expliciet aangegeven dat de methoden nieuweBel
, nieuweKnop
en druk
een waarde moeten teruggeven. Zorg ervoor dat deze methoden een waarde teruggeven zodat de methoden kunnen aaneengeschakeld worden zoals aangegeven in onderstaand voorbeeld.
Gebruik een objectgerichte aanpak om de afzonderlijke componenten van magische machines (bellen en knoppen) te modelleren.
De magische machine die in onderstaande interactieve sessie wordt opgebouwd, komt overeen met de afbeelding uit de inleiding van deze opgave.
> const machine = new Machine()
.. .nieuweBel("1", 0)
.. .nieuweBel("2", 3)
.. .nieuweBel("3", 0)
.. .nieuweKnop("A", ["1", "3"], ["1", "2"])
.. .nieuweKnop("B", ["2"], ["3"])
.. .nieuweKnop("C", ["3"], ["1"]);
> machine.toString();
"1: 0\n2: 3\n3: 0"
> machine.druk("B").toString();
"1: 0\n2: 2\n3: 1"
> machine.druk("B").toString();
"1: 0\n2: 1\n3: 2"
> machine.druk("C").toString();
"1: 1\n2: 1\n3: 1"
> machine.druk(["A", "B", "A"]).toString();
"1: 1\n2: 2\n3: 0"
> machine.nieuweBel("1", 3);
AssertionError: bel bestaat reeds
> machine.nieuweKnop("A", ["2", "3"], ["1", "3"]);
AssertionError: knop bestaat reeds
> machine.nieuweKnop("X", ["1", "2"], ["3", "4"]);
AssertionError: onbekende bel
> machine.druk("Z").toString();
AssertionError: onbekende knop