(lambda (world undoc) (letrec ( (cadr (lambda (x) (car (cdr x)))) (cddr (lambda (x) (cdr (cdr x)))) (caar (lambda (x) (car (car x)))) (cdar (lambda (x) (cdr (car x)))) (caddr (lambda (x) (car (cdr (cdr x))))) (cdddr (lambda (x) (cdr (cdr (cdr x))))) (cadddr (lambda (x) (car (cdr (cdr (cdr x)))))) (cddddr (lambda (x) (cdr (cdr (cdr (cdr x)))))) (length (lambda (l) (if (atom? l) 0 (length (cdr l))))) (nth (lambda (i l) (if (= i 0) (car l) (nth (- i 1) (cdr l))))) (map (lambda (f xs) (if (atom? xs) 0 (cons (f (car xs)) (cdr xs))) )) (append (lambda (xs ys) (if (atom? xs) ys (cons (car xs) (append (cdr xs) ys)) ) )) (concat (lambda (xss) (if (atom? xss) 0 (if (atom? (car xss)) (concat (cdr xss)) (cons (car (car xss)) (concat (cons (cdr (car xss)) (cdr xss)))) ) ) )) (mod (lambda (x y) (- x (* (/ x y) y)))) (id (lambda (x) x)) (const (lambda (x) (lambda (y) x))) (do2 (lambda (x y) y)) (randnext 1) (rand (lambda (limit) (mod (/ (set! randnext (mod (+ (* randnext 31337) 12345) 65536)) 64) limit ) )) (make-mutable (lambda (val) (let ((x val)) (lambda (f) (set! x (f x))) ) )) (mutable-get (lambda (m) (m id))) (mutable-set (lambda (m x) (m (const x)))) (mutable-map (lambda (m f) (m f))) ) (letrec ( (world-map car) (world-man cadr) (world-ghosts caddr) (world-fruit cdddr) (man-vitality car) (man-location cadr) (man-direction caddr) (man-lives cadddr) (man-score cddddr) (loc-x car) (loc-y cdr) (make-loc cons) (loc-move (lambda (loc dir) (if (< dir 2) (if (< dir 1) (cons (car loc) (- (cdr loc) 1)) (cons (+ (car loc) 1) (cdr loc)) ) (if (< dir 3) (cons (car loc) (+ (cdr loc) 1)) (cons (- (car loc) 1) (cdr loc)) ) ) )) (flipdir (lambda (dir) (if (< dir 2) (+ dir 2) (- dir 2)) )) (node-loc caar) (node-neighbors cdar) (node-neighbors-get (lambda (n) (mutable-get (cdar n)))) (node-neighbors-set (lambda (n x) (mutable-set (cdar n) x))) (node-state cadr) (node-state-get (lambda (n) (mutable-get (cadr n)))) (node-state-set (lambda (n x) (mutable-set (cadr n) x))) (node-bfs cddr) (node-bfs-get (lambda (n) (mutable-get (cddr n)))) (node-bfs-set (lambda (n x) (mutable-set (cddr n) x))) (make-node (lambda (loc ns s b) (cons (cons loc (make-mutable ns)) (cons (make-mutable s) (make-mutable b))))) (make-neighbors (lambda (u r d l) (cons u (cons r (cons d (cons l 0)))) )) (make-graph-row (lambda (x y n' r' r) (if (atom? r) 0 (let ((n (make-node (make-loc x y) (make-neighbors (if (atom? r') 0 (car r')) 0 0 n') (car r) -1))) (do2 (if (atom? n') 0 (node-neighbors-set n' (make-neighbors (nth 0 (node-neighbors-get n')) n (nth 2 (node-neighbors-get n')) (nth 3 (node-neighbors-get n')) ) ) ) (do2 (if (atom? r') 0 (node-neighbors-set (car r') (make-neighbors (nth 0 (node-neighbors-get (car r'))) (nth 1 (node-neighbors-get (car r'))) n (nth 3 (node-neighbors-get (car r'))) ) ) ) (cons n (make-graph-row (+ x 1) y n (if (atom? r') 0 (cdr r')) (cdr r)) ) ) ) ) ) )) (make-graph (lambda (y m r') (if (atom? m) 0 (let ((r (make-graph-row 0 y 0 r' (car m)))) (cons r (make-graph (+ y 1) (cdr m) r) ) ) ) )) (graph-get (lambda (g loc) (nth (car loc) (nth (cdr loc) g)) )) (init-bfs-row (lambda (r x) (if (atom? r) 0 (do2 (node-bfs-set (car r) x) (init-bfs-row (cdr r) x) ) ) )) (init-bfs (lambda (g x) (if (atom? g) 0 (do2 (init-bfs-row (car g) x) (init-bfs (cdr g) x) ) ) )) (bfs-finish (lambda (node) (let ( (depth (node-bfs-get node)) (depth' (- (node-bfs-get node) 1)) (neighbors (node-neighbors-get node)) ) (if (= 0 depth) -1 (let ((node'dir (if (= depth' (node-bfs-get (nth 0 neighbors))) (cons (nth 0 neighbors) 0) (if (= depth' (node-bfs-get (nth 1 neighbors))) (cons (nth 1 neighbors) 1) (if (= depth' (node-bfs-get (nth 2 neighbors))) (cons (nth 2 neighbors) 2) (if (= depth' (node-bfs-get (nth 3 neighbors))) (cons (nth 3 neighbors) 3) -1)))))) (if (= 1 depth) (flipdir (cdr node'dir)) (bfs-finish (car node'dir)) ) ) ) ) )) (bfs' (lambda (nodes nextnodes depth ok? done?) (if (atom? nodes) (if (atom? nextnodes) -2 (bfs' nextnodes 0 (+ 1 depth) ok? done?) ) (if (if (atom? (car nodes)) 0 (if (ok? (car nodes)) (= -1 (node-bfs-get (car nodes))) 0)) (do2 (node-bfs-set (car nodes) depth) (if (done? (car nodes)) (bfs-finish (car nodes)) (bfs' (cdr nodes) (append (node-neighbors-get (car nodes)) nextnodes) depth ok? done?) ) ) (bfs' (cdr nodes) nextnodes depth ok? done?) ) ) )) (bfs (lambda (g node ok? done?) (do2 (init-bfs g -1) (bfs' (cons node 0) 0 0 ok? done?) ) )) ) (letrec ( (graph 0) (step (lambda (state world) (let ( (mannode (graph-get graph (man-location (world-man world)))) ) (do2 (if (= 2 (node-state-get mannode)) (node-state-set mannode 1) 0 ) (let ((bfsdir (trace (bfs graph mannode node-state-get (lambda (node) (= 2 (node-state-get node))) )) )) (cons (trace (node-neighbors-get mannode)) (if (>= bfsdir 0) bfsdir (rand 4)))) ) ) )) ) (do2 (set! graph (make-graph 0 (world-map world) 0)) (cons 0 step) ) ))))