红绿灯系统

htdp早期习题中,提到了构造单个红绿灯,那如果构造多个红绿灯
一个红绿灯出了故障,那其他几个红绿灯 不受影响,正常运行。这就类似电路中的并联。

htdp这本书提倡的是abstraction and encapsulation,即抽象与封装
abstraction一般是对数据和功能的抽象,目的是为了处理更多的数据,使程序更简洁。
encapsulation一般是对数据和功能的封装,将功能和数据集合在一个小空间里,racket中的local体现了这一功能

一个红绿灯出了故障,那其他几个红绿灯 不受影响,正常运行。
用多个变量var1,var2,var3,var4....存储多个红绿灯的状态。一个状态出了问题,而另外几个状态不受影响。
这种“并联式”的问题就没有必要对数据抽象,只需要对功能抽象和封装

具体代码

;;data
(define-struct traffic (street x-posn))
(define rice-color 'red)
(define cmu-color 'red)
(define ustc-color 'red)
(define kcl-color 'red)

(define current-color 'red)
(define x-posn 50)
(define width 50)
(define distance 10)
(define radius 20)

;;school-color-selector
(define (school-selector str)
  (local ((define para (traffic-street str)))
       (cond
           [(symbol=? para 'sunrise@rice) rice-color] ;;其他函数调用此函数,已经解析了一遍,得出来的并不是变量
           [(symbol=? para 'sunrise@cmu) cmu-color]
           [(symbol=? para 'sunrise@ustc) ustc-color]
           [(symbol=? para 'sunrise@kcl) kcl-color])))
           
;;初始化红绿灯
;;先清除之前所有红绿灯
(define (init-traffic str)
 (begin
   (clear (traffic-x-posn str) (school-selector str)) ;;
   (set! (school-selector str) 'red) ;;
   (draw-disk (traffic-x-posn str) (school-selector str))));;
       

;;画红绿灯
(define (draw-disk x-posn current-color)
  (draw-solid-disk (make-posn x-posn (location current-color))  radius current-color))

;;清除红绿灯
(define (clear x-posn current-color)
  (clear-solid-disk (make-posn x-posn (location current-color)) radius current-color))
 
;;在x坐标同样的情况下,通过颜色定位y坐标
(define (location current-color)
  (cond
       [(symbol=? current-color 'red) 30]
       [(symbol=? current-color 'yellow) 80]
       [(symbol=? current-color 'green) 130]))
       
;;颜色转换&&画转换后的红绿灯 
(define (next str)
     (begin  (sleep-for-a-while 1)
             (clear (traffic-x-posn str) (school-selector str)) ;;
             (set! (school-selector str) (next-color (school-selector str)))
             (sleep-for-a-while 1)
             (draw-disk (traffic-x-posn str) (school-selector str)))) ;;
;;next-color-selector
(define (next-color current-color)
  (cond
       [(symbol=? current-color 'red) 'yellow]
       [(symbol=? current-color 'yellow) 'green]
       [(symbol=? current-color 'green) 'red]))
;;不需要知道函数怎么调用,就能调用函数
;;当然更简明的方法是设计一个用户界面
(define (service-message msg str)
  (cond
        [(symbol=? msg 'next) (next str)]
        [(symbol=? msg 'reset) (init-traffic str)]
        [else (error "The message can not be understood")]))
;;对于红绿灯数据的处理,还是把它构建成结构比较好
;;对于数据不易泄露,同时也便利
(define lights
         (list (make-traffic 'sunrise@rice 50)
               (make-traffic 'sunrise@cmu 150)
               (make-traffic 'sunrise@ustc 250)
               (make-traffic 'sunrise@kcl 350)))

(define op1 (first lights))
(define op2 (second lights))
(define op3 (third lights))
(define op4 (fourth lights))


出现问题
(set! (school-selector str) 'red) 中,(school-selector str)返回的是值并不是一个identifier,所以会出现 错误

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值