-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrobots.lisp
80 lines (72 loc) · 2.22 KB
/
robots.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(load "ergolib/init")
(require :ergolib)
(define-synonym add1 1+)
(define-synonym sub1 1-)
(define-synonym eq? eq)
(define-synonym every? every)
(defun below (n) (counter 0 n))
(defc board-width 64)
(defc board-height 16)
(defc board-size (* board-width board-height))
(defc num-robots 10)
;; directions in dvorak keyboard layout
(defc directions `(
(g . ,(- (add1 board-width))) (c . ,(- board-width)) (r . ,(- (sub1 board-width)))
(h . -1) (n . 1)
(m . ,(sub1 board-width)) (w . ,board-width) (v . ,(add1 board-width))
))
(defun multiple? (val sequence)
(> (count val sequence) 1))
(defun manhattan-distance (p1 p2)
(+ (abs (- (mod p2 board-width)
(mod p1 board-width)))
(abs (- (truncate p2 board-width)
(truncate p1 board-width)))
))
(defun step-toward (aim current-pos)
(cdar (sort (for pair in directions collect
(bb new-pos (+ current-pos (cdr pair))
(cons (manhattan-distance aim new-pos)
new-pos)
))
'<
:key #'car
)))
(defun read-command (pos)
(format t "~%gcr/h n/mwv to move, (t)eleport, (l)eave:")
(force-output)
(bb c (read)
d (assoc c directions)
(mcond d (+ pos (cdr d))
(eq? 't c) (random board-size)
(eq? 'l c) nil
(read-command pos)
)))
(defun print-board (pos monsters)
(format t
(cat "~%|~{~<|~%|~," (->string (add1 board-width)) ":;~A~>~}|")
(for i in (below board-size) collect
(mcond
(member i monsters)
(if (multiple? i monsters) #\# #\A)
(= i pos) #\@
#\ ;
))))
(defun robots ()
(bb pos (+ (ash board-size -1) (ash board-width -1))
monsters (loop repeat num-robots collect (random board-size))
(iterate main ( (pos pos) (monsters monsters) )
(print-board pos monsters)
(bb new-pos (aif (read-command pos) it (return-from main 'bye))
(bb new-monsters
(for mpos in monsters collect
(if (multiple? mpos monsters)
mpos ; scrap doesn't move
(step-toward new-pos mpos)
))
(if (every? (fn (mpos) (multiple? mpos new-monsters)) new-monsters)
(return-from main 'player-wins)
(when (member new-pos new-monsters)
(return 'player-loses)))
(main new-pos new-monsters)
)))))