Files
Pacman-Project/snake-wpo/adt-positie.rkt
joren cd70055bc7 Refactor(English): Rename all files and identifiers from Dutch to English
Renamed files: constanten→constants, adt-positie→adt-position,
adt-doolhof→adt-maze, adt-sleutel→adt-key, adt-tijdslimiet→adt-timer,
adt-teken→adt-draw, adt-spel→adt-game. All message names, variables,
comments, and tests converted to English.

Also fixed counter location bug (time-label x/y were swapped).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 11:06:32 +01:00

92 lines
3.9 KiB
Racket

#lang r7rs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Positie ADT ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-library ()
(import (scheme base))
(export maak-positie)
(begin
;; maak-positie :: number, number -> position
(define (maak-positie x y)
;; We voorzien twee soorten "beweeg" procedures: een functionele (zonder
;; assignments, die dus een nieuw objectje teruggeeft), en destructieve (met
;; assignments, die de interne variabelen van het objectje aanpast).
;; In deze oplossing worden beiden manieren gebruikt omdat beiden op
;; verschillende plaatsen in het spel gebruikt worden.
;; x! :: number -> /
(define (x! nieuwe-x)
(set! x nieuwe-x))
;; y! :: number -> /
(define (y! nieuwe-y)
(set! y nieuwe-y))
;; vergelijk? :: positie -> boolean
(define (vergelijk? andere-positie)
(and (= x (andere-positie 'x))
(= y (andere-positie 'y))))
;; Merk volgende eigenaardigheid op bij onderstaande code...
;;
;; (define pos1 (maak-positie 10 20))
;; (define pos2 (maak-positie 10 20))
;; (eq? pos1 pos2) ; -> #f
;; ((pos1 'vergelijk?) pos2) ; -> #t
;;
;; De ingebouwde `eq?` van Scheme vergelijkt of twee waardes identiek
;; hetzelfde zijn. `pos1` en `pos2` wijzen naar verschillende procedures (want
;; elk hebben een andere omgeving). Daarom geeft `eq?` #f terug in deze
;; situatie.
;;
;; Merk ook op dat deze implementatie gebruik maakt van `=` want zowel van de
;; variabele `x` als de variabele `y` wordt verwacht dat deze numbers zijn.
;; Als je zeker bent dat twee values number zijn, maak dan altijd gebruik van
;; `=` en niet van `eq?`. Kijk naar de documentatie van R7RS voor meer
;; informatie over het verschil tussen `=`, `eq?` maar ook tussen `equal?` en
;; `eqv?`.
(define (beweeg richting)
(cond ((eq? richting 'omhoog) (maak-positie x (- y 1)))
((eq? richting 'omlaag) (maak-positie x (+ y 1)))
((eq? richting 'links) (maak-positie (- x 1) y))
((eq? richting 'rechts) (maak-positie (+ x 1) y))))
;; Er zijn meerdere manieren om een positie te veranderen. Ofwel pas je met
;; behulp van `x!` en `y!` de waarde van een positie-object aan, ofwel
;; genereer je een nieuw positie-object (zoals `beweeg`) die je dan vervolgens
;; aan een ander object kan toewijzen (bijvoorbeeld met `positie!`)
;; Beiden zijn goede methodes voor je spellogica (of zelfs tekenlogica) te
;; implementeren. Documenteer goed welke keuzes je maakt in jouw spel.
;; In dit spel worden beiden gebruikt: de logica voor een slang te laten
;; bewegen maakt gebruik van `beweeg`, maar de logica om een appel op een
;; nieuwe positie te plaatsen maakt gebruik van `x!` en `y!`.
;; Merk op dat we bij de conditional hierboven een `else` tak geplaatst
;; hebben. Mocht deze procedure opgeroepen worden met een foutief symbool (of
;; andere type van waarde) zal er onmiddellijk een foutmelding gegenereerd
;; worden. Hierdoor kan je sneller bepaalde bugs mee oplossen en bespaar je
;; onnodig debugging-werk. Indien je geen else-tak voorziet zal Scheme een
;; #<void> teruggeven als resultaat.
(define (dispatch-positie msg)
(cond ((eq? msg 'x) x)
((eq? msg 'y) y)
((eq? msg 'x!) x!)
((eq? msg 'y!) y!)
((eq? msg 'beweeg) beweeg)
((eq? msg 'vergelijk?) vergelijk?)
(else (error "Positie ADT -- Onbekend bericht:" msg))))
dispatch-positie)))