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>
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Doolhof ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Het doolhof bevat het logische grid met cellen. Elke cel heeft een type
|
||||
;; (muur, muntje, leeg, sleutel, deur). Dit ADT bevat GEEN grafische code.
|
||||
|
||||
(define-library (pacman-project adt-doolhof)
|
||||
(import (scheme base)
|
||||
(pacman-project constanten))
|
||||
(export maak-doolhof)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-doolhof :: -> doolhof
|
||||
;; Maakt een nieuw doolhof-object aan met het volledige grid.
|
||||
(define (maak-doolhof)
|
||||
|
||||
;; Het doolhof grid: 31 rijen x 28 kolommen.
|
||||
;; vector wordt gebruikt omdat het mutable is (i.t.t. #()).
|
||||
(define grid
|
||||
(vector (vector 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 4 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1)
|
||||
(vector 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1)
|
||||
(vector 2 2 2 2 2 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 1 1 1 4 4 1 1 1 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1)
|
||||
(vector 2 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 2)
|
||||
(vector 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1)
|
||||
(vector 1 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1)
|
||||
(vector 1 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1)
|
||||
(vector 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 4 1 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 0 1)
|
||||
(vector 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)))
|
||||
|
||||
(define aantal-rijen (vector-length grid))
|
||||
(define aantal-kolommen (vector-length (vector-ref grid 0)))
|
||||
|
||||
;; cel-ref :: number, number -> number
|
||||
;; Geeft het celtype terug op de opgegeven positie.
|
||||
(define (cel-ref rij kolom)
|
||||
(vector-ref (vector-ref grid rij) kolom))
|
||||
|
||||
;; cel-set! :: number, number, number -> /
|
||||
;; Past het celtype aan op de opgegeven positie.
|
||||
(define (cel-set! rij kolom waarde)
|
||||
(vector-set! (vector-ref grid rij) kolom waarde))
|
||||
|
||||
;; muur? :: number, number -> boolean
|
||||
(define (muur? rij kolom)
|
||||
(= (cel-ref rij kolom) cel-type-muur))
|
||||
|
||||
;; muntje? :: number, number -> boolean
|
||||
(define (muntje? rij kolom)
|
||||
(= (cel-ref rij kolom) cel-type-muntje))
|
||||
|
||||
;; leeg? :: number, number -> boolean
|
||||
(define (leeg? rij kolom)
|
||||
(= (cel-ref rij kolom) cel-type-leeg))
|
||||
|
||||
;; sleutel? :: number, number -> boolean
|
||||
(define (sleutel? rij kolom)
|
||||
(= (cel-ref rij kolom) cel-type-sleutel))
|
||||
|
||||
;; deur? :: number, number -> boolean
|
||||
(define (deur? rij kolom)
|
||||
(= (cel-ref rij kolom) cel-type-deur))
|
||||
|
||||
;; verwijder-deur! :: number, number -> /
|
||||
;; Verwijdert een deur uit het grid (maakt de cel leeg).
|
||||
(define (verwijder-deur! rij kolom)
|
||||
(cel-set! rij kolom cel-type-leeg))
|
||||
|
||||
;; voor-elke-cel :: (number, number, number -> /) -> /
|
||||
;; Itereert over alle cellen en roept de callback op met rij, kolom en celtype.
|
||||
(define (voor-elke-cel callback)
|
||||
(do ((rij 0 (+ rij 1)))
|
||||
((= rij aantal-rijen))
|
||||
(do ((kolom 0 (+ kolom 1)))
|
||||
((= kolom aantal-kolommen))
|
||||
(callback rij kolom (cel-ref rij kolom)))))
|
||||
|
||||
;; dispatch-doolhof :: symbol -> any
|
||||
(define (dispatch-doolhof msg)
|
||||
(cond ((eq? msg 'rijen) aantal-rijen)
|
||||
((eq? msg 'kolommen) aantal-kolommen)
|
||||
((eq? msg 'cel-ref) cel-ref)
|
||||
((eq? msg 'cel-set!) cel-set!)
|
||||
((eq? msg 'muur?) muur?)
|
||||
((eq? msg 'muntje?) muntje?)
|
||||
((eq? msg 'leeg?) leeg?)
|
||||
((eq? msg 'sleutel?) sleutel?)
|
||||
((eq? msg 'deur?) deur?)
|
||||
((eq? msg 'verwijder-deur!) verwijder-deur!)
|
||||
((eq? msg 'voor-elke-cel) voor-elke-cel)
|
||||
(else (error "Doolhof ADT -- Onbekend bericht:" msg))))
|
||||
|
||||
dispatch-doolhof)))
|
||||
248
pacman-project/adt-draw.rkt
Normal file
248
pacman-project/adt-draw.rkt
Normal file
@@ -0,0 +1,248 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Draw ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; All graphics logic is isolated in this ADT. Game logic knows nothing about
|
||||
;; pixels, windows, or sprites. Grid-to-pixel conversion happens exclusively
|
||||
;; here.
|
||||
|
||||
(define-library (pacman-project adt-draw)
|
||||
(import (scheme base)
|
||||
(pp1 graphics)
|
||||
(pacman-project constants))
|
||||
(export make-draw)
|
||||
|
||||
(begin
|
||||
|
||||
;; make-draw :: number, number -> draw
|
||||
;; Creates the draw object that handles all rendering.
|
||||
(define (make-draw width height)
|
||||
(let ((window (make-window width height "Pacman")))
|
||||
|
||||
((window 'set-background!) "black")
|
||||
|
||||
;;
|
||||
;; Layers (order determines draw order)
|
||||
;;
|
||||
|
||||
(define maze-layer ((window 'new-layer!)))
|
||||
(define coins-layer ((window 'new-layer!)))
|
||||
(define key-layer ((window 'new-layer!)))
|
||||
(define pacman-layer ((window 'new-layer!)))
|
||||
(define ui-layer ((window 'new-layer!)))
|
||||
(define pause-layer ((window 'new-layer!)))
|
||||
|
||||
;;
|
||||
;; Maze tiles
|
||||
;;
|
||||
|
||||
(define maze-tile (make-tile width height))
|
||||
((maze-layer 'add-drawable!) maze-tile)
|
||||
|
||||
;;
|
||||
;; Coins tile
|
||||
;;
|
||||
|
||||
(define coins-tile (make-tile width height))
|
||||
((coins-layer 'add-drawable!) coins-tile)
|
||||
|
||||
;;
|
||||
;; Key sprite (in the maze)
|
||||
;;
|
||||
|
||||
(define key-sprite (make-bitmap-tile "pacman-sprites/key.png"))
|
||||
((key-sprite 'set-scale!) sprite-scale-key)
|
||||
((key-layer 'add-drawable!) key-sprite)
|
||||
|
||||
;; Key UI indicator (next to the score)
|
||||
(define key-ui-sprite (make-bitmap-tile "pacman-sprites/key.png"))
|
||||
((key-ui-sprite 'set-scale!) sprite-scale-key-ui)
|
||||
((key-ui-sprite 'set-x!) key-ui-x)
|
||||
((key-ui-sprite 'set-y!) key-ui-y)
|
||||
|
||||
;;
|
||||
;; Pac-Man sprite
|
||||
;;
|
||||
|
||||
(define pacman-bitmap-tiles
|
||||
(list (make-bitmap-tile "pacman-sprites/pacman-death-1.png")
|
||||
(make-bitmap-tile "pacman-sprites/pacman-closed.png")
|
||||
(make-bitmap-tile "pacman-sprites/pacman-open.png")))
|
||||
|
||||
(define pacman-sprite (make-tile-sequence pacman-bitmap-tiles))
|
||||
((pacman-sprite 'set-scale!) sprite-scale-pacman)
|
||||
((pacman-layer 'add-drawable!) pacman-sprite)
|
||||
|
||||
;; Animation state
|
||||
(define time-since-last-animation 0)
|
||||
|
||||
;;
|
||||
;; UI tiles
|
||||
;;
|
||||
|
||||
(define ui-tile (make-tile width height))
|
||||
((ui-layer 'add-drawable!) ui-tile)
|
||||
|
||||
;;
|
||||
;; Coordinate conversion
|
||||
;;
|
||||
|
||||
;; grid->pixel-x :: number -> number
|
||||
(define (grid->pixel-x col)
|
||||
(* cell-size-px col))
|
||||
|
||||
;; grid->pixel-y :: number -> number
|
||||
(define (grid->pixel-y row)
|
||||
(+ (* row cell-size-px) maze-offset-y))
|
||||
|
||||
;;
|
||||
;; Draw functions
|
||||
;;
|
||||
|
||||
;; draw-maze! :: maze -> /
|
||||
;; Draws all walls and doors.
|
||||
(define (draw-maze! maze)
|
||||
((maze 'for-each-cell)
|
||||
(lambda (row col cell-type)
|
||||
(cond
|
||||
((= cell-type cell-type-wall)
|
||||
((maze-tile 'draw-rectangle!)
|
||||
(grid->pixel-x col)
|
||||
(grid->pixel-y row)
|
||||
(- cell-size-px maze-wall-shrink)
|
||||
(- cell-size-px maze-wall-shrink)
|
||||
"blue"))
|
||||
((= cell-type cell-type-door)
|
||||
((maze-tile 'draw-rectangle!)
|
||||
(grid->pixel-x col)
|
||||
(grid->pixel-y row)
|
||||
(- cell-size-px maze-wall-shrink)
|
||||
(- cell-size-px maze-wall-shrink)
|
||||
"pink"))))))
|
||||
|
||||
;; draw-coins! :: maze -> /
|
||||
;; Draws all coins in the maze.
|
||||
(define (draw-coins! maze)
|
||||
((coins-tile 'clear!))
|
||||
((maze 'for-each-cell)
|
||||
(lambda (row col cell-type)
|
||||
(when (= cell-type cell-type-coin)
|
||||
((coins-tile 'draw-rectangle!)
|
||||
(+ (grid->pixel-x col) coin-inset)
|
||||
(+ (grid->pixel-y row) coin-inset)
|
||||
(- cell-size-px (* 2 coin-inset) 6)
|
||||
(- cell-size-px (* 2 coin-inset) 6)
|
||||
"yellow")))))
|
||||
|
||||
;; draw-key! :: key -> /
|
||||
;; Draws the key at its position, or shows it in UI if taken.
|
||||
(define (draw-key! key-obj)
|
||||
(if (key-obj 'taken?)
|
||||
(begin
|
||||
((key-layer 'remove-drawable!) key-sprite)
|
||||
((key-layer 'add-drawable!) key-ui-sprite))
|
||||
(let ((pos (key-obj 'position)))
|
||||
((key-sprite 'set-x!) (grid->pixel-x (pos 'col)))
|
||||
((key-sprite 'set-y!) (grid->pixel-y (pos 'row))))))
|
||||
|
||||
;; draw-pacman! :: pacman, number -> /
|
||||
;; Draws Pac-Man at its current position with correct rotation.
|
||||
(define (draw-pacman! pacman delta-time)
|
||||
(let* ((pos (pacman 'position))
|
||||
(direction (pacman 'direction)))
|
||||
;; Set position
|
||||
((pacman-sprite 'set-x!) (grid->pixel-x (pos 'col)))
|
||||
((pacman-sprite 'set-y!) (grid->pixel-y (pos 'row)))
|
||||
;; Set rotation based on direction
|
||||
(cond ((eq? direction 'right) ((pacman-sprite 'rotate!) rotation-right))
|
||||
((eq? direction 'left) ((pacman-sprite 'rotate!) rotation-left))
|
||||
((eq? direction 'up) ((pacman-sprite 'rotate!) rotation-up))
|
||||
((eq? direction 'down) ((pacman-sprite 'rotate!) rotation-down)))
|
||||
;; Animation
|
||||
(set! time-since-last-animation (+ time-since-last-animation delta-time))
|
||||
(when (>= time-since-last-animation animation-interval-ms)
|
||||
((pacman-sprite 'set-next!))
|
||||
(set! time-since-last-animation 0))))
|
||||
|
||||
;; draw-ui! :: score, timer -> /
|
||||
;; Draws the score and time limit on screen.
|
||||
(define (draw-ui! score timer)
|
||||
((ui-tile 'clear!))
|
||||
;; Score
|
||||
((ui-tile 'draw-text!)
|
||||
(number->string (score 'points))
|
||||
score-text-size score-text-x score-text-y "white")
|
||||
;; Separator line
|
||||
((ui-tile 'draw-rectangle!)
|
||||
separator-x 0 separator-width height "white")
|
||||
;; Time limit
|
||||
((ui-tile 'draw-text!)
|
||||
"Time remaining:" time-text-size time-label-x time-label-y "white")
|
||||
((ui-tile 'draw-text!)
|
||||
((timer 'format-time))
|
||||
score-text-size time-value-x time-value-y "white"))
|
||||
|
||||
;; draw-pause! :: boolean -> /
|
||||
;; Shows or hides the pause screen.
|
||||
(define (draw-pause! paused?)
|
||||
((pause-layer 'empty!))
|
||||
(when paused?
|
||||
(let ((pause-tile (make-tile width height)))
|
||||
((pause-layer 'add-drawable!) pause-tile)
|
||||
((pause-tile 'draw-rectangle!) 0 90 670 height "black")
|
||||
((pause-tile 'draw-text!) "Game Paused" 40 200 400 "red"))))
|
||||
|
||||
;; redraw-maze! :: maze -> /
|
||||
;; Redraws the maze (after door removal).
|
||||
(define (redraw-maze! maze)
|
||||
((maze-tile 'clear!))
|
||||
(draw-maze! maze))
|
||||
|
||||
;;
|
||||
;; Main draw function
|
||||
;;
|
||||
|
||||
;; draw-game! :: game -> /
|
||||
;; Draws the full game (registered as draw callback).
|
||||
(define (draw-game! game)
|
||||
(let ((level (game 'level)))
|
||||
(draw-pacman! (level 'pacman) 0)
|
||||
(draw-key! (level 'key))
|
||||
(draw-coins! (level 'maze))
|
||||
(draw-ui! (level 'score) (level 'timer))
|
||||
(draw-pause! (level 'paused?))))
|
||||
|
||||
;;
|
||||
;; Callback registration
|
||||
;;
|
||||
|
||||
;; set-game-loop! :: (number -> /) -> /
|
||||
(define (set-game-loop! fun)
|
||||
((window 'set-update-callback!) fun))
|
||||
|
||||
;; set-key-callback! :: (symbol, any -> /) -> /
|
||||
(define (set-key-callback! fun)
|
||||
((window 'set-key-callback!) fun))
|
||||
|
||||
;; start-drawing! :: game -> /
|
||||
;; Starts drawing by setting the draw callback.
|
||||
(define (start-drawing! game)
|
||||
;; Initial maze and coins draw (one-time)
|
||||
(draw-maze! ((game 'level) 'maze))
|
||||
(draw-coins! ((game 'level) 'maze))
|
||||
((window 'set-draw-callback!)
|
||||
(lambda () (draw-game! game))))
|
||||
|
||||
;;
|
||||
;; Dispatch
|
||||
;;
|
||||
|
||||
(define (dispatch-draw msg)
|
||||
(cond ((eq? msg 'set-game-loop!) set-game-loop!)
|
||||
((eq? msg 'set-key-callback!) set-key-callback!)
|
||||
((eq? msg 'start-drawing!) start-drawing!)
|
||||
(else (error "Draw ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-draw))))
|
||||
48
pacman-project/adt-game.rkt
Normal file
48
pacman-project/adt-game.rkt
Normal file
@@ -0,0 +1,48 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Game ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Top-level game object that connects the level (logic) with the draw ADT
|
||||
;; (graphics). Registers callbacks for the game loop, keys, and drawing.
|
||||
|
||||
(define-library (pacman-project adt-game)
|
||||
(import (scheme base)
|
||||
(pacman-project constants)
|
||||
(pacman-project adt-level)
|
||||
(pacman-project adt-draw))
|
||||
(export make-game)
|
||||
|
||||
(begin
|
||||
|
||||
;; make-game :: -> game
|
||||
(define (make-game)
|
||||
(let ((level (make-level))
|
||||
(draw (make-draw window-width-px window-height-px)))
|
||||
|
||||
;; key-handler :: symbol, any -> /
|
||||
;; Processes key presses and forwards them to the level.
|
||||
(define (key-handler status key)
|
||||
(when (eq? status 'pressed)
|
||||
((level 'key-press!) key)))
|
||||
|
||||
;; game-loop :: number -> /
|
||||
;; Called each frame for game state updates.
|
||||
(define (game-loop delta-time)
|
||||
((level 'update!) delta-time))
|
||||
|
||||
;; start! :: -> /
|
||||
;; Starts the game by registering all callbacks.
|
||||
(define (start!)
|
||||
((draw 'set-game-loop!) game-loop)
|
||||
((draw 'set-key-callback!) key-handler)
|
||||
((draw 'start-drawing!) dispatch-game))
|
||||
|
||||
;; dispatch-game :: symbol -> any
|
||||
(define (dispatch-game msg)
|
||||
(cond ((eq? msg 'start!) start!)
|
||||
((eq? msg 'level) level)
|
||||
(else (error "Game ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-game))))
|
||||
55
pacman-project/adt-key.rkt
Normal file
55
pacman-project/adt-key.rkt
Normal file
@@ -0,0 +1,55 @@
|
||||
#lang r7rs
|
||||
|
||||
(#%require (only racket/base random))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Key ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; The key is placed at a random coin position in the maze. When Pac-Man
|
||||
;; picks it up, doors can be opened. Contains NO graphics code.
|
||||
|
||||
(define-library (pacman-project adt-key)
|
||||
(import (scheme base)
|
||||
(pacman-project constants)
|
||||
(pacman-project adt-position))
|
||||
(export make-key)
|
||||
|
||||
(begin
|
||||
|
||||
;; make-key :: maze -> key
|
||||
;; Creates a key and places it at a random coin position.
|
||||
(define (make-key maze)
|
||||
(let ((position #f)
|
||||
(taken? #f))
|
||||
|
||||
;; place-random! :: -> /
|
||||
;; Places the key on a random cell that contains a coin.
|
||||
(define (place-random!)
|
||||
(let loop ((attempts 0))
|
||||
(if (>= attempts max-placement-attempts)
|
||||
(error "No valid position found for key")
|
||||
(let ((col (random 0 (maze 'cols)))
|
||||
(row (random 0 (maze 'rows))))
|
||||
(if ((maze 'coin?) row col)
|
||||
(begin
|
||||
(set! position (make-position row col))
|
||||
((maze 'cell-set!) row col cell-type-key))
|
||||
(loop (+ attempts 1)))))))
|
||||
|
||||
;; take! :: -> /
|
||||
;; Marks the key as taken.
|
||||
(define (take!)
|
||||
(set! taken? #t))
|
||||
|
||||
;; Initialization: place the key immediately on creation.
|
||||
(place-random!)
|
||||
|
||||
;; dispatch-key :: symbol -> any
|
||||
(define (dispatch-key msg)
|
||||
(cond ((eq? msg 'position) position)
|
||||
((eq? msg 'taken?) taken?)
|
||||
((eq? msg 'take!) take!)
|
||||
(else (error "Key ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-key))))
|
||||
@@ -4,172 +4,171 @@
|
||||
;; Level ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Het level bevat alle spellogica: beweging van Pac-Man, botsingsdetectie,
|
||||
;; muntjes eten, sleutel oppakken, deuren openen, teleportatie, pauze en
|
||||
;; tijdsbeheer. Bevat GEEN grafische code.
|
||||
;; Contains all game logic: Pac-Man movement, collision detection, coin/key
|
||||
;; pickup, door opening, teleportation, pause, and time management.
|
||||
;; Contains NO graphics code.
|
||||
|
||||
(define-library (pacman-project adt-level)
|
||||
(import (scheme base)
|
||||
(pacman-project constanten)
|
||||
(pacman-project adt-positie)
|
||||
(pacman-project adt-doolhof)
|
||||
(pacman-project constants)
|
||||
(pacman-project adt-position)
|
||||
(pacman-project adt-maze)
|
||||
(pacman-project adt-pacman)
|
||||
(pacman-project adt-sleutel)
|
||||
(pacman-project adt-key)
|
||||
(pacman-project adt-score)
|
||||
(pacman-project adt-tijdslimiet))
|
||||
(export maak-level)
|
||||
(pacman-project adt-timer))
|
||||
(export make-level)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-level :: -> level
|
||||
;; Maakt een nieuw level aan met alle spelobjecten.
|
||||
(define (maak-level)
|
||||
(let ((doolhof (maak-doolhof))
|
||||
(pacman (maak-pacman 5 2))
|
||||
(sleutel #f)
|
||||
(score (maak-score))
|
||||
(tijdslimiet (maak-tijdslimiet))
|
||||
(gepauzeerd? #f))
|
||||
;; make-level :: -> level
|
||||
;; Creates a new level with all game objects.
|
||||
(define (make-level)
|
||||
(let ((maze (make-maze))
|
||||
(pacman (make-pacman 5 2))
|
||||
(key #f)
|
||||
(score (make-score))
|
||||
(timer (make-timer))
|
||||
(paused? #f))
|
||||
|
||||
;; Initialiseer de sleutel nadat het doolhof is aangemaakt.
|
||||
(set! sleutel (maak-sleutel doolhof))
|
||||
;; Initialize key after maze is created.
|
||||
(set! key (make-key maze))
|
||||
|
||||
;;
|
||||
;; Richting helpers
|
||||
;; Direction helpers
|
||||
;;
|
||||
|
||||
;; richting->delta :: symbol -> (number . number)
|
||||
;; Converteert een richting naar een (delta-rij . delta-kolom) paar.
|
||||
(define (richting->delta richting)
|
||||
(cond ((eq? richting 'rechts) (cons 0 1))
|
||||
((eq? richting 'links) (cons 0 -1))
|
||||
((eq? richting 'omhoog) (cons -1 0))
|
||||
((eq? richting 'omlaag) (cons 1 0))
|
||||
;; direction->delta :: symbol -> (number . number)
|
||||
;; Converts a direction to a (delta-row . delta-col) pair.
|
||||
(define (direction->delta direction)
|
||||
(cond ((eq? direction 'right) (cons 0 1))
|
||||
((eq? direction 'left) (cons 0 -1))
|
||||
((eq? direction 'up) (cons -1 0))
|
||||
((eq? direction 'down) (cons 1 0))
|
||||
(else (cons 0 0))))
|
||||
|
||||
;;
|
||||
;; Muntje logica
|
||||
;; Coin logic
|
||||
;;
|
||||
|
||||
;; eet-muntje! :: number, number -> /
|
||||
;; Verwijdert het muntje op de cel en past score/tijd aan.
|
||||
(define (eet-muntje! rij kolom)
|
||||
((doolhof 'cel-set!) rij kolom cel-type-leeg)
|
||||
((score 'verhoog!))
|
||||
((tijdslimiet 'verhoog!)))
|
||||
;; eat-coin! :: number, number -> /
|
||||
;; Removes the coin at the cell and updates score/time.
|
||||
(define (eat-coin! row col)
|
||||
((maze 'cell-set!) row col cell-type-empty)
|
||||
((score 'increase!))
|
||||
((timer 'increase!)))
|
||||
|
||||
;;
|
||||
;; Sleutel logica
|
||||
;; Key logic
|
||||
;;
|
||||
|
||||
;; pak-sleutel-op! :: number, number -> /
|
||||
;; Pakt de sleutel op en maakt de cel leeg.
|
||||
(define (pak-sleutel-op! rij kolom)
|
||||
((doolhof 'cel-set!) rij kolom cel-type-leeg)
|
||||
((sleutel 'pak-op!)))
|
||||
;; pick-up-key! :: number, number -> /
|
||||
;; Picks up the key and clears the cell.
|
||||
(define (pick-up-key! row col)
|
||||
((maze 'cell-set!) row col cell-type-empty)
|
||||
((key 'take!)))
|
||||
|
||||
;;
|
||||
;; Teleportatie logica
|
||||
;; Teleportation logic
|
||||
;;
|
||||
|
||||
;; teleporteer-horizontaal! :: number, number -> /
|
||||
;; Teleporteert Pac-Man naar de andere kant van het doolhof.
|
||||
(define (teleporteer-horizontaal! rij kolom)
|
||||
(let ((pac-pos (pacman 'positie)))
|
||||
(cond ((< kolom 0)
|
||||
((pac-pos 'kolom!) (- (doolhof 'kolommen) 1))
|
||||
((pac-pos 'rij!) rij))
|
||||
((>= kolom (doolhof 'kolommen))
|
||||
((pac-pos 'kolom!) 0)
|
||||
((pac-pos 'rij!) rij)))))
|
||||
;; teleport-horizontal! :: number, number -> /
|
||||
;; Teleports Pac-Man to the other side of the maze.
|
||||
(define (teleport-horizontal! row col)
|
||||
(let ((pac-pos (pacman 'position)))
|
||||
(cond ((< col 0)
|
||||
((pac-pos 'col!) (- (maze 'cols) 1))
|
||||
((pac-pos 'row!) row))
|
||||
((>= col (maze 'cols))
|
||||
((pac-pos 'col!) 0)
|
||||
((pac-pos 'row!) row)))))
|
||||
|
||||
;;
|
||||
;; Bewegingslogica
|
||||
;; Movement logic
|
||||
;;
|
||||
|
||||
;; beweeg-pacman! :: symbol -> /
|
||||
;; Beweegt Pac-Man in de opgegeven richting met alle spelregels.
|
||||
(define (beweeg-pacman! richting)
|
||||
(when (not ((tijdslimiet 'tijd-op?)))
|
||||
(let* ((delta (richting->delta richting))
|
||||
(delta-rij (car delta))
|
||||
(delta-kolom (cdr delta))
|
||||
(huidige-pos (pacman 'positie))
|
||||
(volgende-rij (+ (huidige-pos 'rij) delta-rij))
|
||||
(volgende-kolom (+ (huidige-pos 'kolom) delta-kolom)))
|
||||
;; move-pacman! :: symbol -> /
|
||||
;; Moves Pac-Man in the given direction with all game rules.
|
||||
(define (move-pacman! direction)
|
||||
(when (not ((timer 'time-up?)))
|
||||
(let* ((delta (direction->delta direction))
|
||||
(delta-row (car delta))
|
||||
(delta-col (cdr delta))
|
||||
(current-pos (pacman 'position))
|
||||
(next-row (+ (current-pos 'row) delta-row))
|
||||
(next-col (+ (current-pos 'col) delta-col)))
|
||||
|
||||
;; Pas richting aan voor de teken-laag.
|
||||
((pacman 'richting!) richting)
|
||||
;; Update direction for the draw layer.
|
||||
((pacman 'direction!) direction)
|
||||
|
||||
(cond
|
||||
;; Teleportatie: buiten het grid horizontaal.
|
||||
((or (< volgende-kolom 0) (>= volgende-kolom (doolhof 'kolommen)))
|
||||
(teleporteer-horizontaal! volgende-rij volgende-kolom))
|
||||
;; Teleportation: outside grid horizontally.
|
||||
((or (< next-col 0) (>= next-col (maze 'cols)))
|
||||
(teleport-horizontal! next-row next-col))
|
||||
|
||||
;; Deur: open alleen als de sleutel opgepakt is.
|
||||
(((doolhof 'deur?) volgende-rij volgende-kolom)
|
||||
(when (sleutel 'opgepakt?)
|
||||
((doolhof 'verwijder-deur!) volgende-rij volgende-kolom)))
|
||||
;; Door: only open if key has been taken.
|
||||
(((maze 'door?) next-row next-col)
|
||||
(when (key 'taken?)
|
||||
((maze 'remove-door!) next-row next-col)))
|
||||
|
||||
;; Normale beweging: alleen als het geen muur is.
|
||||
;; Normal movement: only if not a wall.
|
||||
(else
|
||||
(when (not ((doolhof 'muur?) volgende-rij volgende-kolom))
|
||||
((pacman 'beweeg!) delta-rij delta-kolom)
|
||||
;; Controleer wat er op de nieuwe positie staat.
|
||||
(when (not ((maze 'wall?) next-row next-col))
|
||||
((pacman 'move!) delta-row delta-col)
|
||||
;; Check what's at the new position.
|
||||
(cond
|
||||
(((doolhof 'sleutel?) volgende-rij volgende-kolom)
|
||||
(pak-sleutel-op! volgende-rij volgende-kolom))
|
||||
(((doolhof 'muntje?) volgende-rij volgende-kolom)
|
||||
(eet-muntje! volgende-rij volgende-kolom)))))))))
|
||||
(((maze 'key?) next-row next-col)
|
||||
(pick-up-key! next-row next-col))
|
||||
(((maze 'coin?) next-row next-col)
|
||||
(eat-coin! next-row next-col)))))))))
|
||||
|
||||
;;
|
||||
;; Pauze logica
|
||||
;; Pause logic
|
||||
;;
|
||||
|
||||
;; wissel-pauze! :: -> /
|
||||
;; Wisselt de pauzetoestand.
|
||||
(define (wissel-pauze!)
|
||||
(set! gepauzeerd? (not gepauzeerd?)))
|
||||
;; toggle-pause! :: -> /
|
||||
(define (toggle-pause!)
|
||||
(set! paused? (not paused?)))
|
||||
|
||||
;;
|
||||
;; Toets afhandeling
|
||||
;; Key handling
|
||||
;;
|
||||
|
||||
;; toets! :: symbol -> /
|
||||
;; Verwerkt een toetsaanslag.
|
||||
(define (toets! toets)
|
||||
;; key-press! :: symbol -> /
|
||||
;; Processes a key press.
|
||||
(define (key-press! pressed-key)
|
||||
(cond
|
||||
((eq? toets 'escape) (wissel-pauze!))
|
||||
((not gepauzeerd?)
|
||||
((eq? pressed-key 'escape) (toggle-pause!))
|
||||
((not paused?)
|
||||
(cond
|
||||
((eq? toets 'right) (beweeg-pacman! 'rechts))
|
||||
((eq? toets 'left) (beweeg-pacman! 'links))
|
||||
((eq? toets 'up) (beweeg-pacman! 'omhoog))
|
||||
((eq? toets 'down) (beweeg-pacman! 'omlaag))))))
|
||||
((eq? pressed-key 'right) (move-pacman! 'right))
|
||||
((eq? pressed-key 'left) (move-pacman! 'left))
|
||||
((eq? pressed-key 'up) (move-pacman! 'up))
|
||||
((eq? pressed-key 'down) (move-pacman! 'down))))))
|
||||
|
||||
;;
|
||||
;; Update (spellusfunctie)
|
||||
;; Update (game loop function)
|
||||
;;
|
||||
|
||||
;; update! :: number -> /
|
||||
;; Wordt elk frame aangeroepen met het aantal verstreken milliseconden.
|
||||
(define (update! delta-tijd)
|
||||
(when (not gepauzeerd?)
|
||||
((tijdslimiet 'verlaag!) delta-tijd)))
|
||||
;; Called each frame with elapsed milliseconds.
|
||||
(define (update! delta-time)
|
||||
(when (not paused?)
|
||||
((timer 'decrease!) delta-time)))
|
||||
|
||||
;;
|
||||
;; Dispatch
|
||||
;;
|
||||
|
||||
(define (dispatch-level msg)
|
||||
(cond ((eq? msg 'doolhof) doolhof)
|
||||
(cond ((eq? msg 'maze) maze)
|
||||
((eq? msg 'pacman) pacman)
|
||||
((eq? msg 'sleutel) sleutel)
|
||||
((eq? msg 'key) key)
|
||||
((eq? msg 'score) score)
|
||||
((eq? msg 'tijdslimiet) tijdslimiet)
|
||||
((eq? msg 'gepauzeerd?) gepauzeerd?)
|
||||
((eq? msg 'toets!) toets!)
|
||||
((eq? msg 'timer) timer)
|
||||
((eq? msg 'paused?) paused?)
|
||||
((eq? msg 'key-press!) key-press!)
|
||||
((eq? msg 'update!) update!)
|
||||
(else (error "Level ADT -- Onbekend bericht:" msg))))
|
||||
(else (error "Level ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-level))))
|
||||
|
||||
118
pacman-project/adt-maze.rkt
Normal file
118
pacman-project/adt-maze.rkt
Normal file
@@ -0,0 +1,118 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Maze ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; The maze contains the logical grid with cells. Each cell has a type
|
||||
;; (wall, coin, empty, key, door). This ADT contains NO graphics code.
|
||||
|
||||
(define-library (pacman-project adt-maze)
|
||||
(import (scheme base)
|
||||
(pacman-project constants))
|
||||
(export make-maze)
|
||||
|
||||
(begin
|
||||
|
||||
;; make-maze :: -> maze
|
||||
;; Creates a new maze object with the full grid.
|
||||
(define (make-maze)
|
||||
|
||||
;; The maze grid: 31 rows x 28 columns.
|
||||
;; vector is used because it is mutable (unlike #()).
|
||||
(define grid
|
||||
(vector (vector 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 0 0 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 4 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 1)
|
||||
(vector 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1)
|
||||
(vector 2 2 2 2 2 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 1 1 1 4 4 1 1 1 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1)
|
||||
(vector 2 0 0 0 0 0 0 0 0 0 1 2 2 2 2 2 2 1 0 0 0 0 0 0 0 0 0 2)
|
||||
(vector 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 2 2 2 2 2 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 2 2 2 2 2)
|
||||
(vector 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1)
|
||||
(vector 1 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1)
|
||||
(vector 1 1 1 0 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 1 1)
|
||||
(vector 1 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 4 1 0 0 0 0 0 0 1)
|
||||
(vector 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 0 1)
|
||||
(vector 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1)
|
||||
(vector 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
|
||||
(vector 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1)))
|
||||
|
||||
(define num-rows (vector-length grid))
|
||||
(define num-cols (vector-length (vector-ref grid 0)))
|
||||
|
||||
;; cell-ref :: number, number -> number
|
||||
;; Returns the cell type at the given position.
|
||||
(define (cell-ref row col)
|
||||
(vector-ref (vector-ref grid row) col))
|
||||
|
||||
;; cell-set! :: number, number, number -> /
|
||||
;; Sets the cell type at the given position.
|
||||
(define (cell-set! row col value)
|
||||
(vector-set! (vector-ref grid row) col value))
|
||||
|
||||
;; wall? :: number, number -> boolean
|
||||
(define (wall? row col)
|
||||
(= (cell-ref row col) cell-type-wall))
|
||||
|
||||
;; coin? :: number, number -> boolean
|
||||
(define (coin? row col)
|
||||
(= (cell-ref row col) cell-type-coin))
|
||||
|
||||
;; empty? :: number, number -> boolean
|
||||
(define (empty? row col)
|
||||
(= (cell-ref row col) cell-type-empty))
|
||||
|
||||
;; key? :: number, number -> boolean
|
||||
(define (key? row col)
|
||||
(= (cell-ref row col) cell-type-key))
|
||||
|
||||
;; door? :: number, number -> boolean
|
||||
(define (door? row col)
|
||||
(= (cell-ref row col) cell-type-door))
|
||||
|
||||
;; remove-door! :: number, number -> /
|
||||
;; Removes a door from the grid (makes the cell empty).
|
||||
(define (remove-door! row col)
|
||||
(cell-set! row col cell-type-empty))
|
||||
|
||||
;; for-each-cell :: (number, number, number -> /) -> /
|
||||
;; Iterates over all cells, calling callback with row, col, cell-type.
|
||||
(define (for-each-cell callback)
|
||||
(do ((row 0 (+ row 1)))
|
||||
((= row num-rows))
|
||||
(do ((col 0 (+ col 1)))
|
||||
((= col num-cols))
|
||||
(callback row col (cell-ref row col)))))
|
||||
|
||||
;; dispatch-maze :: symbol -> any
|
||||
(define (dispatch-maze msg)
|
||||
(cond ((eq? msg 'rows) num-rows)
|
||||
((eq? msg 'cols) num-cols)
|
||||
((eq? msg 'cell-ref) cell-ref)
|
||||
((eq? msg 'cell-set!) cell-set!)
|
||||
((eq? msg 'wall?) wall?)
|
||||
((eq? msg 'coin?) coin?)
|
||||
((eq? msg 'empty?) empty?)
|
||||
((eq? msg 'key?) key?)
|
||||
((eq? msg 'door?) door?)
|
||||
((eq? msg 'remove-door!) remove-door!)
|
||||
((eq? msg 'for-each-cell) for-each-cell)
|
||||
(else (error "Maze ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-maze)))
|
||||
@@ -4,45 +4,43 @@
|
||||
;; Pac-Man ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Het Pac-Man ADT beheert de logische toestand van de speler: positie op het
|
||||
;; grid en de huidige richting. Bevat GEEN grafische code.
|
||||
;; Manages the logical state of the player: grid position and current
|
||||
;; direction. Contains NO graphics code.
|
||||
|
||||
(define-library (pacman-project adt-pacman)
|
||||
(import (scheme base)
|
||||
(pacman-project adt-positie))
|
||||
(export maak-pacman)
|
||||
(pacman-project adt-position))
|
||||
(export make-pacman)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-pacman :: number, number -> pacman
|
||||
;; Maakt een Pac-Man object aan op de opgegeven startpositie (rij, kolom).
|
||||
(define (maak-pacman start-rij start-kolom)
|
||||
(let ((positie (maak-positie start-rij start-kolom))
|
||||
(richting 'rechts))
|
||||
;; make-pacman :: number, number -> pacman
|
||||
;; Creates a Pac-Man object at the given start position (row, col).
|
||||
(define (make-pacman start-row start-col)
|
||||
(let ((position (make-position start-row start-col))
|
||||
(direction 'right))
|
||||
|
||||
;; positie! :: positie -> /
|
||||
;; Vervangt de huidige positie.
|
||||
(define (positie! nieuwe-positie)
|
||||
(set! positie nieuwe-positie))
|
||||
;; position! :: position -> /
|
||||
(define (position! new-position)
|
||||
(set! position new-position))
|
||||
|
||||
;; richting! :: symbol -> /
|
||||
;; Past de huidige richting aan.
|
||||
(define (richting! nieuwe-richting)
|
||||
(set! richting nieuwe-richting))
|
||||
;; direction! :: symbol -> /
|
||||
(define (direction! new-direction)
|
||||
(set! direction new-direction))
|
||||
|
||||
;; beweeg! :: number, number -> /
|
||||
;; Verplaatst Pac-Man met een delta op het grid.
|
||||
(define (beweeg! delta-rij delta-kolom)
|
||||
((positie 'rij!) (+ (positie 'rij) delta-rij))
|
||||
((positie 'kolom!) (+ (positie 'kolom) delta-kolom)))
|
||||
;; move! :: number, number -> /
|
||||
;; Moves Pac-Man by a delta on the grid.
|
||||
(define (move! delta-row delta-col)
|
||||
((position 'row!) (+ (position 'row) delta-row))
|
||||
((position 'col!) (+ (position 'col) delta-col)))
|
||||
|
||||
;; dispatch-pacman :: symbol -> any
|
||||
(define (dispatch-pacman msg)
|
||||
(cond ((eq? msg 'positie) positie)
|
||||
((eq? msg 'positie!) positie!)
|
||||
((eq? msg 'richting) richting)
|
||||
((eq? msg 'richting!) richting!)
|
||||
((eq? msg 'beweeg!) beweeg!)
|
||||
(else (error "Pac-Man ADT -- Onbekend bericht:" msg))))
|
||||
(cond ((eq? msg 'position) position)
|
||||
((eq? msg 'position!) position!)
|
||||
((eq? msg 'direction) direction)
|
||||
((eq? msg 'direction!) direction!)
|
||||
((eq? msg 'move!) move!)
|
||||
(else (error "Pac-Man ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-pacman))))
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Positie ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Een positie stelt een locatie voor op het logische grid van het doolhof.
|
||||
;; Coordinaten zijn in grid-eenheden (rij, kolom), NIET in pixels.
|
||||
|
||||
(define-library (pacman-project adt-positie)
|
||||
(import (scheme base))
|
||||
(export maak-positie)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-positie :: number, number -> positie
|
||||
;; Maakt een nieuw positie-object aan met rij en kolom op het grid.
|
||||
(define (maak-positie rij kolom)
|
||||
|
||||
;; rij! :: number -> /
|
||||
;; Past de rij-coordinaat aan.
|
||||
(define (rij! nieuwe-rij)
|
||||
(set! rij nieuwe-rij))
|
||||
|
||||
;; kolom! :: number -> /
|
||||
;; Past de kolom-coordinaat aan.
|
||||
(define (kolom! nieuwe-kolom)
|
||||
(set! kolom nieuwe-kolom))
|
||||
|
||||
;; vergelijk? :: positie -> boolean
|
||||
;; Controleert of twee posities dezelfde coordinaten hebben.
|
||||
(define (vergelijk? andere-positie)
|
||||
(and (= rij (andere-positie 'rij))
|
||||
(= kolom (andere-positie 'kolom))))
|
||||
|
||||
;; beweeg :: number, number -> positie
|
||||
;; Geeft een nieuwe positie terug verschoven met delta-rij en delta-kolom.
|
||||
(define (beweeg delta-rij delta-kolom)
|
||||
(maak-positie (+ rij delta-rij)
|
||||
(+ kolom delta-kolom)))
|
||||
|
||||
;; dispatch-positie :: symbol -> any
|
||||
(define (dispatch-positie msg)
|
||||
(cond ((eq? msg 'rij) rij)
|
||||
((eq? msg 'kolom) kolom)
|
||||
((eq? msg 'rij!) rij!)
|
||||
((eq? msg 'kolom!) kolom!)
|
||||
((eq? msg 'vergelijk?) vergelijk?)
|
||||
((eq? msg 'beweeg) beweeg)
|
||||
(else (error "Positie ADT -- Onbekend bericht:" msg))))
|
||||
|
||||
dispatch-positie)))
|
||||
50
pacman-project/adt-position.rkt
Normal file
50
pacman-project/adt-position.rkt
Normal file
@@ -0,0 +1,50 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Position ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; A position represents a location on the logical maze grid.
|
||||
;; Coordinates are in grid units (row, col), NOT pixels.
|
||||
|
||||
(define-library (pacman-project adt-position)
|
||||
(import (scheme base))
|
||||
(export make-position)
|
||||
|
||||
(begin
|
||||
|
||||
;; make-position :: number, number -> position
|
||||
;; Creates a new position object with row and column on the grid.
|
||||
(define (make-position row col)
|
||||
|
||||
;; row! :: number -> /
|
||||
(define (row! new-row)
|
||||
(set! row new-row))
|
||||
|
||||
;; col! :: number -> /
|
||||
(define (col! new-col)
|
||||
(set! col new-col))
|
||||
|
||||
;; equal? :: position -> boolean
|
||||
;; Checks whether two positions have the same coordinates.
|
||||
(define (equal? other)
|
||||
(and (= row (other 'row))
|
||||
(= col (other 'col))))
|
||||
|
||||
;; move :: number, number -> position
|
||||
;; Returns a new position shifted by delta-row and delta-col.
|
||||
(define (move delta-row delta-col)
|
||||
(make-position (+ row delta-row)
|
||||
(+ col delta-col)))
|
||||
|
||||
;; dispatch-position :: symbol -> any
|
||||
(define (dispatch-position msg)
|
||||
(cond ((eq? msg 'row) row)
|
||||
((eq? msg 'col) col)
|
||||
((eq? msg 'row!) row!)
|
||||
((eq? msg 'col!) col!)
|
||||
((eq? msg 'equal?) equal?)
|
||||
((eq? msg 'move) move)
|
||||
(else (error "Position ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-position)))
|
||||
@@ -4,29 +4,29 @@
|
||||
;; Score ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Houdt de score bij. Bevat GEEN grafische code.
|
||||
;; Tracks the player's score. Contains NO graphics code.
|
||||
|
||||
(define-library (pacman-project adt-score)
|
||||
(import (scheme base)
|
||||
(pacman-project constanten))
|
||||
(export maak-score)
|
||||
(pacman-project constants))
|
||||
(export make-score)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-score :: -> score
|
||||
;; Maakt een nieuw score-object aan, startend bij 0.
|
||||
(define (maak-score)
|
||||
(let ((punten 0))
|
||||
;; make-score :: -> score
|
||||
;; Creates a new score object, starting at 0.
|
||||
(define (make-score)
|
||||
(let ((points 0))
|
||||
|
||||
;; verhoog! :: -> /
|
||||
;; Verhoogt de score met het aantal punten per muntje.
|
||||
(define (verhoog!)
|
||||
(set! punten (+ punten punten-per-muntje)))
|
||||
;; increase! :: -> /
|
||||
;; Increases the score by points-per-coin.
|
||||
(define (increase!)
|
||||
(set! points (+ points points-per-coin)))
|
||||
|
||||
;; dispatch-score :: symbol -> any
|
||||
(define (dispatch-score msg)
|
||||
(cond ((eq? msg 'punten) punten)
|
||||
((eq? msg 'verhoog!) verhoog!)
|
||||
(else (error "Score ADT -- Onbekend bericht:" msg))))
|
||||
(cond ((eq? msg 'points) points)
|
||||
((eq? msg 'increase!) increase!)
|
||||
(else (error "Score ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-score))))
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
(#%require (only racket/base random))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Sleutel ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; De sleutel is een object dat op een willekeurige positie in het doolhof
|
||||
;; geplaatst wordt. Wanneer Pac-Man de sleutel oppakt, worden deuren geopend.
|
||||
;; Bevat GEEN grafische code.
|
||||
|
||||
(define-library (pacman-project adt-sleutel)
|
||||
(import (scheme base)
|
||||
(pacman-project constanten)
|
||||
(pacman-project adt-positie))
|
||||
(export maak-sleutel)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-sleutel :: doolhof -> sleutel
|
||||
;; Maakt een sleutel aan en plaatst deze op een willekeurige muntje-positie.
|
||||
(define (maak-sleutel doolhof)
|
||||
(let ((positie #f)
|
||||
(opgepakt? #f))
|
||||
|
||||
;; plaats-willekeurig! :: -> /
|
||||
;; Plaatst de sleutel op een willekeurige cel waar een muntje staat.
|
||||
(define (plaats-willekeurig!)
|
||||
(let loop ((pogingen 0))
|
||||
(if (>= pogingen max-plaatsing-pogingen)
|
||||
(error "Geen geldige positie gevonden voor sleutel")
|
||||
(let ((kolom (random 0 (doolhof 'kolommen)))
|
||||
(rij (random 0 (doolhof 'rijen))))
|
||||
(if ((doolhof 'muntje?) rij kolom)
|
||||
(begin
|
||||
(set! positie (maak-positie rij kolom))
|
||||
((doolhof 'cel-set!) rij kolom cel-type-sleutel))
|
||||
(loop (+ pogingen 1)))))))
|
||||
|
||||
;; pak-op! :: -> /
|
||||
;; Markeert de sleutel als opgepakt.
|
||||
(define (pak-op!)
|
||||
(set! opgepakt? #t))
|
||||
|
||||
;; Initialisatie: plaats de sleutel direct bij aanmaak.
|
||||
(plaats-willekeurig!)
|
||||
|
||||
;; dispatch-sleutel :: symbol -> any
|
||||
(define (dispatch-sleutel msg)
|
||||
(cond ((eq? msg 'positie) positie)
|
||||
((eq? msg 'opgepakt?) opgepakt?)
|
||||
((eq? msg 'pak-op!) pak-op!)
|
||||
(else (error "Sleutel ADT -- Onbekend bericht:" msg))))
|
||||
|
||||
dispatch-sleutel))))
|
||||
@@ -1,49 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Spel ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Het top-level spel-object dat het level verbindt met het teken-ADT.
|
||||
;; Registreert de callbacks voor de spellus, toetsen en tekenen.
|
||||
|
||||
(define-library (pacman-project adt-spel)
|
||||
(import (scheme base)
|
||||
(pacman-project constanten)
|
||||
(pacman-project adt-level)
|
||||
(pacman-project adt-teken))
|
||||
(export maak-spel)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-spel :: -> spel
|
||||
;; Maakt het spel-object aan.
|
||||
(define (maak-spel)
|
||||
(let ((level (maak-level))
|
||||
(teken (maak-teken venster-breedte-px venster-hoogte-px)))
|
||||
|
||||
;; toets-procedure :: symbol, any -> /
|
||||
;; Verwerkt toetsaanslagen en stuurt ze door naar het level.
|
||||
(define (toets-procedure status toets)
|
||||
(when (eq? status 'pressed)
|
||||
((level 'toets!) toets)))
|
||||
|
||||
;; spel-lus-procedure :: number -> /
|
||||
;; Wordt elk frame aangeroepen voor game-state updates.
|
||||
(define (spel-lus-procedure delta-tijd)
|
||||
((level 'update!) delta-tijd))
|
||||
|
||||
;; start! :: -> /
|
||||
;; Start het spel door alle callbacks te registreren.
|
||||
(define (start!)
|
||||
((teken 'set-spel-lus-functie!) spel-lus-procedure)
|
||||
((teken 'set-toets-functie!) toets-procedure)
|
||||
((teken 'start-tekenen!) dispatch-spel))
|
||||
|
||||
;; dispatch-spel :: symbol -> any
|
||||
(define (dispatch-spel msg)
|
||||
(cond ((eq? msg 'start!) start!)
|
||||
((eq? msg 'level) level)
|
||||
(else (error "Spel ADT -- Onbekend bericht:" msg))))
|
||||
|
||||
dispatch-spel))))
|
||||
@@ -1,252 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Teken ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Alle grafische logica is geisoleerd in dit ADT. De spellogica kent niets
|
||||
;; over pixels, vensters of sprites. De omzetting van grid-coordinaten naar
|
||||
;; schermcoordinaten gebeurt uitsluitend hier.
|
||||
|
||||
(define-library (pacman-project adt-teken)
|
||||
(import (scheme base)
|
||||
(pp1 graphics)
|
||||
(pacman-project constanten))
|
||||
(export maak-teken)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-teken :: number, number -> teken
|
||||
;; Maakt het teken-object aan dat alle grafische weergave verzorgt.
|
||||
(define (maak-teken breedte hoogte)
|
||||
(let ((venster (make-window breedte hoogte "Pacman")))
|
||||
|
||||
((venster 'set-background!) "black")
|
||||
|
||||
;;
|
||||
;; Lagen aanmaken (volgorde bepaalt tekenvolgorde)
|
||||
;;
|
||||
|
||||
(define doolhof-laag ((venster 'new-layer!)))
|
||||
(define muntjes-laag ((venster 'new-layer!)))
|
||||
(define sleutel-laag ((venster 'new-layer!)))
|
||||
(define pacman-laag ((venster 'new-layer!)))
|
||||
(define ui-laag ((venster 'new-layer!)))
|
||||
(define pauze-laag ((venster 'new-layer!)))
|
||||
|
||||
;;
|
||||
;; Doolhof tiles
|
||||
;;
|
||||
|
||||
(define doolhof-tile (make-tile breedte hoogte))
|
||||
((doolhof-laag 'add-drawable!) doolhof-tile)
|
||||
|
||||
;;
|
||||
;; Muntjes tile
|
||||
;;
|
||||
|
||||
(define muntjes-tile (make-tile breedte hoogte))
|
||||
((muntjes-laag 'add-drawable!) muntjes-tile)
|
||||
|
||||
;;
|
||||
;; Sleutel sprite (in het doolhof)
|
||||
;;
|
||||
|
||||
(define sleutel-sprite (make-bitmap-tile "pacman-sprites/key.png"))
|
||||
((sleutel-sprite 'set-scale!) sprite-schaal-sleutel)
|
||||
((sleutel-laag 'add-drawable!) sleutel-sprite)
|
||||
|
||||
;; Sleutel UI indicator (naast de score)
|
||||
(define sleutel-ui-sprite (make-bitmap-tile "pacman-sprites/key.png"))
|
||||
((sleutel-ui-sprite 'set-scale!) sprite-schaal-sleutel-ui)
|
||||
((sleutel-ui-sprite 'set-x!) sleutel-ui-x)
|
||||
((sleutel-ui-sprite 'set-y!) sleutel-ui-y)
|
||||
|
||||
;;
|
||||
;; Pac-Man sprite
|
||||
;;
|
||||
|
||||
(define pacman-bitmap-tiles
|
||||
(list (make-bitmap-tile "pacman-sprites/pacman-death-1.png")
|
||||
(make-bitmap-tile "pacman-sprites/pacman-closed.png")
|
||||
(make-bitmap-tile "pacman-sprites/pacman-open.png")))
|
||||
|
||||
(define pacman-sprite (make-tile-sequence pacman-bitmap-tiles))
|
||||
((pacman-sprite 'set-scale!) sprite-schaal-pacman)
|
||||
((pacman-laag 'add-drawable!) pacman-sprite)
|
||||
|
||||
;; Animatie state
|
||||
(define tijd-sinds-laatste-animatie 0)
|
||||
|
||||
;;
|
||||
;; UI tiles
|
||||
;;
|
||||
|
||||
(define ui-tile (make-tile breedte hoogte))
|
||||
((ui-laag 'add-drawable!) ui-tile)
|
||||
|
||||
;;
|
||||
;; Coordinaat conversie
|
||||
;;
|
||||
|
||||
;; grid->pixel-x :: number -> number
|
||||
;; Converteert een grid kolom naar een pixel x-coordinaat.
|
||||
(define (grid->pixel-x kolom)
|
||||
(* cel-grootte-px kolom))
|
||||
|
||||
;; grid->pixel-y :: number -> number
|
||||
;; Converteert een grid rij naar een pixel y-coordinaat.
|
||||
(define (grid->pixel-y rij)
|
||||
(+ (* rij cel-grootte-px) doolhof-offset-y))
|
||||
|
||||
;;
|
||||
;; Teken functies
|
||||
;;
|
||||
|
||||
;; teken-doolhof! :: doolhof -> /
|
||||
;; Tekent alle muren en deuren van het doolhof.
|
||||
(define (teken-doolhof! doolhof)
|
||||
((doolhof 'voor-elke-cel)
|
||||
(lambda (rij kolom celtype)
|
||||
(cond
|
||||
((= celtype cel-type-muur)
|
||||
((doolhof-tile 'draw-rectangle!)
|
||||
(grid->pixel-x kolom)
|
||||
(grid->pixel-y rij)
|
||||
(- cel-grootte-px doolhof-muur-krimp)
|
||||
(- cel-grootte-px doolhof-muur-krimp)
|
||||
"blue"))
|
||||
((= celtype cel-type-deur)
|
||||
((doolhof-tile 'draw-rectangle!)
|
||||
(grid->pixel-x kolom)
|
||||
(grid->pixel-y rij)
|
||||
(- cel-grootte-px doolhof-muur-krimp)
|
||||
(- cel-grootte-px doolhof-muur-krimp)
|
||||
"pink"))))))
|
||||
|
||||
;; teken-muntjes! :: doolhof -> /
|
||||
;; Tekent alle muntjes in het doolhof.
|
||||
(define (teken-muntjes! doolhof)
|
||||
((muntjes-tile 'clear!))
|
||||
((doolhof 'voor-elke-cel)
|
||||
(lambda (rij kolom celtype)
|
||||
(when (= celtype cel-type-muntje)
|
||||
((muntjes-tile 'draw-rectangle!)
|
||||
(+ (grid->pixel-x kolom) muntje-inset)
|
||||
(+ (grid->pixel-y rij) muntje-inset)
|
||||
(- cel-grootte-px (* 2 muntje-inset) 6)
|
||||
(- cel-grootte-px (* 2 muntje-inset) 6)
|
||||
"yellow")))))
|
||||
|
||||
;; teken-sleutel! :: sleutel -> /
|
||||
;; Tekent de sleutel op haar positie, of verbergt ze als opgepakt.
|
||||
(define (teken-sleutel! sleutel)
|
||||
(if (sleutel 'opgepakt?)
|
||||
(begin
|
||||
((sleutel-laag 'remove-drawable!) sleutel-sprite)
|
||||
((sleutel-laag 'add-drawable!) sleutel-ui-sprite))
|
||||
(let ((pos (sleutel 'positie)))
|
||||
((sleutel-sprite 'set-x!) (grid->pixel-x (pos 'kolom)))
|
||||
((sleutel-sprite 'set-y!) (grid->pixel-y (pos 'rij))))))
|
||||
|
||||
;; teken-pacman! :: pacman, number -> /
|
||||
;; Tekent Pac-Man op zijn huidige positie met de juiste rotatie.
|
||||
(define (teken-pacman! pacman delta-tijd)
|
||||
(let* ((pos (pacman 'positie))
|
||||
(richting (pacman 'richting)))
|
||||
;; Positie instellen
|
||||
((pacman-sprite 'set-x!) (grid->pixel-x (pos 'kolom)))
|
||||
((pacman-sprite 'set-y!) (grid->pixel-y (pos 'rij)))
|
||||
;; Rotatie instellen op basis van richting
|
||||
(cond ((eq? richting 'rechts) ((pacman-sprite 'rotate!) rotatie-rechts))
|
||||
((eq? richting 'links) ((pacman-sprite 'rotate!) rotatie-links))
|
||||
((eq? richting 'omhoog) ((pacman-sprite 'rotate!) rotatie-omhoog))
|
||||
((eq? richting 'omlaag) ((pacman-sprite 'rotate!) rotatie-omlaag)))
|
||||
;; Animatie
|
||||
(set! tijd-sinds-laatste-animatie (+ tijd-sinds-laatste-animatie delta-tijd))
|
||||
(when (>= tijd-sinds-laatste-animatie animatie-interval-ms)
|
||||
((pacman-sprite 'set-next!))
|
||||
(set! tijd-sinds-laatste-animatie 0))))
|
||||
|
||||
;; teken-ui! :: score, tijdslimiet -> /
|
||||
;; Tekent de score en de tijdslimiet op het scherm.
|
||||
(define (teken-ui! score tijdslimiet)
|
||||
((ui-tile 'clear!))
|
||||
;; Score
|
||||
((ui-tile 'draw-text!)
|
||||
(number->string (score 'punten))
|
||||
score-tekst-grootte score-tekst-x score-tekst-y "white")
|
||||
;; Scheidingslijn
|
||||
((ui-tile 'draw-rectangle!)
|
||||
scheidingslijn-x 0 scheidingslijn-breedte hoogte "white")
|
||||
;; Tijdslimiet
|
||||
((ui-tile 'draw-text!)
|
||||
"Time remaining:" tijd-tekst-grootte tijd-label-x tijd-label-y "white")
|
||||
((ui-tile 'draw-text!)
|
||||
((tijdslimiet 'formatteer-tijd))
|
||||
score-tekst-grootte tijd-waarde-x tijd-waarde-y "white"))
|
||||
|
||||
;; teken-pauze! :: boolean -> /
|
||||
;; Toont of verbergt het pauzescherm.
|
||||
(define (teken-pauze! gepauzeerd?)
|
||||
((pauze-laag 'empty!))
|
||||
(when gepauzeerd?
|
||||
(let ((pauze-tile (make-tile breedte hoogte)))
|
||||
((pauze-laag 'add-drawable!) pauze-tile)
|
||||
((pauze-tile 'draw-rectangle!) 0 90 670 hoogte "black")
|
||||
((pauze-tile 'draw-text!) "Game Paused" 40 200 400 "red"))))
|
||||
|
||||
;; herteken-doolhof! :: doolhof -> /
|
||||
;; Hertekent het doolhof (na deur verwijdering).
|
||||
(define (herteken-doolhof! doolhof)
|
||||
((doolhof-tile 'clear!))
|
||||
(teken-doolhof! doolhof))
|
||||
|
||||
;;
|
||||
;; Hoofdtekenfunctie
|
||||
;;
|
||||
|
||||
;; teken-spel! :: spel -> /
|
||||
;; Tekent het volledige spel (wordt als draw-callback geregistreerd).
|
||||
(define (teken-spel! spel)
|
||||
(let ((level (spel 'level)))
|
||||
(teken-pacman! (level 'pacman) 0)
|
||||
(teken-sleutel! (level 'sleutel))
|
||||
(teken-muntjes! (level 'doolhof))
|
||||
(teken-ui! (level 'score) (level 'tijdslimiet))
|
||||
(teken-pauze! (level 'gepauzeerd?))))
|
||||
|
||||
;;
|
||||
;; Callbacks instellen
|
||||
;;
|
||||
|
||||
;; set-spel-lus-functie! :: (number -> /) -> /
|
||||
;; Registreert de update-callback.
|
||||
(define (set-spel-lus-functie! fun)
|
||||
((venster 'set-update-callback!) fun))
|
||||
|
||||
;; set-toets-functie! :: (symbol, any -> /) -> /
|
||||
;; Registreert de keyboard-callback.
|
||||
(define (set-toets-functie! fun)
|
||||
((venster 'set-key-callback!) fun))
|
||||
|
||||
;; start-tekenen! :: spel -> /
|
||||
;; Start het tekenen door de draw-callback in te stellen.
|
||||
(define (start-tekenen! spel)
|
||||
;; Initieel doolhof en muntjes tekenen (eenmalig)
|
||||
(teken-doolhof! ((spel 'level) 'doolhof))
|
||||
(teken-muntjes! ((spel 'level) 'doolhof))
|
||||
((venster 'set-draw-callback!)
|
||||
(lambda () (teken-spel! spel))))
|
||||
|
||||
;;
|
||||
;; Dispatch
|
||||
;;
|
||||
|
||||
(define (dispatch-teken msg)
|
||||
(cond ((eq? msg 'set-spel-lus-functie!) set-spel-lus-functie!)
|
||||
((eq? msg 'set-toets-functie!) set-toets-functie!)
|
||||
((eq? msg 'start-tekenen!) start-tekenen!)
|
||||
(else (error "Teken ADT -- Onbekend bericht:" msg))))
|
||||
|
||||
dispatch-teken))))
|
||||
@@ -1,63 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tijdslimiet ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Beheert de aftellende tijdslimiet van het spel. Bevat GEEN grafische code.
|
||||
|
||||
(define-library (pacman-project adt-tijdslimiet)
|
||||
(import (scheme base)
|
||||
(pacman-project constanten))
|
||||
(export maak-tijdslimiet)
|
||||
|
||||
(begin
|
||||
|
||||
;; maak-tijdslimiet :: -> tijdslimiet
|
||||
;; Maakt een nieuw tijdslimiet-object aan.
|
||||
(define (maak-tijdslimiet)
|
||||
(let ((resterende-tijd start-tijd-seconden)
|
||||
(tijd-sinds-laatste-tick 0))
|
||||
|
||||
;; verlaag! :: number -> /
|
||||
;; Verlaagt de tijd op basis van het aantal verstreken milliseconden.
|
||||
(define (verlaag! ms)
|
||||
(set! tijd-sinds-laatste-tick (+ tijd-sinds-laatste-tick ms))
|
||||
(when (>= tijd-sinds-laatste-tick ms-per-seconde)
|
||||
(set! tijd-sinds-laatste-tick 0)
|
||||
(when (> resterende-tijd 0)
|
||||
(set! resterende-tijd (- resterende-tijd 1)))))
|
||||
|
||||
;; verhoog! :: -> /
|
||||
;; Verhoogt de resterende tijd met een bonus (bij het eten van een muntje).
|
||||
(define (verhoog!)
|
||||
(set! resterende-tijd (+ resterende-tijd tijd-bonus-per-muntje)))
|
||||
|
||||
;; tijd-op? :: -> boolean
|
||||
;; Controleert of de tijd verstreken is.
|
||||
(define (tijd-op?)
|
||||
(= resterende-tijd 0))
|
||||
|
||||
;; formatteer-tijd :: -> string
|
||||
;; Geeft de resterende tijd terug als "m:ss" string.
|
||||
(define (formatteer-tijd)
|
||||
(let* ((minuten (quotient resterende-tijd 60))
|
||||
(seconden (remainder resterende-tijd 60))
|
||||
(min-str (number->string minuten))
|
||||
(sec-str (number->string seconden)))
|
||||
(string-append min-str
|
||||
":"
|
||||
(if (< seconden 10)
|
||||
(string-append "0" sec-str)
|
||||
sec-str))))
|
||||
|
||||
;; dispatch-tijdslimiet :: symbol -> any
|
||||
(define (dispatch-tijdslimiet msg)
|
||||
(cond ((eq? msg 'resterende-tijd) resterende-tijd)
|
||||
((eq? msg 'verlaag!) verlaag!)
|
||||
((eq? msg 'verhoog!) verhoog!)
|
||||
((eq? msg 'tijd-op?) tijd-op?)
|
||||
((eq? msg 'formatteer-tijd) formatteer-tijd)
|
||||
(else (error "Tijdslimiet ADT -- Onbekend bericht:" msg))))
|
||||
|
||||
dispatch-tijdslimiet))))
|
||||
62
pacman-project/adt-timer.rkt
Normal file
62
pacman-project/adt-timer.rkt
Normal file
@@ -0,0 +1,62 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Timer ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Manages the countdown time limit. Contains NO graphics code.
|
||||
|
||||
(define-library (pacman-project adt-timer)
|
||||
(import (scheme base)
|
||||
(pacman-project constants))
|
||||
(export make-timer)
|
||||
|
||||
(begin
|
||||
|
||||
;; make-timer :: -> timer
|
||||
;; Creates a new timer object.
|
||||
(define (make-timer)
|
||||
(let ((remaining-time start-time-seconds)
|
||||
(time-since-last-tick 0))
|
||||
|
||||
;; decrease! :: number -> /
|
||||
;; Decreases time based on elapsed milliseconds.
|
||||
(define (decrease! ms)
|
||||
(set! time-since-last-tick (+ time-since-last-tick ms))
|
||||
(when (>= time-since-last-tick ms-per-second)
|
||||
(set! time-since-last-tick 0)
|
||||
(when (> remaining-time 0)
|
||||
(set! remaining-time (- remaining-time 1)))))
|
||||
|
||||
;; increase! :: -> /
|
||||
;; Adds a time bonus (when eating a coin).
|
||||
(define (increase!)
|
||||
(set! remaining-time (+ remaining-time time-bonus-per-coin)))
|
||||
|
||||
;; time-up? :: -> boolean
|
||||
(define (time-up?)
|
||||
(= remaining-time 0))
|
||||
|
||||
;; format-time :: -> string
|
||||
;; Returns remaining time as "m:ss" string.
|
||||
(define (format-time)
|
||||
(let* ((minutes (quotient remaining-time 60))
|
||||
(seconds (remainder remaining-time 60))
|
||||
(min-str (number->string minutes))
|
||||
(sec-str (number->string seconds)))
|
||||
(string-append min-str
|
||||
":"
|
||||
(if (< seconds 10)
|
||||
(string-append "0" sec-str)
|
||||
sec-str))))
|
||||
|
||||
;; dispatch-timer :: symbol -> any
|
||||
(define (dispatch-timer msg)
|
||||
(cond ((eq? msg 'remaining-time) remaining-time)
|
||||
((eq? msg 'decrease!) decrease!)
|
||||
((eq? msg 'increase!) increase!)
|
||||
((eq? msg 'time-up?) time-up?)
|
||||
((eq? msg 'format-time) format-time)
|
||||
(else (error "Timer ADT -- Unknown message:" msg))))
|
||||
|
||||
dispatch-timer))))
|
||||
@@ -1,135 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Constanten ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Alle configuratieconstanten voor het Pac-Man spel worden hier gedefinieerd.
|
||||
;; Dit voorkomt "magic constants" doorheen de code en maakt het spel flexibel
|
||||
;; aanpasbaar.
|
||||
|
||||
(define-library (pacman-project constanten)
|
||||
(import (scheme base))
|
||||
(export ;; Venster
|
||||
venster-breedte-px
|
||||
venster-hoogte-px
|
||||
|
||||
;; Doolhof grid
|
||||
cel-grootte-px
|
||||
doolhof-offset-y
|
||||
doolhof-muur-krimp
|
||||
|
||||
;; Cel types
|
||||
cel-type-muntje
|
||||
cel-type-muur
|
||||
cel-type-leeg
|
||||
cel-type-sleutel
|
||||
cel-type-deur
|
||||
|
||||
;; Muntje weergave
|
||||
muntje-inset
|
||||
|
||||
;; Sprites
|
||||
sprite-schaal-pacman
|
||||
sprite-schaal-sleutel
|
||||
sprite-schaal-sleutel-ui
|
||||
|
||||
;; Animatie
|
||||
animatie-interval-ms
|
||||
|
||||
;; Score
|
||||
punten-per-muntje
|
||||
|
||||
;; Tijdslimiet
|
||||
start-tijd-seconden
|
||||
ms-per-seconde
|
||||
tijd-bonus-per-muntje
|
||||
|
||||
;; Sleutel plaatsing
|
||||
max-plaatsing-pogingen
|
||||
|
||||
;; Rotatie hoeken
|
||||
rotatie-rechts
|
||||
rotatie-links
|
||||
rotatie-omhoog
|
||||
rotatie-omlaag
|
||||
|
||||
;; UI posities
|
||||
score-tekst-grootte
|
||||
score-tekst-x
|
||||
score-tekst-y
|
||||
tijd-tekst-grootte
|
||||
tijd-label-x
|
||||
tijd-label-y
|
||||
tijd-waarde-x
|
||||
tijd-waarde-y
|
||||
scheidingslijn-x
|
||||
scheidingslijn-breedte
|
||||
sleutel-ui-x
|
||||
sleutel-ui-y)
|
||||
|
||||
(begin
|
||||
|
||||
;; Venster dimensies
|
||||
(define venster-breedte-px 1000)
|
||||
(define venster-hoogte-px 830)
|
||||
|
||||
;; Doolhof grid configuratie
|
||||
(define cel-grootte-px 24)
|
||||
(define doolhof-offset-y 97)
|
||||
(define doolhof-muur-krimp 6)
|
||||
|
||||
;; Cel type encodering voor het doolhof grid
|
||||
(define cel-type-muntje 0)
|
||||
(define cel-type-muur 1)
|
||||
(define cel-type-leeg 2)
|
||||
(define cel-type-sleutel 3)
|
||||
(define cel-type-deur 4)
|
||||
|
||||
;; Muntje weergave: inset in pixels ten opzichte van cel rand
|
||||
(define muntje-inset 7)
|
||||
|
||||
;; Sprite schaalfactoren
|
||||
(define sprite-schaal-pacman 1.5)
|
||||
(define sprite-schaal-sleutel 1.5)
|
||||
(define sprite-schaal-sleutel-ui 3)
|
||||
|
||||
;; Animatie timing
|
||||
(define animatie-interval-ms 100)
|
||||
|
||||
;; Score configuratie
|
||||
(define punten-per-muntje 10)
|
||||
|
||||
;; Tijdslimiet configuratie
|
||||
(define start-tijd-seconden 60)
|
||||
(define ms-per-seconde 1000)
|
||||
(define tijd-bonus-per-muntje 1)
|
||||
|
||||
;; Sleutel plaatsing
|
||||
(define max-plaatsing-pogingen 1000)
|
||||
|
||||
;; Rotatie hoeken (graden)
|
||||
(define rotatie-rechts 0)
|
||||
(define rotatie-links 180)
|
||||
(define rotatie-omhoog 90)
|
||||
(define rotatie-omlaag -90)
|
||||
|
||||
;; UI posities voor score weergave
|
||||
(define score-tekst-grootte 40)
|
||||
(define score-tekst-x 560)
|
||||
(define score-tekst-y 20)
|
||||
|
||||
;; UI posities voor tijd weergave
|
||||
(define tijd-tekst-grootte 35)
|
||||
(define tijd-label-x 300)
|
||||
(define tijd-label-y 710)
|
||||
(define tijd-waarde-x 400)
|
||||
(define tijd-waarde-y 800)
|
||||
|
||||
;; Scheidingslijn tussen speelveld en UI
|
||||
(define scheidingslijn-x 670)
|
||||
(define scheidingslijn-breedte 24)
|
||||
|
||||
;; Sleutel UI positie (naast score)
|
||||
(define sleutel-ui-x 20)
|
||||
(define sleutel-ui-y 35)))
|
||||
134
pacman-project/constants.rkt
Normal file
134
pacman-project/constants.rkt
Normal file
@@ -0,0 +1,134 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Constants ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; All configuration constants for the Pac-Man game. Prevents magic numbers
|
||||
;; throughout the codebase and makes the game easily configurable.
|
||||
|
||||
(define-library (pacman-project constants)
|
||||
(import (scheme base))
|
||||
(export ;; Window
|
||||
window-width-px
|
||||
window-height-px
|
||||
|
||||
;; Maze grid
|
||||
cell-size-px
|
||||
maze-offset-y
|
||||
maze-wall-shrink
|
||||
|
||||
;; Cell types
|
||||
cell-type-coin
|
||||
cell-type-wall
|
||||
cell-type-empty
|
||||
cell-type-key
|
||||
cell-type-door
|
||||
|
||||
;; Coin rendering
|
||||
coin-inset
|
||||
|
||||
;; Sprites
|
||||
sprite-scale-pacman
|
||||
sprite-scale-key
|
||||
sprite-scale-key-ui
|
||||
|
||||
;; Animation
|
||||
animation-interval-ms
|
||||
|
||||
;; Score
|
||||
points-per-coin
|
||||
|
||||
;; Time limit
|
||||
start-time-seconds
|
||||
ms-per-second
|
||||
time-bonus-per-coin
|
||||
|
||||
;; Key placement
|
||||
max-placement-attempts
|
||||
|
||||
;; Rotation angles
|
||||
rotation-right
|
||||
rotation-left
|
||||
rotation-up
|
||||
rotation-down
|
||||
|
||||
;; UI positions
|
||||
score-text-size
|
||||
score-text-x
|
||||
score-text-y
|
||||
time-text-size
|
||||
time-label-x
|
||||
time-label-y
|
||||
time-value-x
|
||||
time-value-y
|
||||
separator-x
|
||||
separator-width
|
||||
key-ui-x
|
||||
key-ui-y)
|
||||
|
||||
(begin
|
||||
|
||||
;; Window dimensions
|
||||
(define window-width-px 1000)
|
||||
(define window-height-px 830)
|
||||
|
||||
;; Maze grid configuration
|
||||
(define cell-size-px 24)
|
||||
(define maze-offset-y 97)
|
||||
(define maze-wall-shrink 6)
|
||||
|
||||
;; Cell type encoding for the maze grid
|
||||
(define cell-type-coin 0)
|
||||
(define cell-type-wall 1)
|
||||
(define cell-type-empty 2)
|
||||
(define cell-type-key 3)
|
||||
(define cell-type-door 4)
|
||||
|
||||
;; Coin rendering: inset in pixels from cell edge
|
||||
(define coin-inset 7)
|
||||
|
||||
;; Sprite scale factors
|
||||
(define sprite-scale-pacman 1.5)
|
||||
(define sprite-scale-key 1.5)
|
||||
(define sprite-scale-key-ui 3)
|
||||
|
||||
;; Animation timing
|
||||
(define animation-interval-ms 100)
|
||||
|
||||
;; Score configuration
|
||||
(define points-per-coin 10)
|
||||
|
||||
;; Time limit configuration
|
||||
(define start-time-seconds 60)
|
||||
(define ms-per-second 1000)
|
||||
(define time-bonus-per-coin 1)
|
||||
|
||||
;; Key placement
|
||||
(define max-placement-attempts 1000)
|
||||
|
||||
;; Rotation angles (degrees)
|
||||
(define rotation-right 0)
|
||||
(define rotation-left 180)
|
||||
(define rotation-up 90)
|
||||
(define rotation-down -90)
|
||||
|
||||
;; UI positions for score display
|
||||
(define score-text-size 40)
|
||||
(define score-text-x 560)
|
||||
(define score-text-y 20)
|
||||
|
||||
;; UI positions for time display (right side of separator)
|
||||
(define time-text-size 35)
|
||||
(define time-label-x 710)
|
||||
(define time-label-y 300)
|
||||
(define time-value-x 800)
|
||||
(define time-value-y 400)
|
||||
|
||||
;; Separator line between play field and UI
|
||||
(define separator-x 670)
|
||||
(define separator-width 24)
|
||||
|
||||
;; Key UI position (next to score)
|
||||
(define key-ui-x 20)
|
||||
(define key-ui-y 35)))
|
||||
@@ -1,11 +1,11 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Spel Opstarten ;;
|
||||
;; Start Game ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(import (scheme base)
|
||||
(pacman-project adt-spel))
|
||||
(pacman-project adt-game))
|
||||
|
||||
(define spel (maak-spel))
|
||||
((spel 'start!))
|
||||
(define game (make-game))
|
||||
((game 'start!))
|
||||
|
||||
24
pacman-project/tests/all-tests.rkt
Normal file
24
pacman-project/tests/all-tests.rkt
Normal file
@@ -0,0 +1,24 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; All Tests ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Runs all ADT tests. Open this file and evaluate to run everything.
|
||||
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(prefix (pacman-project tests test-position) position:)
|
||||
(prefix (pacman-project tests test-maze) maze:)
|
||||
(prefix (pacman-project tests test-pacman) pacman:)
|
||||
(prefix (pacman-project tests test-score) score:)
|
||||
(prefix (pacman-project tests test-timer) timer:))
|
||||
|
||||
(define (test-all)
|
||||
(position:test)
|
||||
(maze:test)
|
||||
(pacman:test)
|
||||
(score:test)
|
||||
(timer:test))
|
||||
|
||||
(test-all)
|
||||
@@ -1,25 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Alle Testen ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Voert alle ADT-testen uit. Open dit bestand en evalueer om alle testen
|
||||
;; tegelijkertijd te draaien.
|
||||
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(prefix (pacman-project tests test-positie) positie:)
|
||||
(prefix (pacman-project tests test-doolhof) doolhof:)
|
||||
(prefix (pacman-project tests test-pacman) pacman:)
|
||||
(prefix (pacman-project tests test-score) score:)
|
||||
(prefix (pacman-project tests test-tijdslimiet) tijdslimiet:))
|
||||
|
||||
(define (test-alles)
|
||||
(positie:test)
|
||||
(doolhof:test)
|
||||
(pacman:test)
|
||||
(score:test)
|
||||
(tijdslimiet:test))
|
||||
|
||||
(test-alles)
|
||||
@@ -1,59 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Doolhof ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-doolhof)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project constanten)
|
||||
(pacman-project adt-doolhof))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test dimensies
|
||||
(define (test-dimensies)
|
||||
(define d (maak-doolhof))
|
||||
(check-eq? (d 'rijen) 31 "Doolhof moet 31 rijen hebben")
|
||||
(check-eq? (d 'kolommen) 28 "Doolhof moet 28 kolommen hebben"))
|
||||
|
||||
;; Test muur detectie (rij 0 is volledig muur)
|
||||
(define (test-muur)
|
||||
(define d (maak-doolhof))
|
||||
(check ((d 'muur?) 0 0) "Cel (0,0) moet een muur zijn")
|
||||
(check ((d 'muur?) 0 14) "Cel (0,14) moet een muur zijn"))
|
||||
|
||||
;; Test muntje detectie
|
||||
(define (test-muntje)
|
||||
(define d (maak-doolhof))
|
||||
(check ((d 'muntje?) 1 1) "Cel (1,1) moet een muntje zijn")
|
||||
(check (not ((d 'muntje?) 0 0)) "Cel (0,0) mag geen muntje zijn"))
|
||||
|
||||
;; Test deur detectie
|
||||
(define (test-deur)
|
||||
(define d (maak-doolhof))
|
||||
(check ((d 'deur?) 4 3) "Cel (4,3) moet een deur zijn")
|
||||
(check (not ((d 'deur?) 1 1)) "Cel (1,1) mag geen deur zijn"))
|
||||
|
||||
;; Test cel-set! en verwijder-deur!
|
||||
(define (test-mutatie)
|
||||
(define d (maak-doolhof))
|
||||
((d 'verwijder-deur!) 4 3)
|
||||
(check ((d 'leeg?) 4 3) "Cel (4,3) moet leeg zijn na verwijder-deur!")
|
||||
(check (not ((d 'deur?) 4 3)) "Cel (4,3) mag geen deur meer zijn"))
|
||||
|
||||
;; Test dat Pac-Man niet door muur kan (muur blokkeert)
|
||||
(define (test-muur-blokkade)
|
||||
(define d (maak-doolhof))
|
||||
;; Pac-Man staat op (1,1) en wil naar links (1,0) -> dat is een muur
|
||||
(check ((d 'muur?) 1 0) "Cel (1,0) is een muur, Pac-Man kan niet door"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-dimensies "Doolhof: dimensies")
|
||||
(run-test test-muur "Doolhof: muur detectie")
|
||||
(run-test test-muntje "Doolhof: muntje detectie")
|
||||
(run-test test-deur "Doolhof: deur detectie")
|
||||
(run-test test-mutatie "Doolhof: cel mutatie")
|
||||
(run-test test-muur-blokkade "Doolhof: muur blokkeert beweging"))))
|
||||
58
pacman-project/tests/test-maze.rkt
Normal file
58
pacman-project/tests/test-maze.rkt
Normal file
@@ -0,0 +1,58 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Maze ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-maze)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project constants)
|
||||
(pacman-project adt-maze))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test dimensions
|
||||
(define (test-dimensions)
|
||||
(define m (make-maze))
|
||||
(check-eq? (m 'rows) 31 "Maze should have 31 rows")
|
||||
(check-eq? (m 'cols) 28 "Maze should have 28 cols"))
|
||||
|
||||
;; Test wall detection (row 0 is all walls)
|
||||
(define (test-wall)
|
||||
(define m (make-maze))
|
||||
(check ((m 'wall?) 0 0) "Cell (0,0) should be a wall")
|
||||
(check ((m 'wall?) 0 14) "Cell (0,14) should be a wall"))
|
||||
|
||||
;; Test coin detection
|
||||
(define (test-coin)
|
||||
(define m (make-maze))
|
||||
(check ((m 'coin?) 1 1) "Cell (1,1) should be a coin")
|
||||
(check (not ((m 'coin?) 0 0)) "Cell (0,0) should not be a coin"))
|
||||
|
||||
;; Test door detection
|
||||
(define (test-door)
|
||||
(define m (make-maze))
|
||||
(check ((m 'door?) 4 3) "Cell (4,3) should be a door")
|
||||
(check (not ((m 'door?) 1 1)) "Cell (1,1) should not be a door"))
|
||||
|
||||
;; Test cell-set! and remove-door!
|
||||
(define (test-mutation)
|
||||
(define m (make-maze))
|
||||
((m 'remove-door!) 4 3)
|
||||
(check ((m 'empty?) 4 3) "Cell (4,3) should be empty after remove-door!")
|
||||
(check (not ((m 'door?) 4 3)) "Cell (4,3) should no longer be a door"))
|
||||
|
||||
;; Test that wall blocks movement
|
||||
(define (test-wall-blocks)
|
||||
(define m (make-maze))
|
||||
(check ((m 'wall?) 1 0) "Cell (1,0) is a wall, Pac-Man cannot pass"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-dimensions "Maze: dimensions")
|
||||
(run-test test-wall "Maze: wall detection")
|
||||
(run-test test-coin "Maze: coin detection")
|
||||
(run-test test-door "Maze: door detection")
|
||||
(run-test test-mutation "Maze: cell mutation")
|
||||
(run-test test-wall-blocks "Maze: wall blocks movement"))))
|
||||
@@ -1,51 +1,51 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Pac-Man ADT ;;
|
||||
;; Tests: Pac-Man ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-pacman)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project adt-positie)
|
||||
(pacman-project adt-position)
|
||||
(pacman-project adt-pacman))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test aanmaak en startpositie
|
||||
(define (test-aanmaak)
|
||||
(define pac (maak-pacman 5 2))
|
||||
(define pos (pac 'positie))
|
||||
(check-eq? (pos 'rij) 5 "Start rij moet 5 zijn")
|
||||
(check-eq? (pos 'kolom) 2 "Start kolom moet 2 zijn"))
|
||||
;; Test creation and start position
|
||||
(define (test-creation)
|
||||
(define pac (make-pacman 5 2))
|
||||
(define pos (pac 'position))
|
||||
(check-eq? (pos 'row) 5 "Start row should be 5")
|
||||
(check-eq? (pos 'col) 2 "Start col should be 2"))
|
||||
|
||||
;; Test richting
|
||||
(define (test-richting)
|
||||
(define pac (maak-pacman 5 2))
|
||||
(check-eq? (pac 'richting) 'rechts "Startrichting moet rechts zijn")
|
||||
((pac 'richting!) 'links)
|
||||
(check-eq? (pac 'richting) 'links "Richting moet links zijn na richting!"))
|
||||
;; Test direction
|
||||
(define (test-direction)
|
||||
(define pac (make-pacman 5 2))
|
||||
(check-eq? (pac 'direction) 'right "Start direction should be right")
|
||||
((pac 'direction!) 'left)
|
||||
(check-eq? (pac 'direction) 'left "Direction should be left after direction!"))
|
||||
|
||||
;; Test beweeg!
|
||||
(define (test-beweeg)
|
||||
(define pac (maak-pacman 5 2))
|
||||
((pac 'beweeg!) 0 1)
|
||||
(define pos (pac 'positie))
|
||||
(check-eq? (pos 'kolom) 3 "Kolom moet 3 zijn na 1 stap rechts")
|
||||
(check-eq? (pos 'rij) 5 "Rij ongewijzigd na horizontale beweging"))
|
||||
;; Test move!
|
||||
(define (test-move)
|
||||
(define pac (make-pacman 5 2))
|
||||
((pac 'move!) 0 1)
|
||||
(define pos (pac 'position))
|
||||
(check-eq? (pos 'col) 3 "Col should be 3 after 1 step right")
|
||||
(check-eq? (pos 'row) 5 "Row unchanged after horizontal move"))
|
||||
|
||||
;; Test meerdere bewegingen
|
||||
(define (test-meerdere-bewegingen)
|
||||
(define pac (maak-pacman 5 5))
|
||||
((pac 'beweeg!) -1 0)
|
||||
((pac 'beweeg!) 0 1)
|
||||
(define pos (pac 'positie))
|
||||
(check-eq? (pos 'rij) 4 "Rij moet 4 zijn na omhoog")
|
||||
(check-eq? (pos 'kolom) 6 "Kolom moet 6 zijn na rechts"))
|
||||
;; Test multiple moves
|
||||
(define (test-multiple-moves)
|
||||
(define pac (make-pacman 5 5))
|
||||
((pac 'move!) -1 0)
|
||||
((pac 'move!) 0 1)
|
||||
(define pos (pac 'position))
|
||||
(check-eq? (pos 'row) 4 "Row should be 4 after up")
|
||||
(check-eq? (pos 'col) 6 "Col should be 6 after right"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-aanmaak "Pac-Man: aanmaak en startpositie")
|
||||
(run-test test-richting "Pac-Man: richting")
|
||||
(run-test test-beweeg "Pac-Man: beweeg!")
|
||||
(run-test test-meerdere-bewegingen "Pac-Man: meerdere bewegingen"))))
|
||||
(run-test test-creation "Pac-Man: creation and start position")
|
||||
(run-test test-direction "Pac-Man: direction")
|
||||
(run-test test-move "Pac-Man: move!")
|
||||
(run-test test-multiple-moves "Pac-Man: multiple moves"))))
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Positie ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-positie)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project adt-positie))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test aanmaak en getters
|
||||
(define (test-aanmaak)
|
||||
(define pos (maak-positie 5 10))
|
||||
(check-eq? (pos 'rij) 5 "Rij moet 5 zijn")
|
||||
(check-eq? (pos 'kolom) 10 "Kolom moet 10 zijn"))
|
||||
|
||||
;; Test mutators
|
||||
(define (test-mutators)
|
||||
(define pos (maak-positie 0 0))
|
||||
((pos 'rij!) 3)
|
||||
((pos 'kolom!) 7)
|
||||
(check-eq? (pos 'rij) 3 "Rij moet 3 zijn na rij!")
|
||||
(check-eq? (pos 'kolom) 7 "Kolom moet 7 zijn na kolom!"))
|
||||
|
||||
;; Test vergelijk?
|
||||
(define (test-vergelijk)
|
||||
(define p1 (maak-positie 5 10))
|
||||
(define p2 (maak-positie 5 10))
|
||||
(define p3 (maak-positie 5 11))
|
||||
(check ((p1 'vergelijk?) p2) "Gelijke posities moeten gelijk zijn")
|
||||
(check (not ((p1 'vergelijk?) p3)) "Verschillende posities mogen niet gelijk zijn"))
|
||||
|
||||
;; Test beweeg
|
||||
(define (test-beweeg)
|
||||
(define pos (maak-positie 5 10))
|
||||
(define nieuwe-pos ((pos 'beweeg) -1 0))
|
||||
(check-eq? (nieuwe-pos 'rij) 4 "Rij moet 4 zijn na beweeg omhoog")
|
||||
(check-eq? (nieuwe-pos 'kolom) 10 "Kolom ongewijzigd na beweeg omhoog")
|
||||
;; Originele positie mag niet gewijzigd zijn
|
||||
(check-eq? (pos 'rij) 5 "Originele rij mag niet wijzigen"))
|
||||
|
||||
;; Test dat twee objecten niet eq? zijn
|
||||
(define (test-identiteit)
|
||||
(define p1 (maak-positie 1 1))
|
||||
(define p2 (maak-positie 1 1))
|
||||
(check (not (eq? p1 p2)) "Twee positie-objecten mogen niet eq? zijn"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-aanmaak "Positie: aanmaak en getters")
|
||||
(run-test test-mutators "Positie: mutators")
|
||||
(run-test test-vergelijk "Positie: vergelijk?")
|
||||
(run-test test-beweeg "Positie: beweeg")
|
||||
(run-test test-identiteit "Positie: identiteit"))))
|
||||
57
pacman-project/tests/test-position.rkt
Normal file
57
pacman-project/tests/test-position.rkt
Normal file
@@ -0,0 +1,57 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Position ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-position)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project adt-position))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test creation and getters
|
||||
(define (test-creation)
|
||||
(define pos (make-position 5 10))
|
||||
(check-eq? (pos 'row) 5 "Row should be 5")
|
||||
(check-eq? (pos 'col) 10 "Col should be 10"))
|
||||
|
||||
;; Test mutators
|
||||
(define (test-mutators)
|
||||
(define pos (make-position 0 0))
|
||||
((pos 'row!) 3)
|
||||
((pos 'col!) 7)
|
||||
(check-eq? (pos 'row) 3 "Row should be 3 after row!")
|
||||
(check-eq? (pos 'col) 7 "Col should be 7 after col!"))
|
||||
|
||||
;; Test equal?
|
||||
(define (test-equal)
|
||||
(define p1 (make-position 5 10))
|
||||
(define p2 (make-position 5 10))
|
||||
(define p3 (make-position 5 11))
|
||||
(check ((p1 'equal?) p2) "Equal positions should match")
|
||||
(check (not ((p1 'equal?) p3)) "Different positions should not match"))
|
||||
|
||||
;; Test move
|
||||
(define (test-move)
|
||||
(define pos (make-position 5 10))
|
||||
(define new-pos ((pos 'move) -1 0))
|
||||
(check-eq? (new-pos 'row) 4 "Row should be 4 after move up")
|
||||
(check-eq? (new-pos 'col) 10 "Col unchanged after move up")
|
||||
;; Original position must not change
|
||||
(check-eq? (pos 'row) 5 "Original row must not change"))
|
||||
|
||||
;; Test that two objects are not eq?
|
||||
(define (test-identity)
|
||||
(define p1 (make-position 1 1))
|
||||
(define p2 (make-position 1 1))
|
||||
(check (not (eq? p1 p2)) "Two position objects must not be eq?"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-creation "Position: creation and getters")
|
||||
(run-test test-mutators "Position: mutators")
|
||||
(run-test test-equal "Position: equal?")
|
||||
(run-test test-move "Position: move")
|
||||
(run-test test-identity "Position: identity"))))
|
||||
@@ -1,30 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Score ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-score)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project adt-score))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test startscore
|
||||
(define (test-startscore)
|
||||
(define s (maak-score))
|
||||
(check-eq? (s 'punten) 0 "Startscore moet 0 zijn"))
|
||||
|
||||
;; Test score verhoging
|
||||
(define (test-verhoog)
|
||||
(define s (maak-score))
|
||||
((s 'verhoog!))
|
||||
(check-eq? (s 'punten) 10 "Score moet 10 zijn na 1 muntje")
|
||||
((s 'verhoog!))
|
||||
(check-eq? (s 'punten) 20 "Score moet 20 zijn na 2 muntjes"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-startscore "Score: startscore")
|
||||
(run-test test-verhoog "Score: verhoging"))))
|
||||
@@ -1,55 +0,0 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Tijdslimiet ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-tijdslimiet)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project adt-tijdslimiet))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test starttijd
|
||||
(define (test-starttijd)
|
||||
(define t (maak-tijdslimiet))
|
||||
(check-eq? (t 'resterende-tijd) 60 "Starttijd moet 60 seconden zijn")
|
||||
(check (not ((t 'tijd-op?))) "Tijd mag niet op zijn bij start"))
|
||||
|
||||
;; Test verlaag na 1 seconde
|
||||
(define (test-verlaag)
|
||||
(define t (maak-tijdslimiet))
|
||||
((t 'verlaag!) 1000)
|
||||
(check-eq? (t 'resterende-tijd) 59 "Tijd moet 59 zijn na 1 seconde"))
|
||||
|
||||
;; Test verhoog (muntje bonus)
|
||||
(define (test-verhoog)
|
||||
(define t (maak-tijdslimiet))
|
||||
((t 'verlaag!) 1000)
|
||||
((t 'verhoog!))
|
||||
(check-eq? (t 'resterende-tijd) 60 "Tijd moet 60 zijn na verlaag + verhoog"))
|
||||
|
||||
;; Test formatteer-tijd
|
||||
(define (test-formatteer)
|
||||
(define t (maak-tijdslimiet))
|
||||
(check-eq? ((t 'formatteer-tijd)) "1:00" "60 seconden = 1:00")
|
||||
((t 'verlaag!) 1000)
|
||||
(check-eq? ((t 'formatteer-tijd)) "0:59" "59 seconden = 0:59"))
|
||||
|
||||
;; Test tijd-op?
|
||||
(define (test-tijd-op)
|
||||
(define t (maak-tijdslimiet))
|
||||
;; 60 keer verlagen met 1 seconde
|
||||
(do ((i 0 (+ i 1)))
|
||||
((= i 60))
|
||||
((t 'verlaag!) 1000))
|
||||
(check ((t 'tijd-op?)) "Tijd moet op zijn na 60 seconden"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-starttijd "Tijdslimiet: starttijd")
|
||||
(run-test test-verlaag "Tijdslimiet: verlaag")
|
||||
(run-test test-verhoog "Tijdslimiet: verhoog")
|
||||
(run-test test-formatteer "Tijdslimiet: formatteer-tijd")
|
||||
(run-test test-tijd-op "Tijdslimiet: tijd-op?"))))
|
||||
55
pacman-project/tests/test-timer.rkt
Normal file
55
pacman-project/tests/test-timer.rkt
Normal file
@@ -0,0 +1,55 @@
|
||||
#lang r7rs
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Tests: Timer ADT ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define-library (pacman-project tests test-timer)
|
||||
(import (scheme base)
|
||||
(pp1 tests)
|
||||
(pacman-project adt-timer))
|
||||
(export test)
|
||||
|
||||
(begin
|
||||
|
||||
;; Test initial time
|
||||
(define (test-initial)
|
||||
(define t (make-timer))
|
||||
(check-eq? (t 'remaining-time) 60 "Initial time should be 60 seconds")
|
||||
(check (not ((t 'time-up?))) "Time should not be up at start"))
|
||||
|
||||
;; Test decrease after 1 second
|
||||
(define (test-decrease)
|
||||
(define t (make-timer))
|
||||
((t 'decrease!) 1000)
|
||||
(check-eq? (t 'remaining-time) 59 "Time should be 59 after 1 second"))
|
||||
|
||||
;; Test increase (coin bonus)
|
||||
(define (test-increase)
|
||||
(define t (make-timer))
|
||||
((t 'decrease!) 1000)
|
||||
((t 'increase!))
|
||||
(check-eq? (t 'remaining-time) 60 "Time should be 60 after decrease + increase"))
|
||||
|
||||
;; Test format-time
|
||||
(define (test-format)
|
||||
(define t (make-timer))
|
||||
(check-eq? ((t 'format-time)) "1:00" "60 seconds = 1:00")
|
||||
((t 'decrease!) 1000)
|
||||
(check-eq? ((t 'format-time)) "0:59" "59 seconds = 0:59"))
|
||||
|
||||
;; Test time-up?
|
||||
(define (test-time-up)
|
||||
(define t (make-timer))
|
||||
;; Decrease 60 times by 1 second
|
||||
(do ((i 0 (+ i 1)))
|
||||
((= i 60))
|
||||
((t 'decrease!) 1000))
|
||||
(check ((t 'time-up?)) "Time should be up after 60 seconds"))
|
||||
|
||||
(define (test)
|
||||
(run-test test-initial "Timer: initial time")
|
||||
(run-test test-decrease "Timer: decrease")
|
||||
(run-test test-increase "Timer: increase")
|
||||
(run-test test-format "Timer: format-time")
|
||||
(run-test test-time-up "Timer: time-up?"))))
|
||||
Reference in New Issue
Block a user