Sudoku

Von Sinclair Basic nach Mallard Basic


In den vergangenen Monaten ist eine neue Sorte Rätsel in Mode gekommen: fast jede Zeitung und Zeitschrift druckt regelmäßig Sudokus ab. Auch in der Computerwelt gibt es einen Nachhall dieses Trends. Nicht nur unter dem weitverbreiteten Windows (zum Beispiel in Excel) gibt es Programme zum Lösen oder zum Erstellen solcher Zahlenrätsel, auch die treuen Anhänger der Homecomputer aus der 8-bit-Zeit sehen hier eine Herausforderung an ihre Programmierfertigkeit.

Auf dem Commodore Plus/4 hat Werner Bertholdt ein Programm vorgestellt, das Sudokus auch höheren Schwierigkeitsgrades löst. Auf dem Amstrad CPC ist Elliot mit der Fertigstellung von "Sudoku Master" beschäftigt und auch bei ANDRE***s ZX81-Programmen ist im Oktober 2006 Sudoku aufgetaucht.

Wie sieht es mit unserem JOYCE aus? Geschrieben hat wohl noch niemand so ein Programm, aber muß man unbedingt das Rad neu erfinden oder kann man Bestehendes nachnutzen? Das Plus/4-Programm gefällt mir sehr gut, ich hätte es gern für den PCW umgeschrieben, aber es ist kompiliertes Basic (was immer noch langsam genug arbeitet, doch wir 8-bit-Freunde sind ja nicht der Hektik verfallen). Somit läßt es sich nicht mehr listen und damit auch nicht von Token- in Textform verwandeln.

André Baune aus Kanada ist ein besonders enthusiastischer Anhänger von Sir Clive Sinclairs "Türstopper", er veröffentlicht seit März 2004 jeden Monat ein Programm, das er selbst geschrieben oder von anderen übernommen und optimiert hat. Er zeigt dabei, daß er die Eigenheiten des Sinclair Basic bis zur Grenze des Möglichen auszunutzen versteht. Oft mag man nicht glauben, daß kein Maschinencode verwendet wird und solch flüssiger Programmablauf mit aufwendiger Grafik (bis hin zu trickfilmartigen Sequenzen) in maximal 16 kByte Basic untergebracht wurden.

Ursprünglich wollte ANDRE*** (so sein "Künstlername") mit dieser www-Offensive das 25jährige Jubiläum des ZX81 (11. März 2006) würdigen und er krönte das Projekt mit einer phantastischen Variante von Puzznic, aber die Resonanz bewog ihn offenbar, seine Aktion fortzusetzen. Nach einer zusammenhängenden Serie von fünf Spielhallenklassikern überraschte er im Oktober mit einer überarbeiteten Version von Stafford Whites Sudoku.

Dieses Programm löst zwar kein Rätsel wie das Plus/4-Programm, aber es unterstützt beim Lösen, indem es für jedes Feld die noch in Frage kommenden Ziffern anzeigt, also Spalte, Zeile und Neunerfeld auswertet. Von Jack Raats gibt es ein Programm (ZX81LIST.EXE), das auf dem IBM-Kompatiblen aus Sinclair-Token ASCII-Listings erzeugt. Mit meinem Faible für BasiCode hätte ich das Programm natürlich am liebsten in dieses "Computer-Esperanto" umgesetzt, doch dann hätte ich zum Beispiel das inverse Ausgeben von Zeichen nicht (jedenfalls nicht hardware-unabhängig) nutzen können. Also machte ich mich daran, von der Textfassung ausgehend das Programm auf den JOYCE zu transferieren. Hierbei gab es einige Dinge auszuknobeln, die vielleicht auch für andere Joycer interessant sind.


Abspeichern einschließlich Variablen

Eine Besonderheit des Basic des ZX81 ist, daß beim Abspeichern eines Programms alle in diesem Moment bestehenden Variablen mit abgespeichert werden, nach dem Laden des Programms also ebenfalls sofort wieder zur Verfügung stehen. Das schließt übrigens den Bildschirminhalt mit ein, der auf dem ZX81 auch als eine Variable wie jede andere behandelt wird. Interessanterweise ist kein fester Platz für den Bildschirm reserviert: Ein leerer Bildschirm verbraucht weniger RAM als ein mit Text gefüllter.

 

ANDRE*** nutzt das aus, um seinen Programmen ein einheitliches Erscheinungsbild zu geben. Jedes enthält eine Zeile 9990, die den SAVE-Befehl beinhaltet und auf dem ohnehin beim Laden wieder auftauchenden Bildschirm gleichzeitig eine kleine Werbeanzeige enthält, dazu einen Hinweis, wie das Programm zu starten und wie abzuspeichern ist. Um Variablen mitzuspeichern, mußte auf dem JOYCE ein höherer Aufwand getrieben werden, auch hier steht eine Beispiel-Belegung zum sofortigen Spielen zur Verfügung.


Dimensionierung von Stringvariablen

DIM A$(4,14) bedeutet auf dem ZX81, daß Speicherplatz für vier Zeichenkettenvariablen von jeweils genau vierzehn Zeichen Länge reserviert wird. Übrigens muß jede Variable vor ihrer ersten Verwendung initialisiert worden sein. Auf dem JOYCE genügt hier DIM A$(4), was nur die Anzahl vorgibt und die Länge nicht einschränkt.
DIM A$(4,14) würde hier das Anlegen eines Zeichenkettenfeldes in den Dimensionen 4 und 14 (oder 5 und 15 bei OPTION BASE 0) bedeuten.


