• Evolve


    最有意思的就是其中的genes,不同的动物会有不同的genes还会遗传和变异!!!

    mapc和mapcar的区别查了一下,mapc返回原始的list而mapcar会把结果cons,如果是利用side effect话mapc比较省时间.

    还有一个问题,就是对于下面的代码

    (defparameter *list* '(1 2 3 4))
    
    (mapc (lambda (x) (incf x)) *list*)
    

    我原本以为会直接把*list*上的每一个数都加一但是并没有,mapcar也一样

    但是下面的代码却可以把每一个list元素中的第一个数改变

    (defparameter *l* '((1 2) (2 3) (3 4)))
    
    (mapc (lambda (x) (incf (car x))) *l*)
    

    我想会不会是这一章前面提到过的浅复制的原因,对于symbol和integer等这些简单的元素传参数时是完全复制,没有共享的结构

    但是对于后者传的是个list,是共享的.所以side effec会影响原始的值

    ;;;;
    
    (defparameter *width* 100)
    (defparameter *height* 30)
    (defparameter *jungle* '(45 10 10 10))
    (defparameter *plant-energy* 80)
    
    ;;;;growing plants in our world
    
    (defparameter *plants* (make-hash-table :test #'equal))
    
    (defun random-plant (left top width height)
    	(let ((pos (cons (+ left (random width)) (+ top (random height)))))
    		(setf (gethash pos *plants*) t)))
    
    (defun add-plants ()
    	(apply #'random-plant *jungle*)
    	(random-plant 0 0 *width* *height*))
    
    
    ;;;;create animals
    
    (defstruct animal x y energy dir genes)
    
    (defparameter *animals*
    	(list (make-animal 
    		:x (ash *width* -1)
    		:y (ash *height* -1)
    		:energy 1000
    		:dir 0
    		:genes (loop repeat 8
    			collecting (1+ (random 10))))))
    
    
    ;;;;handling animal motion
    
    (defun move (animal)
    	(let ((dir (animal-dir animal))
    		(x (animal-x animal))
    		(y (animal-y animal)))
    	(setf (animal-x animal) (mod (+ x
    		(cond ((and (>= dir 2) (< dir 5)) 1)
    			((or (= dir 1) (= dir 5)) 0)
    			(t -1))
    		*width*)
    	*width*))
    	(setf (animal-y animal) (mod (+ y
    		(cond ((and (>= dir 0) (< dir 3)) -1)
    			((and (>= dir 4) (< dir 7)) 1)
    			(t 0))
    		*height*)
    	*height*))
    	(decf (animal-energy animal))))
    
    
    ;;;;handling animal turning
    
    (defun turn (animal)
    	(let ((x (random (apply #'+ (animal-genes animal)))))
    		(labels ((angle (genes x)
    			(let ((xnu (- x (car genes))))
    				(if (< xnu 0)
    					0
    					(1+ (angle (cdr genes) xnu))))))
    		(setf (animal-dir animal)
    			(mod (+ (animal-dir animal) (angle (animal-genes animal) x))
    				8)))))
    
    
    ;;;;handling animal eating
    
    (defun eat (animal)
    	(let ((pos (cons (animal-x animal) (animal-y animal))))
    		(when (gethash pos *plants*)
    			(incf (animal-energy animal) *plant-energy*)
    			(remhash pos *plants*))))
    
    
    ;;;;handling animal reproduction
    
    (defparameter *reproduction-energy* 200)
    
    (defun reproduce (animal)
    	(let ((e (animal-energy animal)))
    		(when (>= e *reproduction-energy*)
    			(setf (animal-energy animal) (ash e -1))
    			(let ((animal-nu (copy-structure animal))
    				(genes (copy-list (animal-genes animal)))
    				(mutation (random 8)))
    			(setf (nth mutation genes) (max 1 (+ (nth mutation genes) (random 3) -1)))
    			(setf (animal-genes animal-nu) genes)
    			(push animal-nu *animals*)))))
    
    
    ;;;;simulating a day in our world
    
    (defun update-world ()
    	(setf *animals* (remove-if (lambda (animal)
    									(<= (animal-energy animal) 0))
    								*animals*))
    	(mapc (lambda (animal)
    		(turn animal)
    		(move animal)
    		(eat animal)
    		(reproduce animal))
    	*animals*)
    	(add-plants))
    
    
    ;;;;drawing our world
    
    (defun draw-world ()
    	(loop for y
    		below *height*
    		do (progn (fresh-line)
    				  (princ "|")
    				  (loop for x
    				  	below *width*
    				  	do (princ (cond ((some (lambda (animal)
    				  							(and (= (animal-x animal) x)
    				  								 (= (animal-y animal) y)))
    				  							*animals*)
    				  						#M)
    				  					((gethash (cons x y) *plants*) #*)
    				  					(t #space))))
    				  (princ "|"))))
    
    
    ;;;;creating a user interface
    
    (defun evolution ()
    	(draw-world)
    	(fresh-line)
    	(let ((str (read-line)))
    		(cond ((equal str "quit") ())
    			(t (let ((x (parse-integer str :junk-allowed t)))
    				(if x
    					(loop for i
    						below x
    						do (update-world)
    						if (zerop (mod i 1000))
    						do (princ #.))
    					(update-world))
    				(evolution))))))
    

     

    Yosoro
  • 相关阅读:
    关于hql执行带有case when 的语句问题,另:数据表的倒置
    xslt 转换 xml
    xsd校验xml
    java 调用存储过程
    js return无效,表单自动提交
    bat 启动java程序
    Delphi 窗体拖动,无边框,透明的设置
    installshield实例(三)发布,补丁,升级
    Installshield实例(二)创建自定义界面
    InstallShield 实例(一)检测JDK,MYSQL,创建数据库
  • 原文地址:https://www.cnblogs.com/tclan126/p/7467381.html
Copyright © 2020-2023  润新知