aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/play/hanoi.el65
1 files changed, 23 insertions, 42 deletions
diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el
index 12a700d458e..ba74a2ba645 100644
--- a/lisp/play/hanoi.el
+++ b/lisp/play/hanoi.el
@@ -53,59 +53,40 @@
53;;;###autoload 53;;;###autoload
54(defun hanoi (nrings) 54(defun hanoi (nrings)
55 "Towers of Hanoi diversion. Argument is number of rings." 55 "Towers of Hanoi diversion. Argument is number of rings."
56 (interactive 56 (interactive "p")
57 (list (if (null current-prefix-arg) 57 (if (<= nrings 1) (setq nrings 7))
58 3
59 (prefix-numeric-value current-prefix-arg))))
60 (if (<= nrings 0) (error "Negative number of rings"))
61 (let* (floor-row 58 (let* (floor-row
62 fly-row 59 fly-row
63 (window-height (window-height (selected-window))) 60 (window-height (1- (window-height (selected-window))))
64 (window-width (window-width (selected-window))) 61 (window-width (window-width (selected-window)))
65 62
66 ;; This is the unit of spacing to use between poles. It 63 ;; This is half the spacing to use between poles.
67 ;; must be even. We round down, since rounding up might 64 (pole-spacing (/ window-width 6)))
68 ;; cause us to draw off the edge of the window. 65 (if (not (and (> window-height (1+ nrings))
69 (pole-spacing (logand (/ window-width 6) (lognot 1)))) 66 (> pole-spacing nrings)))
70 (let ( 67 (progn
71 ;; The poles are (1+ NRINGS) rows high; we also want an 68 (delete-other-windows)
72 ;; empty row at the top for the flying rings, a base, and a 69 (if (not (and (> (setq window-height
73 ;; blank line underneath that. 70 (1- (window-height (selected-window))))
74 (h (+ nrings 4)) 71 (1+ nrings))
75 72 (> (setq pole-spacing (/ window-width 6))
76 ;; If we have NRINGS rings, we label them with the numbers 0 73 nrings)))
77 ;; through NRINGS-1. The width of ring i is 2i+3; it pokes 74 (error "Window is too small (need at least %dx%d)"
78 ;; out i spaces on either side of the pole. Rather than 75 (* 6 (1+ nrings)) (+ 2 nrings)))))
79 ;; checking if the window is wide enough to accommodate this, 76 (setq floor-row (if (> (- window-height 3) (1+ nrings))
80 ;; we make sure pole-spacing is large enough, since that 77 (- window-height 3) window-height))
81 ;; works even when we have decremented pole-spacing to make
82 ;; it even.
83 (w (1+ nrings)))
84 (if (not (and (>= window-height h)
85 (> pole-spacing w)))
86 (progn
87 (delete-other-windows)
88 (if (not (and (>= (setq window-height
89 (window-height (selected-window)))
90 h)
91 (> (setq pole-spacing
92 (logand (/ window-width 6) (lognot 1)))
93 w)))
94 (error "Screen is too small (need at least %dx%d)" w h))))
95 (setq floor-row (if (> (- window-height 3) h)
96 (- window-height 3) window-height)))
97 (let ((fly-row (- floor-row nrings 1)) 78 (let ((fly-row (- floor-row nrings 1))
98 ;; pole: column . fill height 79 ;; pole: column . fill height
99 (pole-1 (cons pole-spacing floor-row)) 80 (pole-1 (cons (1- pole-spacing) floor-row))
100 (pole-2 (cons (* 3 pole-spacing) floor-row)) 81 (pole-2 (cons (1- (* 3 pole-spacing)) floor-row))
101 (pole-3 (cons (* 5 pole-spacing) floor-row)) 82 (pole-3 (cons (1- (* 5 pole-spacing)) floor-row))
102 (rings (make-vector nrings nil))) 83 (rings (make-vector nrings nil)))
103 ;; construct the ring list 84 ;; construct the ring list
104 (let ((i 0)) 85 (let ((i 0))
105 (while (< i nrings) 86 (while (< i nrings)
106 ;; ring: [pole-number string empty-string] 87 ;; ring: [pole-number string empty-string]
107 (aset rings i (vector nil 88 (aset rings i (vector nil
108 (make-string (+ i i 3) (+ ?0 i)) 89 (make-string (+ i i 3) (+ ?0 (% i 10)))
109 (make-string (+ i i 3) ?\ ))) 90 (make-string (+ i i 3) ?\ )))
110 (setq i (1+ i)))) 91 (setq i (1+ i))))
111 ;; 92 ;;
@@ -124,7 +105,7 @@
124 105
125 (let ((n 1)) 106 (let ((n 1))
126 (while (< n 6) 107 (while (< n 6)
127 (hanoi-topos fly-row (* n pole-spacing)) 108 (hanoi-topos fly-row (1- (* n pole-spacing)))
128 (setq n (+ n 2)) 109 (setq n (+ n 2))
129 (let ((i fly-row)) 110 (let ((i fly-row))
130 (while (< i floor-row) 111 (while (< i floor-row)