Een schuifpuzzel bestaat uit een rechthoekig bord van $$m$$ rijen en $$n$$ kolommen, waarbij één van de velden leeg blijft. Puzzelstukken op horizontaal of verticaal aangrenzende velden kunnen naar dit lege veld geschoven worden. Hierdoor verschuift in essentie het lege veld, vandaar de naam van de puzzel. De eerste schuifpuzzel werd uitgevonden door Noyes Chapman en ontketende in 1880 een echte puzzelgekte.
Bij verschillende varianten van de schuifpuzzel worden puzzelstukken gemarkeerd met getallen, letters of stukjes van een afbeelding. Het spel bestaat er dan in om de puzzelstukken eerst een groot aantal keer te verschuiven, zodat ze in een schijnbaar willekeurige volgorde op het bord staan, en daarna te proberen om de stukken terug in de oorspronkelijke volgorde op het bord te schuiven.
Definieer een klasse Schuifpuzzel waarmee schuifpuzzels kunnen voorgesteld worden, waarvan de puzzelstukken gemarkeerd zijn met ASCII karakters. Deze klasse moet volgende methoden implementeren:
Een initialisatiemethode __init__ waaraan drie argumenten moeten meegegeven worden: i) het aantal rijen $$m$$, ii) het aantal kolommen $$n$$ en iii) een string. De puzzelstukken van de schuifpuzzel moeten van links naar rechts, en van boven naar onder gemarkeerd worden met de opeenvolgende karakters van de gegeven string. Deze string moet dus juist evenveel karakters tellen als het aantal velden van de schuifpuzzel, en er moet juist één spatie in voorkomen die de positie van het lege veld aangeeft. De initialisatiemethode moet een AssertionError met de tekst ongeldige configuratie opwerpen indien niet aan deze voorwaarden voldaan is. Het spelbord moet ook minstens drie rijen en kolommen tellen, en de initialisatiemethode moet een AssertionError met de tekst puzzel moet minstens drie rijen en kolommen hebben opwerpen als dat niet het geval is.
Een methode __str__ waarmee een stringvoorstelling van de huidige toestand van de schuifpuzzel kan uitgeschreven worden. Deze stringvoorstelling bestaat uit $$m$$ regels, waarbij op elke regel de $$n$$ karakters die de puzzelstukken markeren achter elkaar uitgeschreven worden. Deze stringvoorstelling eindigt zelf niet op een newline.
Een methode __repr__ waarmee een stringvoorstelling van de huidige toestand van de schuifpuzzel kan uitgeschreven worden. Deze stringvoorstelling leest als een Python expressie die een nieuw object aanmaakt van de klasse Schuifpuzzel dat dezelfde toestand heeft.
Een methode schuif waarmee het lege veld van de schuifpuzzel achtereenvolgens over een aantal gegeven richtingen verschoven wordt. De mogelijke richtingen zijn links (L), rechts (R), op (O) en neer (N) en geven aan in welke richting het lege veld verschoven wordt, en dus niet de richting waarin een aangrenzend puzzelstuk naar het lege veld geschoven wordt. Aan deze methode moet een string doorgegeven worden, die enkel bestaat uit de letters L, R, O en N. Op basis van deze richtingen moet de methode achtereenvolgens de corresponderende schuifbewegingen van het lege veld doorvoeren. Van zodra een ongeldige schuifbeweging moet uitgevoerd worden, moet de methode een AssertionError met de tekst ongeldige richting opwerpen. Voorgaande (geldige) schuifbewegingen moeten echter wel uitgevoerd worden.
Onderstaand voorbeeld toont hoe je een $$4 \times 4$$ schuifpuzzel waarvan de letters initieel lezen als pikante loketten, over een aantal schuifbeurten kunt omvormen tot een puzzel waarvan de letters het woord platentektoniek spellen.
>>> puzzel = Schuifpuzzel(4, 4, 'pikante loketten'); print(puzzel)
pika
nte
loke
tten
>>> puzzel.schuif('L'); print(puzzel)
pika
nt e
loke
tten
>>> puzzel.schuif('LL'); print(puzzel)
pika
nte
loke
tten
>>> puzzel.schuif('L')
Traceback (most recent call last):
AssertionError: ongeldige richting: L
>>> puzzel.schuif('ORRRNLLLORNNLOORRRNLLNNLORNROOOLNRRNLLLORRNRN'); print(puzzel)
plat
ente
kton
iek
>>> puzzel
Schuifpuzzel(4, 4, 'platentektoniek ')
>>> puzzel = Schuifpuzzel(2, 2, "AOJN")
Traceback (most recent call last):
AssertionError: puzzel moet minstens 3 rijen en kolommen hebben
>>> puzzel = Schuifpuzzel(4, 4, "AOJNDH")
Traceback (most recent call last):
AssertionError: ongeldige configuratie
>>> puzzel = Schuifpuzzel(4, 4, "OEKBFJOZKSOLDFKE")
Traceback (most recent call last):
AssertionError: ongeldige configuratie
Hieronder zie je de grafische voorstelling van deze schuifpuzzel.
Omdat we het niet kunnen laten, staan hieronder nog enkele voorbeelden van schuifpuzzels die in een aantal schuifbeurten wartaal (of toch niet?) omzetten in een herkenbaar woord.
>>> puzzel = Schuifpuzzel(3, 6, 'tardwean schpeaper')
>>> puzzel.schuif('LRLNLRROLNLORLNOORNRLRNRLLRRONRR')
>>> print(puzzel)
aardwe
tensch
apper
>>> puzzel = Schuifpuzzel(7, 3, 'catal uteitsiripcinpe')
>>> puzzel.schuif('LONOLNNNONNNOONNRLNRRLRLR')
>>> print(puzzel)
act
ual
ite
its
pri
nci
pe
>>> puzzel = Schuifpuzzel(4, 4, 'migraine toestel')
>>> puzzel.schuif('RROOLNNROORNNLNROLLLNRROLLORORRNLNLLNROOORNRNLNR')
>>> puzzel
Schuifpuzzel(4, 4, 'meteorietinslag ')
>>> puzzel = Schuifpuzzel(4, 4, 'eenstemmig opaal')
>>> puzzel.schuif('LLORORNRNNLOOROLNRNNLLORNLOLORRNLLNROOLNROOLNRROLNRROLNRNNLLLOORRRNN')
>>> puzzel
Schuifpuzzel(4, 4, 'paleomagnetisme ')