0

The following Scheme code is about a game with a spaceship and right now it doesn't take into account when the spaceship runs out of fuel, which is what I'm trying to do. Here is the code:
;; this is the code for problem rrset -- Lunar Lander

(define (update ship-state fuel-burn-rate)  
 (make-ship-state  
   (+ (height ship-state) (* (velocity ship-state) dt)) ; height  
   (+ (velocity ship-state)  
      (* (- (* engine-strength fuel-burn-rate) gravity)  
         dt))                                           ; velocity  
   (cond (<= (fuel 0)  
        ((write-line "no fuel left")   
          'game-over)  
         (else  
           (- (fuel ship-state) (* fuel-burn-rate dt))))))       ; fuel  

(define (lander-loop ship-state)  
  (show-ship-state ship-state)  
  (if (landed? ship-state)  
  (end-game ship-state)  
  (lander-loop (update ship-state (get-burn-rate)))))  

(define (show-ship-state ship-state)  
  (write-line   
    (list 'height (height ship-state)  
          'velocity (velocity ship-state)  
          'fuel (fuel ship-state))))  

(define (landed? ship-state)  
  (<= (height ship-state) 0))  

(define (end-game ship-state)  
  (let ((final-velocity (velocity ship-state)))  
       (write-line final-velocity)  
       (cond ((>= final-velocity safe-velocity)  
               (write-line "good landing")  
               'game-over)  
             (else  
               (write-line "you crashed!")  
               'game-over))))  

(define (get-burn-rate)  
  (if (= (player-input) burn-key)  
      1  
      0))  

(define (play) (lander-loop (initial-ship-state)))  

(define (initial-ship-state)  
  (make-ship-state 50       ; 50 km high  
                   0        ; not moving (0 km/sec)  
                   20))     ; 20 kg of fuel left  

(define dt 1)               ; 1 second interval of simulation  

(define gravity 0.5)        ; 0.5 km/sec/sec  

(define safe-velocity -0.5) ; 0.5 km/sec or faster is a crash  

(define engine-strength 1)  ; 1 kilonewton-second  

(define (player-input)  
  (char->integer (prompt-for-command-char " action: ")))  

(define burn-key 32)   ;space key  

(define (make-ship-state height velocity fuel)  
  (list 'HEIGHT   height  
        'VELOCITY velocity  
        'FUEL     fuel))  

(define (height state) (second state))  
(define (velocity state) (fourth state))  
(define (fuel state) (sixth state))  

(define (second l) (cadr l))  
(define (fourth l) (cadr (cddr l)))  
(define (sixth l) (cadr (cddr (cddr l))))  

; Users of DrScheme or DrRacket: add these for compatibility with MIT Scheme...  
(define (write-line x)  
  (display x)  
  (newline))  

(define (prompt-for-command-char prompt)  
  (display prompt)  
  (read-char))  

To modify it, I modified the "update" procedure, so now there is a conditional statement:

(define (update ship-state fuel-burn-rate)  
  (make-ship-state  
   (+ (height ship-state) (* (velocity ship-state) dt)) ; height  
   (+ (velocity ship-state)  
      (* (- (* engine-strength fuel-burn-rate) gravity)  
         dt))                                           ; velocity  
   (cond (<= (fuel 0)  
        ((write-line "no fuel left")   
          'game-over)  
         (else  
           (- (fuel ship-state) (* fuel-burn-rate dt))))))  

however this doesn't work.

4

1 回答 1

1

You're going to want to add your conditional to the lander-loop procedure. This is the part of the code that checks whether the game is over each cycle.

(define (lander-loop ship-state)  
  (show-ship-state ship-state)
  (if (or (landed? ship-state) (<= (fuel ship-state) 0))
    (end-game ship-state)
    (lander-loop (update ship-state (get-burn-rate)))))

Then you can add your out of fuel message to the end-game procedure.

于 2013-02-03T03:27:36.977 回答