diff options
Diffstat (limited to 'lisp')
| -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 @@ ;;;###autoload (defun hanoi (nrings) "Towers of Hanoi diversion. Argument is number of rings." - (interactive - (list (if (null current-prefix-arg) - 3 - (prefix-numeric-value current-prefix-arg)))) - (if (<= nrings 0) (error "Negative number of rings")) + (interactive "p") + (if (<= nrings 1) (setq nrings 7)) (let* (floor-row fly-row - (window-height (window-height (selected-window))) + (window-height (1- (window-height (selected-window)))) (window-width (window-width (selected-window))) - ;; This is the unit of spacing to use between poles. It - ;; must be even. We round down, since rounding up might - ;; cause us to draw off the edge of the window. - (pole-spacing (logand (/ window-width 6) (lognot 1)))) - (let ( - ;; The poles are (1+ NRINGS) rows high; we also want an - ;; empty row at the top for the flying rings, a base, and a - ;; blank line underneath that. - (h (+ nrings 4)) - - ;; If we have NRINGS rings, we label them with the numbers 0 - ;; through NRINGS-1. The width of ring i is 2i+3; it pokes - ;; out i spaces on either side of the pole. Rather than - ;; checking if the window is wide enough to accommodate this, - ;; we make sure pole-spacing is large enough, since that - ;; works even when we have decremented pole-spacing to make - ;; it even. - (w (1+ nrings))) - (if (not (and (>= window-height h) - (> pole-spacing w))) - (progn - (delete-other-windows) - (if (not (and (>= (setq window-height - (window-height (selected-window))) - h) - (> (setq pole-spacing - (logand (/ window-width 6) (lognot 1))) - w))) - (error "Screen is too small (need at least %dx%d)" w h)))) - (setq floor-row (if (> (- window-height 3) h) - (- window-height 3) window-height))) + ;; This is half the spacing to use between poles. + (pole-spacing (/ window-width 6))) + (if (not (and (> window-height (1+ nrings)) + (> pole-spacing nrings))) + (progn + (delete-other-windows) + (if (not (and (> (setq window-height + (1- (window-height (selected-window)))) + (1+ nrings)) + (> (setq pole-spacing (/ window-width 6)) + nrings))) + (error "Window is too small (need at least %dx%d)" + (* 6 (1+ nrings)) (+ 2 nrings))))) + (setq floor-row (if (> (- window-height 3) (1+ nrings)) + (- window-height 3) window-height)) (let ((fly-row (- floor-row nrings 1)) ;; pole: column . fill height - (pole-1 (cons pole-spacing floor-row)) - (pole-2 (cons (* 3 pole-spacing) floor-row)) - (pole-3 (cons (* 5 pole-spacing) floor-row)) + (pole-1 (cons (1- pole-spacing) floor-row)) + (pole-2 (cons (1- (* 3 pole-spacing)) floor-row)) + (pole-3 (cons (1- (* 5 pole-spacing)) floor-row)) (rings (make-vector nrings nil))) ;; construct the ring list (let ((i 0)) (while (< i nrings) ;; ring: [pole-number string empty-string] (aset rings i (vector nil - (make-string (+ i i 3) (+ ?0 i)) + (make-string (+ i i 3) (+ ?0 (% i 10))) (make-string (+ i i 3) ?\ ))) (setq i (1+ i)))) ;; @@ -124,7 +105,7 @@ (let ((n 1)) (while (< n 6) - (hanoi-topos fly-row (* n pole-spacing)) + (hanoi-topos fly-row (1- (* n pole-spacing))) (setq n (+ n 2)) (let ((i fly-row)) (while (< i floor-row) |
