Het spelletje "∞ lus" wordt gespeeld met $$m \times n$$ tegels, gerangschikt in een $$m \times n$$ rooster met $$m$$ rijen en $$n$$ kolommen. Er zijn in totaal 16 verschillende tegelconfiguraties:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
╹ | ╺ | ┗ | ╻ | ┃ | ┏ | ┣ | ╸ | ┛ | ━ | ┻ | ┓ | ┫ | ┳ | ╋ |
Elke tegel kan met andere woorden aansluitingen hebben naar boven, naar rechts, naar beneden, en naar links. De tegelconfiguraties worden gevormd door alle mogelijke combinaties van aansluitingen in deze vier richtingen, inclusief de tegel zonder aansluitingen.
Bij aanvang van het spel wordt het rooster gevuld met een selectie van tegels. De speler kiest vervolgens een tegel, en draait die 90° in wijzerzin of tegenwijzerzin. Als we bijvoorbeeld tegel ┣ in wijzerin draaien dan bekomen we tegel ┳, tegel ┛ wordt ┗, maar tegel ╋ blijft ╋. De speler kan deze procedure eindeloos blijven herhalen.
Het doel van het spel is om gesloten circuits te vormen: elke aansluiting moet connecteren op een aansluiting van de naburige tegel langs dezelfde zijde. Als een tegel bijvoorbeeld een aansluiting naar rechts heeft, dan moet de tegel rechts daarvan in het rooster een aansluiting naar links hebben. Bij wijze van illustratie toont onderstaand videofragment een speler die puzzels uit het spelletje "∞ lus" probeert op te lossen.
Een eenvoudige manier om de tegels voor te stellen — zonder gebruik te moeten maken van Unicode-karakters — is door gebruik te maken van een bitmasktechniek. Hierbij wordt elke tegel voorgesteld als een natuurlijk getal uit het interval $$[0, 15]$$ door gebruik te maken van de volgende code:
begin met 0
als de tegel een aansluiting naar boven heeft, tel er dan 1 bij op
als de tegel een aansluiting naar rechts heeft, tel er dan 2 bij op
als de tegel een aansluiting naar onder heeft, tel er dan 4 bij op
als de tegel een aansluiting naar links heeft, tel er dan 8 bij op
Grafisch ziet dat er als volgt uit:
Op die manier kan de tegel ┫ voorgesteld worden als het getal $$1 + 4 + 8 = 13$$. Als we de binaire voorstelling van het getal bekijken, dan zien we dat
het eerste cijfer vanaf rechts aangeeft of de tegel een aansluiting naar boven heeft
het tweede cijfer vanaf rechts aangeeft of de tegel een aansluiting naar rechts heeft
het derde cijfer vanaf rechts aangeeft of de tegel een aansluiting naar onder heeft
het vierde cijfer vanaf rechts aangeeft of de tegel een aansluiting naar links heeft
Zo komt 13 overeen met het binaire getal 1101, waaruit we direct kunnen afleiden dat de tegel aansluitingen heeft naar alle richtingen behalve naar rechts.
Definieer een klasse Tegel waarmee tegels uit het spelletje "∞ lus" kunnen voorgesteld worden. Bij het aanmaken van een nieuwe tegel (Tegel) kan een natuurlijk getal (Number; standaardwaarde: 0) doorgegeven worden, dat de tegel beschrijft op basis van de bitmasktechniek die hierboven werd beschreven. Als het gegeven getal niet in het interval $$[0, 15]$$ ligt, dan moet een Error opgeworpen worden met de boodschap ongeldige tegel.
Een tegel $$t$$ (Tegel) moet minstens de volgende eigenschappen hebben:
boven: Booleaanse waarde (Boolean) die aangeeft of tegel $$t$$ een aansluiting naar boven heeft
rechts: Booleaanse waarde (Boolean) die aangeeft of tegel $$t$$ een aansluiting naar rechts heeft
onder: Booleaanse waarde (Boolean) die aangeeft of tegel $$t$$ een aansluiting naar onder heeft
links: Booleaanse waarde (Boolean) die aangeeft of tegel $$t$$ een aansluiting naar links heeft
Daarnaast moet je op een tegel $$t$$ (Tegel) minstens de volgende methoden kunnen aanroepen:
Een methode toString die een stringvoorstelling (String) van tegel $$t$$ teruggeeft. Die stringvoorstelling bestaat uit het Unicode-karakter op de positie in de tabel uit de inleiding van deze opgave die overeenkomt met de voorstelling van tegel $$t$$ als natuurlijk getal.
Een methode draai waaraan een Booleaanse waarde (Boolean) kan doorgegeven worden (standaardwaarde: true). Als de waarde true wordt doorgegeven, dan moet tegel $$t$$ 90° in wijzerzin gedraaid worden. Anders moet de tegel $$t$$ 90° in tegenwijzerzin gedraaid worden. De methode moet een verwijzing naar tegel $$t$$ teruggeven.
Definieer ook nog een klasse OneindigeLus waarmee een puzzel van het spelletje "∞ lus" kan voorgesteld worden. Bij het aanmaken van een nieuwe puzzel (OneindigeLus) moeten twee argumenten doorgegeven worden: i) een reeks (Array) met natuurlijke getallen (Number) uit het interval $$[0, 15]$$ die de tegels in het rooster voorstellen, uitgelezen in de leesrichting (van links naar rechts en van boven naar onder), en ii) een natuurlijk getal (Number) dat aangeeft hoeveel kolommen het rooster telt. Als deze argumenten niet corresponderen met een geldig rooster van tegels, dan moet een Error opgeworpen worden met de boodschap ongeldig rooster.
Op een puzzel $$p$$ (OneindigeLus) moet je minstens de volgende methoden kunnen aanroepen:
Een methode toString die een stringvoorstelling (String) van het rooster met tegels van puzzel $$p$$ teruggeeft. Daarin vormt elke rij een afzonderlijke regel (opgelijst van boven naar onder), en worden de tegels op een rij voorgesteld door hun Unicode-karakter (opgelijst van links naar rechts).
Een methode draai waaraan het rijnummer (Number) en het kolomnummer (Number) van een cel uit het rooster van puzzel $$p$$ moeten doorgegeven worden. Hierbij worden de rijen van boven naar onder genummerd, en de kolommen van links naar rechts, telkens vanaf 0. Bovendien kan als derde argument ook nog een Booleaanse waarde (Boolean) doorgegeven worden (standaardwaarde: true). Als het rij- en kolomnummer geen geldige positie van een tegel in het rooster van puzzel $$p$$ aanwijzen, dan moet een Error opgeworpen worden met de boodschap ongeldige positie. Anders moet de tegel op de aangegeven positie in het rooster van puzzel $$p$$ 90° gedraaid worden: in wijzerzin als de de derde parameter de waarde true heeft of anders in tegenwijzerzin. De methode moet een verwijzing naar puzzel $$p$$ teruggeven.
Een methode opgelost waaraan geen argumenten moeten doorgegeven worden. De methode moet een Booleaanse waarde (Boolean) teruggeven, die aangeeft of de tegels in het rooster gesloten circuits vormen. Dat is het geval als elke aansluiting connecteert op een aansluiting van de naburige tegel langs dezelfde zijde.
>>> const tegel = new Tegel(11)
>>> tegel.boven
true
>>> tegel.rechts
true
>>> tegel.onder
false
>>> tegel.links
true
>>> tegel.toString()
"┻"
>>> tegel.draai().toString()
"┣"
>>> tegel.draai().draai().toString()
"┫"
>>> tegel.draai(false).toString()
"┳"
>>> tegel.draai(false).draai(false).toString()
"┻"
>>> const spel = new OneindigeLus([9, 12, 12, 6, 10, 13, 13, 5, 3, 3, 9, 3], 4)
>>> console.log(spel.toString())
┛┓┓┏
━┫┫┃
┗┗┛┗
>>> spel.opgelost()
false
>>> console.log(spel.draai(0, 0).draai(0, 0).draai(0, 2, false).draai(0, 3).toString())
┏┓┏┓
━┫┫┃
┗┗┛┗
>>> spel.opgelost()
false
>>> console.log(spel.draai(1, 0).draai(1, 1).draai(1, 1).toString())
┏┓┏┓
┃┣┫┃
┗┗┛┗
>>> spel.opgelost()
false
>>> console.loo(spel.draai(2, 1, false).draai(2, 2).draai(2, 3, false).toString())
┏┓┏┓
┃┣┫┃
┗┛┗┛
>>> spel.opgelost()
true