-
Notifications
You must be signed in to change notification settings - Fork 0
/
Wumpus.lisp
78 lines (67 loc) · 2.52 KB
/
Wumpus.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
(defparameter *worm-num* 10)
(defparameter *edge-num* 1000)
(defparameter *node-num* 1000)
(defun neighbors (node edge-alist)
(mapcar #'first (rest (assoc node edge-alist))))
(defun within-one (a b edge-alist)
(member b (neighbors a edge-alist)))
(defun within-two (a b edge-alist)
(or (within-one a b edge-alist)
(some (lambda(x)
(within-one x b edge-alist))
(neighbors a edge-alist))))
(defun make-city-nodes (edge-alist)
(let ((wumpus (random-node))
(glow-worms (loop for i below *worm-num*
collect (random-node))))
(loop for n from 1 to *node-num*
collect (append (list n)
(cond ((eql n wumpus) '(wumpus))
((within-two n wumpus edge-alist) '(blood!)))
(cond ((member n glow-worms)
'(glow-worm))
((some (lambda (worm)
(within-one n worm edge-alist))
glow-worms)
'(lights!)))
(when (some #'rest (rest (assoc n edge-alist)))
'(sirens!))))))
(defun get-connected (node edge-list)
(let ((visited nil))
(labels ((traverse (node)
(unless (member node visited)
(push node visited)
(mapc (lambda (edge)
(traverse (rest edge)))
(direct-edges node edge-list)))))
(traverse node))
visited))
(defun direct-edges (node edge-list)
(remove-if-not (lambda (x)
(eql (first x) node))
edge-list))
(defun make-edge-list ()
(apply #'append (loop repeat *edge-num*
collect (edge-pair (random-node) (random-node)))))
(defun edge-pair (a b)
(unless (eql a b)
(list (cons a b) (cons b a))))
(defun random-node ()
(1+ (random *node-num*)))
(defun hash-edges (edge-list)
(let ((tab (make-hash-table :size (length edge-list))))
(mapc (lambda (x)
(let ((node (first x)))
(push (rest x) (gethash node tab))))
edge-list)
tab))
(defun get-connected-hash (node edge-tab)
(let ((visited (make-hash-table)))
(labels ((traverse (node)
(unless (gethash node visited)
(setf (gethash node visited) t)
(mapc (lambda (edge)
(traverse edge))
(gethash node edge-tab)))))
(traverse node))
visited))