PiF 9 | <terug> |
Het programma dat we nu hebbben kun je met van alles uitbreiden. Het aardige daaraan is dat ook de beginnende forther nu eens een groter programma ziet, en meemaakt hoe het tot stand komt. En het ook begrijpt (hoop ik dan). Bovendien kunnen er allerlei aspecten van Forth de revue passeren, want het programma focust niet op één bepaald specialisme.
Op het gevaar af dat je denkt "hou nou eens op over die sudoku's" ga ik dus toch nog maar een stapje verder.
s" 4::3:7:1:39:::5:::::::4:::6 enz. " !sudokuDit heeft als nadeel dat de string onhanteerbaar lang is. Opknippen in stukjes maakt het ook niet eenvoudiger. Daarom stel ik het volgende voor:
sudoku 4::3:7:1: 39:::5::: ::::4:::6 enz.Het woord SUDOKU vist zelf de sudokugegevens uit de invoerstroom. Er zijn geen hulptekens of aanhalingstekens nodig en het formaat van de gegevens is volkomen vrij, alleen het aantal tekens en hun volgorde is van belang. De gegevens hoeven niet op één regel te staan. Drie regels met 3 groepjes van 9 karakters (of negen regels van 9 karakters) lijkt me handzaam, maar het mag anders.
Drie voorbeelden, alle met dezelfde sudoku:
sudoku 4-- 3-7 -1- 39- --5 --- --- -4- --6 -5- --- --3 --- 1-8 4-- --2 --- -7- --8 --- --9 --1 -3- --- 6-- --- --5 | sudoku 4..3.7.1. 39...5... ....4...6 .5......3 ...1.84.. ..2....7. ..8.....9 ..1.3.... 6.......5 |
sudoku 400 307 010 390 005 000 000 040 006 050 000 003 000 108 400 002 000 070 008 000 009 001 030 000 600 000 005 |
Je zou SUDOKU en de gegevens erachter met de hand in Forth in kunnen typen, maar de bedoeling is natuurlijk dat je ze in een file zet die je gewoon kunt 'includen'.
- Let op: ga eerst met [escape] uit het SU-programma, zodat de ok-prompt verschijnt.
Als je het woord SUDOKU met zijn gegevens erachter in een file met de muis selecteert en kopieert kun je die in Win32forth rechtstreeks in het Win32forth-venster plakken bij de ok-prompt.
De pseudo-code voor SUDOKU
: SUDOKU ( <sudokugegevens> -- ) Lees het volgende woord uit de invoerstroom. BEGIN Verwijder het eerste karakter uit het woord. Is dat een geldig symbool? IF Zet het in het volgende vakje. ELSE Zet het 'leegteken' in het volgende vakje. THEN Alle vakjes ingevuld? ?EXIT Is de string "op"? IF Lees het volgende woord uit de invoerstroom. THEN AGAIN ;
Aan het eind van een regel komt BL WORD niet verder, hij gaat dan strings met lengte nul afgeven.
Over die hobbel moet we hem dus heen helpen.
REFILL ( -- true | false ) is een forthwoord dat de volgende regel probeert te ontvangen in de invoerbuffer.
TRUE betekent dat dat gaat lukken, FALSE betekent dat het niet kan (bijvoorbeeld aan het eind van de laatste regel van een file).
Met behulp van REFILL maken we het woord BL-WORD (aaneengeschreven) dat nooit een nulstring oplevert.
Als REFILL een FALSE oplevert wordt het programma afgebroken met een foutmelding.
: bl-word ( -- counted-string ) begin bl word dup c@ ?exit \ Er is tekst gevonden. drop refill \ Volgende regel in de invoerbuffer. 0= \ Niet mogelijk? until -39 throw ; \ Onverwacht inputeinde
: schoon ( -- ) (sdk zz 255 fill h-ini ; \ Wis de hele sudokuVerder is het handig om iedere sudoku van een naam te voorzien. Daarvoor zijn NAAM en het hulpwoordje !STRING nodig.
create naam 1 c, char ? c, 30 allot alignRuimte voor de naam: count en 31 karakters.
: !string ( adr len adr2 -- ) \ Zet de string adr,len als tuck c! count move ; \ counted string in adr2.In het hoofdwoord SU komt een extra regel die de naam laat zien:
cr space naam count type
: sudoku ( <sudokunaam> <sudoku-inhoud> -- ) schoon bl-word count \ Naam 31 min naam !string \ Naam opslaan. bl-word count \ Eerste brok sudoku-inhoud zz 0 do dup 0= \ De string is leeg? if 2drop bl-word count \ Volgende woord then over c@ \ Volgende karakter symbool? if i noteer then 1 /string loop 2drop ;
Zie helemaal onderaan in de file sudo3.f
Maak het woord .SUDOKU dat de stand van het moment afdrukt in een vorm die je met SUDOKU weer kunt inlezen.
: .SUDOKU ( -- ) ... ;
De afgedrukte tekst kan dan rechtstreeks of in een log-file met de muis geselecteerd worden en naar een file gekopieerd worden om te bewaren.
Groeten,
| <terug> |