だめな子

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

SchemeでLifeGame v2

他の人の投稿も見てみた結果こうなった

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 (step-exec value next proc)
  18.     (define (iter value cc)
  19.         (cc value
  20.             (lambda () (iter (next value) cc))))
  21.     (lambda ()
  22.         (iter
  23.             value
  24.             (lambda (value cc) (proc value) cc))))
  25.  
  26. (define (make-field)
  27.     (define (flatten x) (fold-right append '() x))
  28.     (map
  29.         (lambda (e) (make-element (car e) (cadr e) #f))
  30.         (zip
  31.             (apply circular-list (iota width 0))
  32.             (flatten
  33.                 (map
  34.                     (lambda (x) (iota width x 0))
  35.                     (iota height 0))))))
  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 (randomize-field field)
  51.     (random-source-randomize! default-random-source)
  52.     (map
  53.         (lambda (e)
  54.             (if (<(random-real) population)
  55.                 (make-element (element-x e) (element-y e) #t)
  56.                 (make-element (element-x e) (element-y e) #f)))
  57.         field))
  58.  
  59. (define (count field)
  60.     (length (filter (lambda (e) (element-value e)) field)))
  61.  
  62. (define (game-next field)
  63.     (define (get-neighbors x y)
  64.         (let
  65.             ((x-1 (remainder (+ x width -1) width))
  66.              (x+1 (remainder (+ x width +1) width))
  67.              (y-1 (remainder (+ y height -1) height))
  68.              (y+1 (remainder (+ y height +1) height)))
  69.             (filter
  70.                 (lambda (e)
  71.                     (let
  72.                         ((cx    (element-x e))
  73.                          (cy    (element-y e)))
  74.                         (or
  75.                             (and (= x-1 cx) (= y-1 cy)) (and (= x   cx) (= y-1 cy)) (and (= x+1 cx) (= y-1 cy))
  76.                             (and (= x-1 cx) (= y   cy))                             (and (= x+1 cx) (= y   cy))
  77.                             (and (= x-1 cx) (= y+1 cy)) (and (= x   cx) (= y+1 cy)) (and (= x+1 cx) (= y+1 cy)))))
  78.                 field)))
  79.     (define (next-state e)
  80.         (define neighbors (count (get-neighbors (element-x e) (element-y e))))
  81.         (define live? element-value)
  82.         (define (live->next)
  83.             (if (fold (lambda (x y) (or x y)) #f (map (cut = neighbors <>) keep))
  84.                 e
  85.                 (make-element (element-x e) (element-y e) #f)))
  86.         (define (dead->next)
  87.             (if (fold (lambda (x y) (or x y)) #f (map (cut = neighbors <>) birth))
  88.                 (make-element (element-x e) (element-y e) #t)
  89.                 e))
  90.         (if (live? e)
  91.             (live->next)
  92.             (dead->next)))
  93.     (map
  94.         next-state
  95.         field))
  96.  
  97. (define next
  98.     (step-exec
  99.         (randomize-field (make-field))
  100.         game-next
  101.         (lambda (e) (print-field e))))
  102.  
  103. (let loop
  104.     ((c (read-char))
  105.      (count 1))
  106.     (if (char=? #\e c)
  107.         (exit 0)
  108.         (begin
  109.             (display count)
  110.             (newline)
  111.             (set! next (next))
  112.             (display "next -> any keys.")
  113.             (newline)
  114.             (display "exit -> press e.")
  115.             (newline)
  116.             (loop (read-char) (+ count 1)))))

・のりしろがなくなった
・make-element やら element-* を使ってればセルの表現を気にしないでよくなった(相変わらず全体はセルのリストだ

毎回get-neighborsしてるのはバカらしい気もするけどまぁいいや

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>