Nieuwe Red release, beginnerscursus programmeren

Het is al een poosje terug dat ik tijd vond om een leuk artikeltje op dit blog te schrijven.
Gelukkig is er nu weer een goede reden om even iets te posten.

Namelijk de release 0.5.4 van Red.

Red is een nieuwe programmeertaal. Al even in ontwikkeling, al sinds 2012, maar nu ligt een stevige basis waarop flink kan worden doorgebouwd.

En bovendien is Red nu al aardig bruikbaar voor kleine programma’s.

Binnenkort komt de eerste versie met GUI ondersteuning. Des te meer reden om eens kort te laten zien hoe makkelijk het programmeren met Red is.

Laten we een versie maken van een simpel raad-een-getal-onder-de-100 spel. We gaan een werkend programma maken en ondertussen maken we het nog iets fraaier, maar het kan altijd beter, het is ook om te laten zien wat er zoal kan.

Deze Nederlandstalige versie behandel ik uitgebreid de stappen die nodig zijn om je omgeving in te richten. Omdat alles op de officiele sites in het Engels wordt uitgelegd laat ik dit in de Engelse versie die ik ook zal plaatsen achterwege, maar om degenen die het Engels minder goed beheersen ook met Red kennis te laten maken vertel ik hier alles lekker uitgebreid.

Wat hebben we nodig?

Allereerst een Rebol runtime (het Rebol programma) voor onze computer.
Download daarom een rebol-core van de Rebol.com site
http://www.rebol.com/download-core.html
en als je toch bezig bent ook gelijk een view versie van
http://www.rebol.com/download-view.html
Om Red programma’s te compileren heb je aan de core versie genoeg.

Download de broncode van Red van de Github site
https://github.com/red/red
Onderaan in de rechter kolom staat een knop met de tekst “Download ZIP”
Pak dit bestand uit naar de map waar je het wilt hebben.

Download ook het Red programma van de officiele site
http://www.red-lang.org/p/download.html
Als het goed is zie je een grote rode knop waarin de link naar programma voor jouw besturingssysteem van je computer staat.
Je maakt in mijnmap ook een map met bijvoorbeeld de naam ‘project’ hierin kun je weer nieuwe mappen maken, voor elk programma dat je maakt eentje.

Ik ga er even vanuit dat je nu een paar mappen hebt:

/mijnmap
    rebol-core.exe 
    rebol-view.exe
    red.exe
/mijnmap/project
/mijnmap/red

Start het Red programma eens op. Red compileert nu het console programma voor je. Met dit console kun je allerlei HELP hulp opvragen. Probeer het gerust. Je kunt ook kleine sommetjes proberen bijvoorbeeld 12 * 12 of 4096 / 16

We maken nu een programmafile aan.
Dat is gewoon een tekstbestand dat je met Notepad of Kladblok kunt openen.
Het bestand noemen we “raden.red” en we zetten het in de map mijnmap/project/raden/

Op de eerste regel komt te staan dat dit een Red programma is.

Red []

Tussen de blokhaken (of spekhaken ik gebruik vaak beide namen door elkaar) die je veel zult zien kun je allerlei informatie over je programma (of script) zetten.

Red [
    file: %raden.red
    maker: "ik"
    omschrijving: {
    Dit programma kiest een getal van 1 tot en met 99 dat je moet raden.
    }
]

Zoals je ziet wordt het bestand raden.red voorafgegaan door een procent teken “%”. Dit geeft in Red aan dat het om een bestand gaat en niet om een naam van een variabele of iets anders.

We willen straks aan de speler vragen om een getal in te vullen. Hoe doen we dat? We gebruiken de functie ASK.
ASK is nog geen standaard functie binnen Red maar het console programma dat met red geleverd wordt maakt al wel gebruik hiervan.
We moeten op dit moment dus even zelf de broncode voor deze functie aan ons programma meegeven. Gelukkig is dat heel makkelijk.

Red []
#include %../../red/environment/console/input.red

De puntjes en de slash geven aan dat we eerst vanuit dit programma een map omhoog in de mappenboom moeten stappen.

Wat moet het programma doen?
1. Een willekeurig geheel getal kiezen van 1 tot 99
2. Vragen om een getal
3. kijken of het het getal geraden is of dat het te raden getal groter of kleiner is.
4. Is het getal geraden of wil de speler stoppen of is er te vaak geprobeerd zonder het goede antwoord dan stoppen
5. Anders gaan we weer naar stap 2

We noemen het getal dat de computer kiest geheim-getal
Met een dubbele punt na geheim-getal geven we aan dat de waarde van geheim-getal gevuld gaat worden met wat er achter volgt.
Het kiezen van een willekeurig getal gaat met de functie random, dat natuurlijk ook willekeurig betekent in het Engels.

Stap 1 vertaalt dan naar

geheim-getal: random 99

De rest van het programma schrijf ik nu even anders op
doe-totdat speler wil stoppen of te vaak geraden of goed geraden
vraag om een getal
tel een op bij het aantal keer raden
kijk of het getal is geraden
zo niet geef een aanwijzing, moet de speler hoger raden of juist lager?

