diff options
| -rw-r--r-- | lisp/play/hanoi.el | 65 |
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) |