Mercurial > hg > xemacs-beta
comparison lisp/games/hanoi.el @ 4:b82b59fe008d r19-15b3
Import from CVS: tag r19-15b3
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:46:56 +0200 |
parents | 376386a54a3c |
children | 131b0175ea99 |
comparison
equal
deleted
inserted
replaced
3:30df88044ec6 | 4:b82b59fe008d |
---|---|
6 | 6 |
7 ; Author (a) 1985, Damon Anton Permezel | 7 ; Author (a) 1985, Damon Anton Permezel |
8 ; This is in the public domain | 8 ; This is in the public domain |
9 ; since he distributed it without copyright notice in 1985. | 9 ; since he distributed it without copyright notice in 1985. |
10 | 10 |
11 ;;; Synched up with: FSF 19.30. | 11 ;; This file is part of XEmacs. |
12 | |
13 ;; XEmacs is free software; you can redistribute it and/or modify it | |
14 ;; under the terms of the GNU General Public License as published by | |
15 ;; the Free Software Foundation; either version 2, or (at your option) | |
16 ;; any later version. | |
17 | |
18 ;; XEmacs is distributed in the hope that it will be useful, but | |
19 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
21 ;; General Public License for more details. | |
22 | |
23 ;; You should have received a copy of the GNU General Public License | |
24 ;; along with XEmacs; see the file COPYING. If not, write to the Free | |
25 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
26 ;; 02111-1307, USA. | |
27 | |
28 ;;; Synched up with: FSF 19.34. | |
12 | 29 |
13 ;;; Commentary: | 30 ;;; Commentary: |
14 | 31 |
15 ;; Solves the Towers of Hanoi puzzle while-U-wait. | 32 ;; Solves the Towers of Hanoi puzzle while-U-wait. |
16 ;; | 33 ;; |
55 ;;;###autoload | 72 ;;;###autoload |
56 (defun hanoi (nrings) | 73 (defun hanoi (nrings) |
57 "Towers of Hanoi diversion. Argument is number of rings." | 74 "Towers of Hanoi diversion. Argument is number of rings." |
58 (interactive | 75 (interactive |
59 (list (if (null current-prefix-arg) | 76 (list (if (null current-prefix-arg) |
60 3 | 77 3 |
61 (prefix-numeric-value current-prefix-arg)))) | 78 (prefix-numeric-value current-prefix-arg)))) |
62 (if (<= nrings 0) (error "Negative number of rings")) | 79 (if (<= nrings 0) (error "Negative number of rings")) |
63 (let* (floor-row | 80 (let* (floor-row |
64 fly-row | 81 fly-row |
65 (window-height (window-height (selected-window))) | 82 (window-height (1- (window-height (selected-window)))) |
66 (window-width (window-width (selected-window))) | 83 (window-width (window-width (selected-window))) |
67 | 84 |
68 ;; This is the unit of spacing to use between poles. It | 85 ;; This is half the spacing to use between poles. |
69 ;; must be even. We round down, since rounding up might | 86 (pole-spacing (/ window-width 6))) |
70 ;; cause us to draw off the edge of the window. | 87 (if (not (and (> window-height (1+ nrings)) |
71 (pole-spacing (logand (/ window-width 6) (lognot 1)))) | 88 (> pole-spacing nrings))) |
72 (let ( | 89 (progn |
73 ;; The poles are (1+ NRINGS) rows high; we also want an | 90 (delete-other-windows) |
74 ;; empty row at the top for the flying rings, a base, and a | 91 (if (not (and (> (setq window-height |
75 ;; blank line underneath that. | 92 (1- (window-height (selected-window)))) |
76 (h (+ nrings 4)) | 93 (1+ nrings)) |
77 | 94 (> (setq pole-spacing (/ window-width 6)) |
78 ;; If we have NRINGS rings, we label them with the numbers 0 | 95 nrings))) |
79 ;; through NRINGS-1. The width of ring i is 2i+3; it pokes | 96 (error "Window is too small (need at least %dx%d)" |
80 ;; out i spaces on either side of the pole. Rather than | 97 (* 6 (1+ nrings)) (+ 2 nrings))))) |
81 ;; checking if the window is wide enough to accommodate this, | 98 (setq floor-row (if (> (- window-height 3) (1+ nrings)) |
82 ;; we make sure pole-spacing is large enough, since that | 99 (- window-height 3) window-height)) |
83 ;; works even when we have decremented pole-spacing to make | |
84 ;; it even. | |
85 (w (1+ nrings))) | |
86 (if (not (and (>= window-height h) | |
87 (> pole-spacing w))) | |
88 (progn | |
89 (delete-other-windows) | |
90 (if (not (and (>= (setq window-height | |
91 (window-height (selected-window))) | |
92 h) | |
93 (> (setq pole-spacing | |
94 (logand (/ window-width 6) (lognot 1))) | |
95 w))) | |
96 (error "Screen is too small (need at least %dx%d)" w h)))) | |
97 (setq floor-row (if (> (- window-height 3) h) | |
98 (- window-height 3) window-height))) | |
99 (let ((fly-row (- floor-row nrings 1)) | 100 (let ((fly-row (- floor-row nrings 1)) |
100 ;; pole: column . fill height | 101 ;; pole: column . fill height |
101 (pole-1 (cons pole-spacing floor-row)) | 102 (pole-1 (cons (1- pole-spacing) floor-row)) |
102 (pole-2 (cons (* 3 pole-spacing) floor-row)) | 103 (pole-2 (cons (1- (* 3 pole-spacing)) floor-row)) |
103 (pole-3 (cons (* 5 pole-spacing) floor-row)) | 104 (pole-3 (cons (1- (* 5 pole-spacing)) floor-row)) |
104 (rings (make-vector nrings nil))) | 105 (rings (make-vector nrings nil))) |
105 ;; construct the ring list | 106 ;; construct the ring list |
106 (let ((i 0)) | 107 (let ((i 0)) |
107 (while (< i nrings) | 108 (while (< i nrings) |
108 ;; ring: [pole-number string empty-string] | 109 ;; ring: [pole-number string empty-string] |
109 (aset rings i (vector nil | 110 (aset rings i (vector nil |
110 (make-string (+ i i 3) (+ ?0 i)) | 111 (make-string (+ i i 3) (+ ?0 (% i 10))) |
111 (make-string (+ i i 3) ?\ ))) | 112 (make-string (+ i i 3) ?\ ))) |
112 (setq i (1+ i)))) | 113 (setq i (1+ i)))) |
113 ;; | 114 ;; |
114 ;; init the screen | 115 ;; init the screen |
115 ;; | 116 ;; |
124 (insert ?\n))) | 125 (insert ?\n))) |
125 (insert-char ?= (1- window-width)) | 126 (insert-char ?= (1- window-width)) |
126 | 127 |
127 (let ((n 1)) | 128 (let ((n 1)) |
128 (while (< n 6) | 129 (while (< n 6) |
129 (hanoi-topos fly-row (* n pole-spacing)) | 130 (hanoi-topos fly-row (1- (* n pole-spacing))) |
130 (setq n (+ n 2)) | 131 (setq n (+ n 2)) |
131 (let ((i fly-row)) | 132 (let ((i fly-row)) |
132 (while (< i floor-row) | 133 (while (< i floor-row) |
133 (setq i (1+ i)) | 134 (setq i (1+ i)) |
134 (next-line 1) | 135 (next-line 1) |
149 (hanoi-draw-ring ring t nil) | 150 (hanoi-draw-ring ring t nil) |
150 (setcdr pole-1 (1- (cdr pole-1))) | 151 (setcdr pole-1 (1- (cdr pole-1))) |
151 (setq i (1+ i)))) | 152 (setq i (1+ i)))) |
152 (setq buffer-read-only t) | 153 (setq buffer-read-only t) |
153 (sit-for 0) | 154 (sit-for 0) |
154 ;; | 155 ;; Disable display of line and column numbers, for speed. |
155 ;; do it! | 156 (let ((line-number-mode nil) |
156 ;; | 157 (column-number-mode nil)) |
157 (hanoi0 (1- nrings) pole-1 pole-2 pole-3) | 158 ;; do it! |
159 (hanoi0 (1- nrings) pole-1 pole-2 pole-3)) | |
158 (goto-char (point-min)) | 160 (goto-char (point-min)) |
159 (message "Done") | 161 (message "Done") |
160 (setq buffer-read-only t) | 162 (setq buffer-read-only t) |
161 (force-mode-line-update) | 163 (force-mode-line-update) |
162 (sit-for 0)))) | 164 (sit-for 0)))) |