Einde van het spel

Voor doe-totdat hebben we in Red de functie until. Until doet alles uit het blok dat er na komt totdat de voorwaarde op de laatste regel waar is geworden.

We kunnen help until doen in de Red console (red.exe op Windows computers)

--== Red 0.5.4 ==--
Type HELP for starting information.

red>> help until

USAGE:
until body

DESCRIPTION:
Evaluates body until it is true.
until is of type: native!

ARGUMENTS:
body [block!]

REFINEMENTS:

Dus until wordt gevolgd door een block!. En een block! is niets meer of minder dan een blok code. En dat is weer alle code die binne een paar spekhaken staat. Oftewel until []. We schrijven nu onze code op.

until [
    doe-hier-de-dingen-die-je-wilt-doen
    en-misschien-heb-je-daar-heel-wat-regels-voor-nodig

    totdat-deze-regel-waar-is
]

We moeten dus bij gaan houden hoe vaak er geraden is en of het getal geraden is.

aantal-keer-raden: 0
getal-geraden: false

Als de speler wil stoppen willen we daar ook wel rekening mee houden, toch?
Dus er zijn 3 redenen waarom ons programma mag stoppen. Elke reden is op zichzelf genoeg reden om te stoppen.
We hebben in Red een ANY functie die van meer dan 1 voorwaarden teruggeeft of er 1 of meer van waar zijn. Zet elke voorwaarde netjes op een regel.

Dit zegt de Red help any

red>> help any

USAGE:
any conds

DESCRIPTION:
Evaluates, returning at the first that is true.
any is of type: native!

ARGUMENTS:
conds [block!]

REFINEMENTS:

ANY geeft dus al waar terug bij de eerste de beste voorwaarde die waar is.

We krijgen dus

any [ aantal-keren-raden > 20
antwoord = "stop"
getal-geraden ]

Samen wordt dit dan

aantal-keer-raden: 0
getal-geraden: false

until [ antwoord: ask "Geef een getal (1 t/m 99 of stop): "
    aantal-keer-raden: aantal-keer-raden + 1

    is-het-getal-geraden?

    any [ aantal-keren-raden > 20
        antwoord = "stop"
        getal-geraden ]
]

Het stukje is-het-getal-geraden? moeten we nog invullen.
Het geheim-getal is dan gelijk aan het antwoord. Als dat zo is dan is antwoord-geraden.
Net als in andere talen heeft Red ook een IF
if geheim-getal = antwoord [getal-geraden: true]

Als we alle stukjes invullen, krijgen we een aardig programma

Red [
    file: %raden.red
    maker: "ik"
    omschrijving: {
    Dit programma kiest een getal van 1 tot en met 99 dat je moet raden.
    }
]

#include %../../red/environment/console/input.red

geheim-getal: random 99

aantal-keer-raden: 0
getal-geraden: false
klaar: false

until [ antwoord: ask "Geef een getal (1 t/m 99 of stop): "
    aantal-keer-raden: aantal-keer-raden + 1

if geheim-getal = antwoord [
    getal-geraden: true
    print ["Hoera je hebt het getal geraden in" aantal-keer-raden "keer"]
]

if geheim-getal < antwoord [ print ["Het geheime getal is kleiner dan" antwoord] ] if                 geheim-getal > antwoord [
    print ["Het geheime getal is groter dan" antwoord]
]

any [ aantal-keren-raden > 20
    antwoord = "stop"
    getal-geraden ]
]

Maar….
We moeten het programma nog compileren!

Hiervoor starten we de rebol-core op.
We gaan met CD naar de map mijnmap/red

cd red

En daar

do %red.r