Teil-Zeichenketten

Auf dem ZX81 gibt es die Funktionen LEFT$, MID$ und RIGHT$ nicht unter diesen Namen. Um beispielsweise aus der Zeichenkette A$(3)="SINCLAIR" das C herauszulösen (wofür in Mallard Basic MID$(A$(3),4,1) verwendet würde) gibt es im Sinclair Basic folgende möglichen Schreibweisen: A$(3,4 TO 4), A$(3)(4 TO 4) oder A$(3,4). Vor allem die letzte, kürzeste, Schreibweise birgt Verwechslungsgefahr: es ist ein Teil eines eindimensionalen Zeichenkettenfeldes und nicht eine Zeichenkette aus einem zweidimensionalen Zeichenkettenfeld.


Manipulation von Zeichenketten

Eng verwandt mit dem Vorigen ist das Ändern von Zeichenketten. Um den Rechtschreibfehler in B$="SYNCLAIR" zu korrigieren, schreiben wir auf dem JOYCE MID$(B$,2,1)="I", wonach B$ den INHALT "SINCLAIR" hat. Auf dem ZX81 muß eingegeben werden: LET B$(2 TO 2)="I" oder kürzer: LET B$(2)="I". Der Befehl LET zur Variablenzuweisung darf nicht (wie bei fast allen anderen Basic-Dialekten) weggelassen werden. Der Befehl in der kürzeren Schreibweise ist also wieder keine Zuweisung eines Werts zu einer eindimensionalen Stringvariablen, sondern der Austausch eines Teils einer Zeichenkette.


Cursorpositionierung

Um etwas auf eine bestimmte Position des Bildschirms auszugeben, müssen wir unter Mallard Basic mit ESC-Sequenzen hantieren, Sinclair Basic kennt bereits PRINT AT.


Wahr und Falsch

Einer falschen Aussage wird auf dem ZX81 (wie auf dem JOYCE) der Wert "0" zugewiesen, einer wahren jedoch nicht "-1", sondern "1". Auf dem JOYCE war daher die Umformulierung einiger IF-Bedingungen erforderlich.


Bedingte Ausgabe von Zahlen oder Text

Auf dem ZX81 bedeutet die Anweisung

PRINT AT RD,CD;" " AND NOT A(Y1,X1);CHR$ (A(Y1,X1)+28) AND A(Y1,X1),

daß in Zeile RD und Spalte CD abhängig vom Wahrheitswert der Bedingung A(Y1,X1) (was hier bedeutet, daß das Element des Feldes A mit den Indizes Y1, X1 entweder eine "0" oder keine "0" ist) entweder ein Leerzeichen oder eine Ziffer ausgegeben wird. Diese Schreibweise ist sehr ökonomisch und trägt wesentlich zum schnellen Ablauf von ANDRE***s Programmen bei. Auf dem JOYCE ist hier sowohl für die Cursorpositionierung als auch für das Testen auf "0" eine deutlich aufwendigere Formulierung vonnöten:

DEF FNC$(X,Y)=CHR$(27)+"Y"+CHR$(32+X)+CHR$(32+Y)
PRINT FNC$(RD,CD);:IF NOT A(Y1,X1) THEN PRINT " "; ELSE PRINT CHR$(A(Y1,X1)+48);


Daß hier 48 statt 28 steht, liegt daran, daß Sinclair Basic nicht den ASCII-Code verwendet. Die Ziffern liegen hier auf den Positionen 28 bis 37 (ASCII: 48 bis 57), unmittelbar gefolgt von den Großbuchstaben auf 38 bis 63 (ASCII: 65 bis 90), was nebenbei bemerkt bei der Umrechnung von und nach Hexadezimal einen Vorteil darstellt.

 






    <---




Spielanleitung

auf dem Original

auf der Kopie








-->    


Weitere Feinheiten

Außerdem gab es noch kleinere Sachen anzupassen, zum Beispiel POKEs auszukommentieren, CODE D$ durch ASC(D$) zu ersetzen, die invertierte Ausgabe von Buchstaben oder Ziffern zu realisieren, ein Bildschirmfenster zu definieren und auch sonst die Ausgabe möglichst detailgetreu dem Original anzupassen.
Möchte man das Knobeln unterbrechen, drückt man "S" und das Programm wird als "SUDOKUxx.BAS" abgespeichert. Bei jedem erneuten Abspeichern wird xx um 1 erhöht - in Zeile 1 wird in Y$ der Stand abgelegt, die aktuelle Nummer steht zweistellig am Anfang dieser Variablen. Aufzupassen, doppelte Dateinamen, Überschreiten der 99 und "überlaufende" Disketten zu vermeiden, muß der User selbst übernehmen.

 

Anzeige einer bereits verwendeten Zahl
in Spalte, Reihe oder 9er-Feld mit zugehörigem Hinweistext

 




    <---   



Hinweise auf
verbleibende
mögliche Ziffer(n)

oder eben keine







-->    

 



    <---  


nicht veränderbares
(weil vorgegebenes)
Feld

Schluß-Screen






-->    

 

Thomas Rademacher im November 2006

 

KLICK = download