だめな子

だめな子ですが頑張って成長してゆくのです。

SchemeでLifeGame v3

SCHEME:
  1. (use srfi-1)
  2. (use srfi-27)
  3.  
  4. (define width 14)
  5. (define height 10)
  6.  
  7. (define population 0.3)
  8.  
  9. (define birth '(3))
  10. (define keep '(2 3))
  11.  
  12. (define element-x car)
  13. (define element-y cadr)
  14. (define element-value caddr)
  15. (define (make-element x y v) (list x y v))
  16.  
  17. (define (make-field)
  18.     (define (flatten x) (fold-right append '() x))
  19.     (map
  20.         (lambda (e) (make-element (car e) (cadr e) #f))
  21.         (zip
  22.             (apply circular-list (iota width 0))
  23.             (flatten
  24.                 (map
  25.                     (lambda (x) (iota width x 0))
  26.                     (iota height 0))))))
  27.  
  28. (define (randomize-field field)
  29.     (random-source-randomize! default-random-source)
  30.     (map
  31.         (lambda (e)
  32.             (if (<(random-real) population)
  33.                 (make-element (element-x e) (element-y e) #t)
  34.                 (make-element (element-x e) (element-y e) #f)))
  35.         field))
  36.  
  37. (define (print-field field)
  38.     (define (print-cell e)
  39.         (if (element-value e)
  40.             (display "[*]")
  41.             (display "[ ]")))
  42.     (let loop ((left field))
  43.         (if (not (null? left))
  44.             (begin
  45.                 (print-cell (car left))
  46.                 (if (= (element-x (car left)) (- width 1))
  47.                     (newline))
  48.                 (loop (cdr left))))))
  49.  
  50. (define (game-next field)
  51.     (define (count field) (length (filter (lambda (e) (element-value e)) field)))
  52.     (define (get-neighbors x y)
  53.         (let
  54.             ((x-1 (remainder (+ x width -1) width))
  55.              (x+1 (remainder (+ x width +1) width))
  56.              (y-1 (remainder (+ y height -1) height))
  57.              (y+1 (remainder (+ y height +1) height)))
  58.             (filter
  59.                 (lambda (e)
  60.                     (let
  61.                         ((cx    (element-x e))
  62.                          (cy    (element-y e)))
  63.                         (or
  64.                             (and (= x-1 cx) (= y-1 cy)) (and (= x   cx) (= y-1 cy)) (and (= x+1 cx) (= y-1 cy))
  65.                             (and (= x-1 cx) (= y   cy))                             (and (= x+1 cx) (= y   cy))
  66.                             (and (= x-1 cx) (= y+1 cy)) (and (= x   cx) (= y+1 cy)) (and (= x+1 cx) (= y+1 cy)))))
  67.                 field)))
  68.     (define (next-state e)
  69.         (define neighbors (count (get-neighbors (element-x e) (element-y e))))
  70.         (define live? element-value)
  71.         (define (live->next)
  72.             (if (fold (lambda (x y) (or x y)) #f (map (cut = neighbors <>) keep))
  73.                 e
  74.                 (make-element (element-x e) (element-y e) #f)))
  75.         (define (dead->next)
  76.             (if (fold (lambda (x y) (or x y)) #f (map (cut = neighbors <>) birth))
  77.                 (make-element (element-x e) (element-y e) #t)
  78.                 e))
  79.         (if (live? e)
  80.             (live->next)
  81.             (dead->next)))
  82.     (map
  83.         next-state
  84.         field))
  85.  
  86. (define (play)
  87.     (define (field-chain field)
  88.         (cons
  89.             field
  90.             (delay (field-chain (game-next field)))))
  91.     (define field-list (field-chain (randomize-field (make-field))))
  92.     (define count ((lambda ()
  93.         (define counter 0)
  94.         (define (inc)
  95.             (set! counter (+ counter 1))
  96.             counter)
  97.         inc)))
  98.     (define (iter)
  99.         (display (count))
  100.         (newline)
  101.         (print-field (car field-list))
  102.         (display "if you want to exit. press e.")
  103.         (newline)
  104.         (if (char=? #\e (read-char)) (exit 0))
  105.         (set! field-list (force (cdr field-list)))
  106.         (iter))
  107.     (iter))
  108.  
  109. (play)

・CPSっぽいやり方じゃなくなった
・無限ストリームっぽいものになった
play内部のcountの作り方に1〜2分悩んだ(おばか

SCHEME:
  1. (define (play)
  2.     (define (field-chain field)
  3.         (cons
  4.             field
  5.             (delay (field-chain (game-next field)))))
  6.     (define field-list (field-chain (randomize-field (make-field))))
  7.     (define (iter count)
  8.         (display count)
  9.         (newline)
  10.         (print-field (car field-list))
  11.         (display "if you want to exit. press e.")
  12.         (newline)
  13.         (if (char=? #\e (read-char)) (exit 0))
  14.         (set! field-list (force (cdr field-list)))
  15.         (iter (+ count 1)))
  16.     (iter 1))

playの定義はこっちのが綺麗ですよねーってなるよねぇ…

RSS 2.0 | Trackback | Comment

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>