en we compileren ons programma (hoe dit moet staat in het Engels uitgebreid hier: http://www.red-lang.org/2015/04/053-faster-compilation-and-extended.html )

rc "-c ../project/raden/raden.red"

Als dit klaar is is er een programma gemaakt dat je kunt uitvoeren. In Windows moet je een cmd.exe (DOS schil) openen hierin ga je naar de map (mijnmap/red) met het programma raden.exe

We testen eerst of het programma ook stopt als we stop typen. Okee dat gaat leuk. Nu gaan we nog eens testen en geven een getal in. Oeps! Een fout!

Alles dat we intypen is natuurlijk een string en geen getal. En als we “12” vergelijken met bijvoorbeeld 6, dan vergelijken we appels en peren. We moeten van onze invoer een getal maken. Gelukkig kan dat simpel met de functie LOAD.

raad-getal: load antwoord

en we testen of we nu ook echt een getal hebben met

integer? raad-getal

Als dat zo is kunnen we verder.

Hoe maken we het programma beter?
In plaats van antwoord = “stop” maken we een vlag om te stoppen, we kunnen deze bijvoorbeeld “stoppen” noemen, maar “klaar” is ook een optie. Als we beginnen zijn we nog niet klaar, dus nemen we een regel op met
klaar: false
Nu kunnen we de speler ook helpen door “s” en “stoppen” ook als “stop” op te vatten

if any [antwoord = "s"
    antwoord = "stop"
    antwoord = "stoppen"] [klaar: true]

Als je het spelletje vaker speelt zul je merken dat het programma steeds het zelfde getal kiest. We moeten nog de random generator opschudden. Dat moet met de /seed refinement van de random functie.
random/seed 9999
Het getal waarmee de seed wordt gedaan moet bij voorkeur zelf ook niet steeds gelijk zijn. De tijdstempel is hiervoor een goede optie. Helaas heeft Red nu nog geen tijd die opgevraagd kan worden.

Verder crasht het programma aan het einde als je al klaar bent. Ik heb dit al gemeld bij de ontwikkelaars, maar het wordt tzt vanzelf opgelost als Red officieel input/output ondersteuning krijgt.

Deze laatste beide problemen zijn ook op te lossen door de C-library binding van Kaj de Vos te gebruiken, en speciaal hiervan de ANSI binding. Je kunt deze binding vinden http://red.esperconsultancy.nl/Red-test/dir?ci=tip
TIP! Je vindt hier ook voor allerlei Operating Systemen een Red programma met de bindingen er al in gebouwd.
Je moet ook nog even een fossil programma downloaden vanaf http://fossil-scm.org/index.html/doc/trunk/www/index.wiki beter gezegd vanaf https://www.fossil-scm.org/download.html
Dat zet je in de map bij je rebol programma en vanuit de rebol console doe je dan
do %download.r

Zet al je nieuwe binding files in een map met de naam bind

Nu vervang je de #include regel voor de volgende

#include %../bind/C-library/ANSI.red

en we bepalen de tijd in seconden met now/precise die we dankzij de binding ook meteen hebben.

tijd: remainder now/precise 10000 ; is niet echt nodig maar ruim genoeg voor ons programma.

random/seed tijd

Voor de volledigheid het hele programma

(Let niet te veel op de uitlijning, de inspringing hoort met tabs van 4 spaties te zijn)

Red [
    file: %raden.red
    maker: "ik"
    omschrijving: {
    Dit programma kiest een getal van 1 tot en met 99 dat je moet raden.
    }
]
; commentaar is alles dat na een puntkomma komt, behalve als de puntkomma
; in een tekst tussen aanhalingstekens staat.

; Voeg de functies ASK en NOW toe met deze binding
#include %../bind/C-library/ANSI.red

; Beginwaarden instellen
tijd: remainder now/precise 10000
random/seed tijd

geheim-getal: random 99
print geheim-getal  ; Dit moet je natuurlijk straks in commentaar veranderen!

aantal-keer-raden: 0
getal-geraden: false
klaar?: false

until [
    antwoord: ask "Geef een getal (1 t/m 99 of stop): "
    if any [antwoord = "s"
        antwoord = "S"
        antwoord = "stop"
        antwoord = "STOP"
        antwoord = "stoppen"
        antwoord = "STOPPEN"][
        print "Je wilt stoppen, dus tot de volgende keer!"
        klaar?: true
    ]

    aantal-keer-raden: aantal-keer-raden + 1

    if not klaar? [
        raad-getal: load antwoord
        either integer! = type? raad-getal [

            if geheim-getal = raad-getal [
                getal-geraden: true
                klaar?: true
                print ["Hoera je hebt het getal geraden in" aantal-keer-raden "keer"]
            ]

            if not klaar? [
                if aantal-keer-raden > 19 [
                    klaar?: true
                    print ["Sorry. Je hebt 20 keer geraden, het getal was" geheim-getal]
                ]
            ]

            if not klaar? [
                if geheim-getal < raad-getal [
                    print ["Het geheime getal is kleiner dan" raad-getal]
                ]

                if geheim-getal > raad-getal [
                    print ["Het geheime getal is groter dan" raad-getal]
                ]
            ]
        ][
            either aantal-keer-raden > 19 [
                klaar?: true
                print ["Sorry. Je hebt 20 keer geraden, het getal was" geheim-getal]
            ][
                print "Dat snapte ik niet helemaal, probeer het nog eens."
            ]
        ]
    ]

    klaar?
]

; einde programma
print "Tot ziens!"

Programmeren in je moerstaal
Wil je nou liever in het Nederlands programmeren, dan kun je makkelijk je eigen functienaam geven aan de functies in Red. Als je liever VRAAG gebruikt dan ASK dan neem je een regel op met
vraag: :ask
Dit zegt dat je VRAAG gelijk maakt aan ASK.

Bedenk wel dat het over het algemeen een beter idee is om de originele functies te gebruiken. Andere programmeurs over de hele wereld gebruiken deze ook en kunnen je beter helpen want jouw eigen functienamen zijn alleen bij jou bekend. En je leert gelijk een beetje Engels 🙂

Wat kan er nog meer met Red?

Dat is een goede vraag. Mooi voor een volgend blogje.

Laat je het even weten als er nog dingen niet helemaal duidelijk zijn in dit artikel?

This entry was posted in Programmeren and tagged , . Bookmark the permalink.

Geef een reactie

Your email address will not be published. Required fields are marked *

Vul dit nog even in: * Time limit is exhausted. Please reload CAPTCHA.