#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))))