;;;;;;;;;;;;;;;;;;;;;;; ;;; LANGTON'S ANT ;;; ;;;;;;;;;;;;;;;;;;;;;;; ;; Kyle Kovacs ;; CS61A Spring 2015 ;; ______________________________ ;; | Around and around, | ;; | never sure where he will go, | ;; | Langton's Ant wanders. | ;; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;; This program is a visualization for the celular automaton 'Langton's Ant.' ;; Langton's Ant consists of an imaginary "ant" on an infinite grid. The ant ;; follows a set of rules as follows: ;; ;; 1) read the color of the ant's current square, ;; 2) turn either left or right depending on the particular pattern*, ;; 3) change the current square's color to the next color in the pattern*, ;; 4) advance forward 1 square. ;; ;; *All patterns consist of a set of colors that loop and a set of corresponding ;; turns, e.g. colors: red, green, blue, then back to red again; turns: left, ;; right, right, then back to left again. ;; ;; By these four simple rules, Langton's Ant can produce many interesting ;; patterns. Some rule sets produce filled regions, random chaotic structures, ;; or even infinite repeating 'highways.' Defined at the bottom of this file are ;; some example functions with different behaviors. Changing these and running ;; the simulation with a different rule set will produce drastucally different ;; results. For more, go to https://www.youtube.com/watch?v=1X-gtr4pEBU ;; To run the program, use (run function iterations) where function is a pattern ;; function and iterations is the number of steps the ant will take. ;;;;;;;;;;;;;; ; set up board (define (make-zeros n) (cond ((= n 0) nil) (else (cons 0 (make-zeros (- n 1)))) ) ) (define (n-times seq n) (cond ((= n 0) nil) (else (cons seq (n-times seq (- n 1)))) ) ) (define grid (n-times (make-zeros 100) 100)) (define (get-item s i) (cond ((null? s) 'item-not-found) ((= i 0) (car s)) (else (get-item (cdr s) (- i 1))) ) ) (define (get-item-in-grid seq row-n col-n) (if (> row-n (length seq)) 'row-too-big (let ((row (get-item seq row-n))) (if (> col-n (length seq)) 'col-too-big (get-item row col-n) ) ) ) ) (define (set seq i e) (cond ((null? seq) 'index-too-big) ((= i 0) (cons e (cdr seq))) (else (cons (car seq) (set (cdr seq) (- i 1) e))) ) ) (define (set-in-grid seq row-n col-n e) (cond ((null? seq) 'cannot-set) ((= row-n 0) (cons (set (car seq) col-n e) (cdr seq))) (else (cons (car seq) (set-in-grid (cdr seq) (- row-n 1) col-n e))) ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; MAIN PROCEDURE! START HERE (define (run rules n) (define psize 10) (pixelsize psize) ;(bgcolor (rgb (/ 196 255) (/ 196 255) (/ 196 255))); grey (bgcolor (rgb 0 0 0)) (pu) (ht) (speed 0) (loop rules n grid 50 50 0) (exitonclick) ) ; main loop (define (loop rules n grid xpos ypos dir) (if (= 0 (modulo n 100)) (begin (display n) (newline))) (define new (rules grid xpos ypos));find out new color and direction (define newcolor (car new));find out what color to draw (define newdir (cdr new));find out what direction to turn (define grid (set-in-grid grid xpos ypos newcolor));update the color in this place (pix xpos ypos (get-color newcolor) 20);draw the updated color with pixel size 5 (define dir (turn dir newdir));turn the turtle 90 degrees inthe appropriate direction (define ypos (+ ypos (cdr (move dir)))) (define xpos (+ xpos (car (move dir))));advance the turtle (if (> n 0) (loop rules (- n 1) grid xpos ypos dir) grid ) ) ; how a pixel is actually drawn (define (pix x y color_to_draw size) (speed 0) (goto (* (- x 50) size) (* (- y 50) size)) (color color_to_draw) (begin_fill) (forward size) (lt 90) (forward size) (lt 90) (forward size) (lt 90) (forward size) (lt 90) (end_fill) ) ;;;;;;;;;;;;;;;;;;;;;;;; ;define colors and turns (define white 0) (define red 1) (define green 2) (define blue 3) (define cyan 4) (define magenta 5) (define yellow 6) (define black 7) (define laura-color-1 8) (define laura-color-2 9) (define laura-color-3 10) (define laura-color-4 11) (define laura-color-5 12); define additional colors here (define (get-color c) (cond ((= c 0) (rgb 1 1 1)) ((= c 1) (rgb 1 0 0)) ((= c 2) (rgb 0 1 0)) ((= c 3) (rgb 0 0 1)) ((= c 4) (rgb 0 1 1)) ((= c 5) (rgb 1 0 1)) ((= c 6) (rgb 1 1 0)) ((= c 7) (rgb 0 0 0)) ((= c 8) (rgb (/ 99 255) (/ 126 255) (/ 242 255))) ((= c 9) (rgb (/ 242 255) (/ 215 255) (/ 99 255))) ((= c 10) (rgb (/ 99 255) (/ 235 255) (/ 242 255))) ((= c 11) (rgb (/ 240 255) (/ 34 255) (/ 192 255))) ((= c 12) (rgb (/ 62 255) (/ 10 255) (/ 204 255))); define additional colors here ) ) (define (turn dir-facing dir);return the resultant facing direction (cond ((= dir-facing 0);north (if (= dir 0) 3 ;left 1 ;right )) ((= dir-facing 1);east (if (= dir 0) 0 ;left 2 ;right )) ((= dir-facing 2);south (if (= dir 0) 1 ;left 3 ;right )) ((= dir-facing 3);west (if (= dir 0) 2 ;left 0 ;right )) ) ) (define (move dir);return the numbers to add to the position (cond ((= dir 0) '(0 . 1));north ((= dir 1) '(1 . 0));east ((= dir 2) '(0 . -1));south ((= dir 3) '(-1 . 0));west ) ) ;;;;;;;;;;;;;;;;;;;;;;;;;;; ; define some example rules (define classic (lambda (grid row col) (cond ((= (get-item-in-grid grid row col) red) (cons white 1)); left is 0, right is 1 ((= (get-item-in-grid grid row col) white) (cons red 0)) (else 'color-not-recognized) ) )) (define italy (lambda (grid row col) (cond ((= (get-item-in-grid grid row col) white) (cons red 1)) ((= (get-item-in-grid grid row col) red) (cons green 0)) ((= (get-item-in-grid grid row col) green) (cons white 0)) ) )) (define sheet (lambda (grid row col) (cond ((= (get-item-in-grid grid row col) white) (cons green 1)) ((= (get-item-in-grid grid row col) green) (cons cyan 1)) ((= (get-item-in-grid grid row col) cyan) (cons red 0)) ((= (get-item-in-grid grid row col) red) (cons yellow 1)) ((= (get-item-in-grid grid row col) yellow) (cons white 1)) ) )) (define pineapple (lambda (grid row col) (cond ((= (get-item-in-grid grid row col) white) (cons green 0)) ((= (get-item-in-grid grid row col) green) (cons cyan 1)) ((= (get-item-in-grid grid row col) cyan) (cons blue 0)) ((= (get-item-in-grid grid row col) blue) (cons red 0)) ((= (get-item-in-grid grid row col) red) (cons yellow 0)) ((= (get-item-in-grid grid row col) yellow) (cons magenta 1)) ((= (get-item-in-grid grid row col) magenta) (cons black 0)) ((= (get-item-in-grid grid row col) black) (cons laura-color-4 0)) ((= (get-item-in-grid grid row col) laura-color-4) (cons laura-color-3 0)) ((= (get-item-in-grid grid row col) laura-color-3) (cons laura-color-1 0)) ((= (get-item-in-grid grid row col) laura-color-1) (cons white 1)) ) )) (define laura (lambda (grid row col) (cond ((or (= (get-item-in-grid grid row col) laura-color-1) (= (get-item-in-grid grid row col) white)) (cons laura-color-2 1)) ((= (get-item-in-grid grid row col) laura-color-2) (cons laura-color-3 0)) ((= (get-item-in-grid grid row col) laura-color-3) (cons laura-color-4 0)) ((= (get-item-in-grid grid row col) laura-color-4) (cons laura-color-5 1)) ((= (get-item-in-grid grid row col) laura-color-5) (cons laura-color-1 1)) ) ))