home *** CD-ROM | disk | FTP | other *** search
/ RUN Flagazine: Run 6 / run6.zip / GWBASIC6.ASC < prev    next >
Text File  |  1992-06-19  |  21KB  |  329 lines

  1.  
  2.                            De GWBASIC Interpreter (6)
  3.  
  4.                                    RANDOMIZERS
  5.  
  6. Iedere programmeur wil zijn programma's levend en verrassend maken door het
  7. gebruik van randomizers of willekeurige getallenkiezers. Randomizers zijn
  8. nuttig en onmisbaar bij toepassingen als: games, kunstmatige intelligentie,
  9. statistiek en vooral bij simulaties (nabootsingen van de werkelijkheid).
  10. Om tot verrassende elementen of 'puur toeval' in onze programma's te komen,
  11. kunnen we niet volstaan met een beroep op de GWBASIC-functie: RND. De op-
  12. dracht in de directe modus:
  13. PRINT RND
  14. geeft weliswaar steeds een ander resultaat: 'n schijnbaar willekeurig decimaal
  15. getal onder de 10 maar als we RND nader bekijken in een klein onderzoekspro-
  16. grammaatje als hieronder, blijkt er van puur toeval totaal geen sprake meer te
  17. ┌────────────────────────────────────────────┐ zijn. Elke RUN levert 'n lijst-
  18. │ 10 REM Genereer 10 willkeurige getallen    │ je op met telkens dezelfde ge-
  19. │ 30 FOR A%=1 TO 10                          │ tallen: 1,6,8,7,7,0,4,4,1 en 9.
  20. │ 40   PRINT "Willekeurig getal nr.";A%;":"; │ De functie RND moet eenmalig
  21. │ 50   PRINT INT(RND*10)                     │ worden voorafgegaan door het
  22. │ 60 NEXT A%                                 │ commando: RANDOMIZE.
  23. │ Ok                                         │ Met dit commando wordt intern de
  24. │ run                                        │ randomizer aangezet maar dit ge-
  25. │ Willekeurig getal nr. 1 : 1                │ beurt pas wanneer daarvoor een
  26. │ Willekeurig getal nr. 2 : 6                │ uitgangs- of zaagetal aanwezig
  27. │ Willekeurig getal nr. 3 : 8                │ is. Het programmaatje hiernaast
  28. │ Willekeurig getal nr. 4 : 7                │ kan worden uitgebreid met de re-
  29. │ Willekeurig getal nr. 5 : 7                │ gel:
  30. │ Willekeurig getal nr. 6 : 0                │ 15 RANDOMIZE
  31. │ Willekeurig getal nr. 7 : 4                │ Als we dat doen zal de interpe-
  32. │ Willekeurig getal nr. 8 : 4                │ ter in deze regel 15 de afwer-
  33. │ Willekeurig getal nr. 9 : 1                │ king van het programma onderbre-
  34. │ Willekeurig getal nr. 10 : 9               │ ken om de gebruiker een zaadge-
  35. └────────────────────────────────────────────┘ tal te vragen. Deze vraag luidt:
  36. Random number seed (-32768 to 32767)
  37. Van de gebruiker wordt verwacht dat hij een getal invoert in het gegeven bereik
  38. maar het getuigt natuurlijk van slecht programmeerwerk wanneer een programma
  39. een argeloze gebruiker met een dergelijke vraag overvalt.
  40. Als programmeurs kunnen we de interne randomizer zelf een zaadgetal geven.
  41. Niets hoeft ons ervan te weerhouden om de nieuwe regel 15 alsdus uit te
  42. breiden:
  43. 15 RANDOMIZE 25                                ┌─────────────────────────────┐
  44. Verscheidene RUN's op het aangepaste programma │ run                         │
  45. geven elke keer weer het resultaat zoals hier- │ Willekeurig getal nr. 1 : 1 │
  46. naast is weergegeven. We hebben nu wel een an- │ Willekeurig getal nr. 2 : 3 │
  47. getallenreeks gegenereerd maar elke keer ver-  │ Willekeurig getal nr. 3 : 1 │
  48. schijnen de getallen in dezelfde volgorde.     │ Willekeurig getal nr. 4 : 8 │
  49. De oorzaak laat zich niet moeilijk raden. De   │ Willekeurig getal nr. 5 : 1 │
  50. volgorde is bepaald door de waarde 25 die we   │ Willekeurig getal nr. 6 : 9 │
  51. als zaadgetal aan RANDOMIZE hebben meegegeven  │ Willekeurig getal nr. 7 : 6 │
  52. in regel 15. Om tot puur toeval te komen moe-  │ Willekeurig getal nr. 8 : 4 │
  53. ten we als zaadgetal een willekeurig getal op- │ Willekeurig getal nr. 9 : 5 │
  54. geven maar hoe doen we dat? Hoe laten we ons   │ Willekeurig getal nr. 10 : 8│
  55. programma een willekeurig zaadgetal bedenken   │ Ok                          │
  56. in een programma dat zelf willekeurige getal-  └─────────────────────────────┘
  57. len moet maken?
  58. Er zijn twee manieren voor. De eenvoudigste en meest gebruikte is die welke
  59. gebruik maakt van de microtimer. Met GWBASIC-commando:
  60. PRINT TIMER
  61. krijgen we de inhoud te zien van de interne klok die microseconden telt. Het
  62. kwartskristal levert daarvoor de invoer. Dit tellertje is gestart op het mo-
  63. moment dat we de PC aanzetten.             ┌─────────────────────────────────┐
  64. TIMER is een interne systeemvariabele die  │ 10 REM BESTUDEER MICROTIMER     │
  65. voortdurend anders zal zijn als hij wordt  │ 20 CLS:KEY OFF                  │
  66. opgevraagd met:                            │ 30 LOCATE 12,25                 │
  67. PRINT TIMER                                │ 40 PRINT "Aanvangstijd:";TIMER  │
  68. We krijgen de waarde tot op twee cijfers   │ 50 WHILE INKEY$=""              │
  69. achter de decimale komma nauwkeurig. Deze  │ 60   LOCATE 13,38               │
  70. nauwkeurigheid kunnen we beperken tot hele │ 70   PRINT TIMER                │
  71. getallen of integers met de toevoeging:    │ 80 WEND                         │
  72. INT. Dus:                                  │ 90 LOCATE 13,25                 │
  73. PRINT INT(TIMER)                           │ 100 PRINT "Stoptijd    :";TIMER │
  74. levert een geheel getal op en in een loop- └─────────────────────────────────┘
  75. je of kringloop geeft dit een bruikbaar secondentellertje. TIMER of INT(TIMER)
  76. kunnen we bij uitstek gebruik als zaadgetal voor RANDOMIZE omdat TIMER op elk
  77. moment een andere waarde zal opleveren. Breiden we het programma van de vorige
  78. pagina uit met:
  79. 15 RANDOMIZE TIMER
  80. dan krijgen we onze zin en zal het resulterende lijstje telkens anders zijn. In
  81. plaats van TIMER wordt ook de negatieve waarde: -TIMER gebruikt. Dat maakt
  82. allemaal niets uit omdat het gevraagde zaadgetal zich over een bereik van
  83. negatieve en positieve getallen uitstrekt.
  84.  
  85. True (?) randomizers
  86.  
  87. Het klinkt misschien gek maar een digitale computer als de PC is niet in staat
  88. echte willekeurige getallen te genereren. Wanneer we gebruik maken van 'wille-
  89. keurig' gekozen zaadgetallen, krijgen we wat we willen, namelijk telkens een
  90. andere waarde van RND() maar heel principieel beschouwd is het resulterende
  91. random getal niet echt random. Het lijkt erop. Daarom wordt er in het computer-
  92. jargon gesproken van 'true randomizers'.
  93. Studenten in de edele kunst van het programmeren komen niet onder de opgave uit
  94. een spelletje te maken dat een willekeurig geheim getal onder de 100 kiest en
  95. de speler laat raden wat het is. Na invoer krijgt de speler te zien of zijn
  96. ingevoerde getal goed is geraden of dat het ingevoerde getal te hoog of te laag
  97. is gegokt.
  98. U gaat dit hooglaag-spelletje nu ook maken maar met wat we in de zes lessen tot
  99. nu toe hebben geleerd, mogen bepaalde eisen aan het programma worden gesteld.
  100. Het programma mag geen invoer accepteren die kleiner is dan nul of groter dan
  101. 99.
  102. Wanneer het programma vaststelt dat de speler het geheime getal heeft geraden,
  103. geeft het tot slot weer hoeveel beurten de speler er over heeft gedaan.
  104.                               ┌────────────────────┐
  105. ┌─────────────────────────────┤      Opgave 1      ├──────────────────────────┐
  106. │100 REM HOOG LAAG SPEL       └────────────────────┘                          │
  107. │110 CLS:KEY OFF:RANDOMIZE TIMER                                              │
  108. │120 COMPUTERKEUS=INT(RND*100)                                                │
  109. │130 INPUT "Welk getal (0 - 99)";SPELERKEUS                                   │
  110. │140 BEURT = BEURT + 1                                                        │
  111. │150 IF SPELERKEUS < 0 OR SPELERKEUS > 99 THEN BEEP:BEURT = BEURT - 1:GOTO 130│
  112. │160 IF SPELERKEUS = COMPUTERKEUS THEN 190                                    │
  113. │170 IF SPELERKEUS < COMPUTERKEUS THEN 200                                    │
  114. │180 IF SPELERKEUS > COMPUTERKEUS THEN 210                                    │
  115. │190 PRINT "Geraden in";BEURT;"beurten":END                                   │
  116. │200 PRINT "Te laag gegokt":GOTO 130                                          │
  117. │210 PRINT "Te hoog gegokt":GOTO 130                                          │
  118. └─────────────────────────────────────────────────────────────────────────────┘
  119.  
  120. De hierboven staande uitwerking van de vingeroefening geeft aanleiding tot een
  121. opmerking. Regel 150 is nogal lang geworden. Dat komt doordat lange numerieke
  122. variabelenamen zijn gebruikt maar ook doordat er na THEN drie dingen aan de
  123. voorwaarden moeten voldoen. ALS de situatie zich voordoet dat de invoer kleiner
  124. is dan 0 OF de situatie zich voordoet dat de invoer groter is dan 100 DAN
  125. moeten er dingen gebeuren die nu volgen: een beepsignaal om de speler tot
  126. opletten te manen, de beurt wordt ongeldig verklaard en de beurtteller wordt
  127. met 1 verminderd en de programma-afwerking springt terug naar regel 130.
  128. Lange regels zijn lelijk in GWBASIC. Zelf probeer ik ze in de RUN-listings voor
  129. het AD zo veel mogelijk te vermijden. Maar bezwijk nooit voor de verleiding om
  130. de opdrachten die aan de IF moeten voldoen in een nieuwe regel te schrijven.
  131. Als u dat doet, voldoen ze niet meer aan de voorwaarden en uw programma gaat
  132. zich misdragen. Het doet niet meer wat u er van verwacht.
  133.  
  134. Randomizer in DEF FN
  135.  
  136. Het moet u inmiddels zijn opgevallen dat GWBASIC een kist vol gereedschappen is
  137. waarvan u er al heel wat kunt hanteren voor het maken van programmaatjes. Als u
  138. met RND() aan de gang gaat, kunt u vooral in combinatie met andere gereed-
  139. schappen, tot zeer verrassende resultaten komen. Het beroemde programma
  140. ELIZA bijvoorbeeld is sterk randomizer-afhankelijk. Het lijkt alsof je met dit
  141. programma over koetjes en kalfjes kunt praten maar in werkelijkheid kiest ELIZA
  142. random uit een lijst van tekststrings. In sommige gevallen worden delen van wat
  143. de gebruiker invoert, verweven in de willekeurig gekozen antwoorden. In de
  144. praktijk gaat dan ongeveer zo:
  145. ╔════════════════════════════════════════════════════════════════════════════╗
  146. ║ Hallo, Ik ben Eliza. Wat is je probleem?                                   ║
  147. ║ -- Mijn naam is Nico.                                                      ║
  148. ║ Namen interesseren me niet.                                                ║
  149. ║ -- Ik heb ruzie met mijn broer.                                            ║
  150. ║ Vertel daar eens meer over.                                                ║
  151. ║ -- Mijn broer is onhebbelijk.                                              ║
  152. ║ Misschien ben jij wel onhebbelijk.                                         ║
  153. ║ -- Ik houd van reizen.                                                     ║
  154. ║ Daar wil ik meer over weten.                                               ║
  155. ║ -- Ik was laatst in de Belgische plaats Namen.                             ║
  156. ║ Namen interesseren me niet.                                                ║
  157. ╚════════════════════════════════════════════════════════════════════════════╝
  158. U voelt 'm al: Dit nepprogramma kiest willekeurig uit nietszeggende zinnetjes
  159. om de conversatie gaande te houden als het geen zinsdelen kan vinden die het
  160. kan verweven in quasi-intelligente antwoorden. Vaak worden antwoorden met
  161. verweven zinsdelen uit de invoer totaal verkeerd gebruikt.
  162. Bij het programmeren van deze en andere programma's die uitbundig van rando-
  163. mizers gebruik maken, moet vele, vele malen de opdracht:
  164. X=INT(RND*x)+1
  165. worden gebruikt. Dat kan ook eenmalig gebeuren met een weinig gebruikte maar
  166. zeer nuttige zelf te maken functie. GWBASIC voorziet in het zelf maken van
  167. functies en het later aanroepen van die functies met: DEF FN en FN. Evenals
  168. RANDOMIZE wordt een DEF FN bovenin de programmalijst geplaatst. De interpreter
  169. hoeft er slechts één keer voorbij te komen.
  170. Een DEF FN kan van alles zijn maar in ons geval kunnen we van te voren bepalen
  171. dat deze 'user DEFined FuNction' een randomizer gaat bevatten. Wanneer we de
  172. volgende zelf te maken function eenmalig en aan het begin van het programma
  173. declareren:
  174. DEF FN X=INT(RND*99)+1
  175. dan kunnen we hem in het werkende programma naar hartelust aanroepen met:
  176. FN X.
  177. De variabele X zal dan elke keer een willekeurig getal tussen 0 en 99 bevatten.
  178. U kunt dit niet in de directe modus van GWBASIC uitproberen. Een DEF FN in de
  179. directe modus geeft als foutmelding: Illegal direct. Daarom een piepklein
  180. programmaatje om dit eens nader te bekijken:
  181. ┌───────────────────────────┐
  182. │ 10 RANDOMIZE -TIMER       │  Tik deze oefening in GWBASIC en geef RUN. U 
  183. │ 20 DEF FN X=INT(RND*99)+1 │  krijgt kolomsgewijs net zo veel willekeurig ge-
  184. │ 30 WHILE INKEY$=""        │  kozen getallen onder de 100 als u maar hebben
  185. │ 40   PRINT FN X,          │  wilt. Voor verdeling in kolommen zorgt de kom-
  186. │ 50 WEND                   │  ma die in regel 30 na X als scheidingsteken fun-
  187. └───────────────────────────┘  geert. Het genereren van de willekeurige getal-
  188. len houdt pas op wanneer u op een toets drukt. Dit is het gevolg van de
  189. WHILE/WEND die op een intoetsing wacht. Tussen de dubbele aanhalingstekens in
  190. regel 20 staat niets; geen spatie dus! Als gevorderde kunt u toch lezen wat er
  191. staat? ZOLANG (WHILE) er geen toets ("")  wordt ingedrukt, druk het in DEF FN
  192. gedeclareerde random getal (FN X) af (WEND).
  193. Op de niet altijd even simpele maar toch wel erg machtige DEF FN komen we
  194. verderop in de cursus nog uitgebreid terug.
  195.  
  196. Randomizers in ON x GOTO
  197.  
  198. Tussen neus en lippen door leren we nu even een handig techniekje dat door
  199. velen vaak wordt gebruikt in een menugestuurd programma. Veel programma's
  200. beginnen met een overzichtelijk menu van opties of keuzemogelijkheden.
  201. Bijvoorbeeld:
  202.  
  203.                               ┌───────────┐
  204.                     ╔═════════╡ HOOFDMENU ╞═════════╗
  205.                     ║         └───────────┘         ║
  206.                     ║   1 - Zoeken op trefwoorden   ║
  207.                     ║   2 - Trefwoorden sorteren    ║
  208.                     ║   3 - Documenten invoeren     ║
  209.                     ║   4 - Systeemoverzicht        ║
  210.                     ║   5 - Statistiek              ║
  211.                     ║   6 - Einde programma         ║
  212.                     ■═══════════════════════════════■
  213.                     │  U kiest: 1, 2, 3, 4, 5 of 6  │
  214.                     └───────────────────────────────┘   
  215.  
  216. Als dit menu op het scherm staat verwacht de programmeur dat de gebruiker nu
  217. de cijfertoetsen 1 tot en met 6 gaat indrukken. Alle andere intoetsingen worden
  218. afgevangen. Het programma ontvangt de intoetsing en daarmee de keuze van de
  219. gebruiker in een numerieke variabele uit, bijvoorbeeld:
  220. 400 INPUT K
  221. 410 IF K<1 AND K>7 THEN BEEP:GOTO 400
  222.  
  223. Wanneer in de variabele K een geldige menukeuze staat, gaat het programma
  224. verder. Nu moet de programmeur zorgen dat het programma wegspringt naar het
  225. deel in het programma waar de bestelde functie begint. Hij heeft zijn programma
  226. netjes gestructureerd opgezet. Zoeken op trefwoorden begint op regel 1000,
  227. Trefwoorden sorteren op regel 2000, Documenten invoeren op 3000,
  228. Systeemoverzicht op 4000, Statistiek op 5000 en Einde programma op 6000.
  229. De programmeur mag nu afzien van een constructie waarin komt te staan:
  230. IF K=1 THEN GOTO 1000
  231. IF K=2 THEN GOTO 2000
  232. ...enzovoort. In plaats daarvan beschikt hij over de functie:
  233. ON [variabelenaam] GOTO [regelnummer].
  234. De verkeersregeling gaat na regel 410 dan als volgt in zijn werk:
  235.  
  236. 420 ON K GOTO 1000, 2000, 3000, 4000, 5000, 6000
  237.  
  238. In een programma dat de schijn wil ophouden dat het over iets beschikt dat doet
  239. denken aan de menselijke vrije wil, kunnen we de ON x GOTO constructie
  240. natuurlijk ook gebruiken met een randomizer. Stel dat in een simulatieprogramma
  241. in 'willekeurige' volgorde continue bepaalde delen van het programma moeten
  242. worden afgewerkt. Laten we aannemen dat die geroepen stukken netjes zijn onder-
  243. gebracht in delen. Schematisch geprogrammeerd ziet dat er zo uit:
  244. We hebben gebruik gemaakt van DEF FN  ┌───────────────────────────────────────┐
  245. functie in regel 20 om in regel 30    │ 10 CLS:KEY OFF:RANDOMIZE TIMER        │
  246. uit FN X steeds een andere waarde     │ 20 DEF FN X=INT(RND*5)+1              │
  247. voor de numerieke variabele X te ver- │ 30 ON FN X GOTO 60, 70, 80, 90, 100   │
  248. krijgen. De ON in regel 30 doet braaf │ 40 PRINT X                            │
  249. wat we willen. Omdat in X telkens een │ 50 REM Hieronder de 5 delen           │
  250. 1, 2, 3, 4 of 5 komt te staan, wordt  │ 60 PRINT "Dit is deel 1":GOTO 110     │
  251. de programmabesturing telkens op een  │ 70 PRINT "Dit is deel 2":GOTO 110     │
  252. ander punt in het programma voortge-  │ 80 PRINT "Dit is deel 3":GOTO 110     │
  253. zet. We kunnen dat op twee manieren   │ 90 PRINT "Dit is deel 4":GOTO 110     │
  254. controleren. In regel 40 wordt X ter  │ 100 PRINT "Dit is deel 5              │
  255. controle op het scherm gezet en in de │ 110 PRINT "Toets voor vervolg"        │
  256. programmadelen wordt weergegeven om   │ 120 WHILE INKEY$="":WEND:GOTO 30      │
  257. welk programmadeel het op dat moment  └───────────────────────────────────────┘
  258. gaat. U ziet trouwens ook waarom in regel 100 geen doorverwijzing naar regel
  259. 110 nodig is; het is de regel die in de programmaflow volgt op regel 100.
  260. Dit testprogramma gedraagt zich, evenals tal van andere als een perpetuum
  261. mobile. De STOP of END ontbreekt. Stop dit programma met Shift+Break.
  262.  
  263. Muzikale grapjes met randomizers
  264.  
  265. Randomizers kunnen de fantasie van de programmeur enorm prikkelen. Sterker nog:
  266. door te stoeien met functies en randomizers kun je tot ontdekkingen komen. Je
  267. kunt tot dingen komen die nog nooit eerder zijn bedacht. Dat geldt bijvoorbeeld
  268. voor grafische en geluidseffecten.
  269. We hebben het muziek- en geluidsgedeelte van GWBASIC nog niet gehad maar niets
  270. hoeft ons er van te weerhouden er onze randomizers op los te laten. Opgemerkt
  271. is al dat randomizers de illusie van kunstmatige intelligentie kunnen opwekken.
  272. Ze kunnen ook de illusie van kunsmatige creativiteit oproepen. Ik heb dat
  273. geprobeerd met onderstaand programma waarin ik de PC muzikale akkoorden laat
  274. genereren. Daarbij is uitgegaan van een simpel principe, namelijk dat muziek
  275. voor een belangrijk deel op herhaling van voorgaande akkoorden maar dan met
  276. verschillende toonhoogte is gebaseerd.
  277. En warempel... dit principe hanterend worden er geluiden ten gehore gebracht
  278. die meestal sterk aan gecomponeerde muziek doen denken.
  279. ╔════════════════════════════════════════════════════════════════════════════╗
  280. ║10 CLS:KEY OFF:RANDOMIZE TIMER                                              ║
  281. ║20 M$="ABCDEFG...."                                                         ║
  282. ║30 DEF FN X=INT(RND*2)+12                                                   ║
  283. ║40 DEF FN Y=INT(RND*11)+1                                                   ║
  284. ║50 DEF FN H=INT(RND*2)+2                                                    ║
  285. ║60 MUZIEK$=""                                                               ║
  286. ║70 FOR A%=1 TO FN X                                                         ║
  287. ║80   Z$=MID$(M$,FN Y,1)                                                     ║
  288. ║90   MUZIEK$=MUZIEK$+Z$                                                     ║
  289. ║100  IF A%/6=INT(A%/6) THEN GOSUB 180:MUZIEK$=MUZIEK$+"MB"+Z$:PRINT MUZIEK$ ║
  290. ║110  IF A%/7=INT(A%/7) THEN GOSUB 190:MUZIEK$=MUZIEK$+"ML"+Z$:PRINT MUZIEK$ ║
  291. ║120 NEXT A%                                                                 ║
  292. ║130 IF LEFT$(MUZIEK$,1)="." THEN MUZIEK$="":GOTO 30                         ║
  293. ║140 GOSUB 180                                                               ║
  294. ║150 PRINT:PRINT MUZIEK$                                                     ║
  295. ║160 MUZIEK$=MUZIEK$+"MLL4EDEGAGFEDMNL2C...C."                               ║
  296. ║170 PLAY MUZIEK$:END                                                        ║
  297. ║180 Z$="O"+STR$(FN H)+MUZIEK$:RETURN                                        ║
  298. ║190 Z$="L"+STR$((FN H)+2)+MUZIEK$:RETURN                                    ║
  299. ╚════════════════════════════════════════════════════════════════════════════╝
  300.  
  301. Print dit programma uit (gebruik desnoods <Shift/Print Scrn>) en luister. U
  302. zult het met me eens zijn dat er iets 'herkenbaars' in de akkoorden zit, maar
  303. over de vraag of dit 'muzikaal' is of 'mooi' mag u van mening verschillen.
  304. Merk op dat in de regels 30 tot en met 50 DEF FN is gebruikt voor de
  305. randomizers die elders in het programma in actie komen.
  306. Voor muziek wordt in GWBASIC het commando PLAY gebruikt. Dit is een nogal
  307. veelzijdig commando dat eigenlijk verspild is aan het goedkope en vaak ook
  308. kwalitatief slechts luidsprekertje waarmee PC's zijn uitgerust. In eerste
  309. aanleg was het luidsprekertje alleen bedoeld om piepjes van SOUND en BEEP
  310. hoorbaar te maken. PLAY verwacht een tekststring en het aardige is natuurlijk
  311. dat zo'n tekststring willekeurig kan worden gemaakt door het gebruik van
  312. randomizers.
  313. Willkeurige getallen die door RND() worden gemaakt moeten voor de tekststring
  314. naar tekst worden omgezet. Dit gebeurt in de regels 180 en 190 met de functie:
  315. STR$(numerieke variabele). STR$ is dus het omgekeerde van VAL(tekst) waarmee
  316. van een getal in de vorm van tekst een echt numeriek en verwerkbaar getal wordt
  317. gemaakt.
  318. Dat was het weer. Oefen vooral veel met het geleerde en bedenk zelf varianten.
  319.  
  320. Ik zie u over een paar maanden graag weer terug....
  321.  
  322.                                                             (Word vervolgd)
  323.  
  324.  
  325. ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
  326.  
  327.  
  328.  
  329.