Mercurial > emacs
view lisp/play/hanoi.el @ 59146:9bde7721ad0f
* dispextern.h: Change HAVE_CARBON to MAC_OS.
(struct glyph_string): Likewise.
* emacs.c (main) [MAC_OS8]: Call mac_term_init instead of
mac_initialize.
* fileio.c (Fnext_read_file_uses_dialog_p, Fread_file_name):
Change TARGET_API_MAC_CARBON to HAVE_CARBON.
* fns.c (vector): Change MAC_OSX to MAC_OS.
* frame.c (x_set_frame_parameters, x_report_frame_params)
(x_set_fullscreen): Remove #ifndef HAVE_CARBON.
(x_set_border_width, Vdefault_frame_scroll_bars): Change
HAVE_CARBON to MAC_OS.
* image.c [MAC_OS]: Include sys/stat.h.
[MAC_OS && !MAC_OSX]: Include sys/param.h, ImageCompression.h, and
QuickTimeComponents.h.
* mac.c [!MAC_OSX] (mac_wait_next_event): Add extern.
[!MAC_OSX] (select): Use mac_wait_next_event.
[!MAC_OSX] (run_mac_command): Change EXEC_SUFFIXES to
Vexec_suffixes.
[!MAC_OSX] (select, run_mac_command): Change `#ifdef
TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'.
(mac_clear_font_name_table): Add extern.
(Fmac_clear_font_name_table): New defun.
(syms_of_mac): Defsubr it.
[MAC_OSX] (SELECT_POLLING_PERIOD_USEC): New define.
[MAC_OSX] (select_and_poll_event): New function.
[MAC_OSX] (sys_select): Use it.
[MAC_OSX && SELECT_USE_CFSOCKET] (socket_callback): New function.
[MAC_OSX && SELECT_USE_CFSOCKET]
(SELECT_TIMEOUT_THRESHOLD_RUNLOOP, EVENT_CLASS_SOCK): New defines.
[MAC_OSX] (sys_select) [SELECT_USE_CFSOCKET]: Use CFSocket and
RunLoop for simultaneously monitoring two kinds of inputs, window
events and process outputs, without periodically polling.
* macfns.c (mac_initialized): Remove extern.
(stricmp): Put in #if 0. All callers changed to use xstricmp in
xfaces.c.
(strnicmp): Decrement `n' at the end of each loop, not the
beginning.
(check_mac): Use the term "Mac native windows" instead of "Mac
OS".
(check_x_display_info, x_display_info_for_name): Sync with xfns.c.
(mac_get_rdb_resource): New function (from w32reg.c).
(x_get_string_resource): Use it.
(install_window_handler): Add extern.
(mac_window): New function.
(Fx_create_frame): Use it instead of make_mac_frame. Set
parameter for Qfullscreen. Call x_wm_set_size_hint.
(Fx_open_connection, Fx_close_connection): New defuns.
(syms_of_macfns): Defsubr them.
(x_create_tip_frame) [TARGET_API_MAC_CARBON]: Add
kWindowNoUpdatesAttribute to the window attribute.
(x_create_tip_frame) [!TARGET_API_MAC_CARBON]: Use NewCWindow.
(x_create_tip_frame): Don't call ShowWindow.
(Fx_show_tip): Call ShowWindow.
(Fx_file_dialog): Change `#ifdef TARGET_API_MAC_CARBON' to `#if
TARGET_API_MAC_CARBON'.
(mac_frame_parm_handlers): Set handlers for Qfullscreen.
(syms_of_macfns) [MAC_OSX]: Initialize mac_in_use to 0.
* macgui.h [!MAC_OSX]: Don't include Controls.h. Include
Windows.h.
(Window): Typedef to WindowPtr and move outside `#if
TARGET_API_MAC_CARBON'.
(XSizeHints): New struct.
* macterm.c (x_update_begin, x_update_end)
[TARGET_API_MAC_CARBON]: Disable screen updates during update of a
frame.
(x_draw_glyph_string_background, x_draw_glyph_string_foreground)
[MAC_OS8]: Use XDrawImageString/XDrawImageString16.
(construct_mouse_click): Put in #if 0.
(x_check_fullscreen, x_check_fullscreen_move): Remove decls.
(x_scroll_bar_create, x_scroll_bar_handle_click): Change `#ifdef
TARGET_API_MAC_CARBON' to `#if TARGET_API_MAC_CARBON'.
(activate_scroll_bars, deactivate_scroll_bars)
[!TARGET_API_MAC_CARBON]: Use ActivateControl/DeactivateControl.
(x_make_frame_visible) [TARGET_API_MAC_CARBON]: Reposition window
if the position is neither user-specified nor program-specified.
(x_free_frame_resources): Free size_hints.
(x_wm_set_size_hint): Allocate size_hints if needed. Set
size_hints.
(mac_clear_font_name_table): New function.
(mac_do_list_fonts): Initialize font_name_table if needed.
(x_list_fonts): Don't initialize font_name_table. Add BLOCK_INPUT
around mac_do_list_fonts.
(mac_unload_font): New function.
(x_load_font): Add BLOCK_INPUT around XLoadQueryFont.
(init_mac_drag_n_drop, mac_do_receive_drag): Enclose declarations
and definitions with #if TARGET_API_MAC_CARBON.
[USE_CARBON_EVENTS] (mac_handle_window_event): Add decl.
(install_window_handler): Add decl.
(do_window_update): Add BeginUpdate/EndUpdate for the tooltip
window. Use UpdateControls. Get the rectangle that should be
updated and restrict the target of expose_frame to it.
(do_grow_window): Set minimum height/width according to
size_hints.
(do_grow_window) [TARGET_API_MAC_CARBON]: Use ResizeWindow.
(do_zoom_window): Don't use x_set_window_size.
[USE_CARBON_EVENTS] (mac_handle_window_event): New function.
(install_window_handler): New function.
[!USE_CARBON_EVENTS] (mouse_region): New variable.
[!USE_CARBON_EVENTS] (mac_wait_next_event): New function.
(XTread_socket) [USE_CARBON_EVENTS]: Move call to
GetEventDispatcherTarget inside BLOCK_INPUT.
(XTread_socket) [!USE_CARBON_EVENTS]: Use mac_wait_next_event.
Update mouse_region when mouse is moved.
(make_mac_frame): Remove.
(make_mac_terminal_frame): Put in #ifdef MAC_OS8. Initialize
mouse pointer shapes. Change values of f->left_pos and
f->top_pos. Don't use make_mac_frame. Use NewCWindow. Don't
call ShowWindow.
(mac_initialize_display_info) [MAC_OSX]: Create mac_id_name from
Vinvocation_name and Vsystem_name.
(mac_make_rdb): New function (from w32term.c).
(mac_term_init): Use it. Add BLOCK_INPUT. Error if display has
already been opened. Don't pass argument to
mac_initialize_display_info. Don't set dpyinfo->height/width.
Add entries to x_display_list and x_display_name_list.
(x_delete_display): New function.
(mac_initialize): Don't call mac_initialize_display_info.
(syms_of_macterm) [!MAC_OSX]: Don't call Fprovide.
* macterm.h (check_mac): Add extern.
(struct mac_output): New member size_hints.
(FRAME_SIZE_HINTS): New macro.
(mac_unload_font): Add extern.
* xdisp.c (expose_window, expose_frame): Remove kludges for Mac.
* xfaces.c (clear_font_table) [MAC_OS]: call mac_unload_font.
author | Steven Tamm <steventamm@mac.com> |
---|---|
date | Mon, 27 Dec 2004 17:27:30 +0000 |
parents | 695cf19ef79e |
children | bedc73f663be 375f2633d815 |
line wrap: on
line source
;;; hanoi.el --- towers of hanoi in Emacs ;; Author: Damon Anton Permezel ;; Maintainer: FSF ;; Keywords: games ; Author (a) 1985, Damon Anton Permezel ; This is in the public domain ; since he distributed it without copyright notice in 1985. ;; This file is part of GNU Emacs. ; ; Support for horizontal poles, large numbers of rings, real-time, ; faces, defcustom, and Towers of Unix added in 1999 by Alakazam ; Petrofsky <Alakazam@Petrofsky.Berkeley.CA.US>. ;;; Commentary: ;; Solves the Towers of Hanoi puzzle while-U-wait. ;; ;; The puzzle: Start with N rings, decreasing in sizes from bottom to ;; top, stacked around a post. There are two other posts. Your mission, ;; should you choose to accept it, is to shift the pile, stacked in its ;; original order, to another post. ;; ;; The challenge is to do it in the fewest possible moves. Each move ;; shifts one ring to a different post. But there's a rule; you can ;; only stack a ring on top of a larger one. ;; ;; The simplest nontrivial version of this puzzle is N = 3. Solution ;; time rises as 2**N, and programs to solve it have long been considered ;; classic introductory exercises in the use of recursion. ;; ;; The puzzle is called `Towers of Hanoi' because an early popular ;; presentation wove a fanciful legend around it. According to this ;; myth (uttered long before the Vietnam War), there is a Buddhist ;; monastery at Hanoi which contains a large room with three time-worn ;; posts in it surrounded by 21 golden discs. Monks, acting out the ;; command of an ancient prophecy, have been moving these disks, in ;; accordance with the rules of the puzzle, once every day since the ;; monastery was founded over a thousand years ago. They are said to ;; believe that when the last move of the puzzle is completed, the ;; world will end in a clap of thunder. Fortunately, they are nowhere ;; even close to being done... ;; ;; 1999 addition: The `Towers of Unix' command (hanoi-unix) stems from ;; the never-disproven legend of a Eunuch monastery at Princeton that ;; contains a large air-conditioned room with three time-worn posts in ;; it surrounded by 32 silicon discs. Nimble monks, acting out the ;; command of an ancient prophecy, have been moving these disks, in ;; accordance with the rules of the puzzle, once every second since ;; the monastery was founded almost a billion seconds ago. They are ;; said to believe that when the last move of the puzzle is completed, ;; the world will reboot in a clap of thunder. Actually, because the ;; bottom disc is blocked by the "Do not feed the monks" sign, it is ;; believed the End will come at the time that disc is to be moved... ;;; Code: (eval-when-compile (require 'cl) ;; dynamic bondage: (defvar baseward-step) (defvar fly-step) (defvar fly-row-start) (defvar pole-width) (defvar pole-char) (defvar line-offset)) (defgroup hanoi nil "The Towers of Hanoi." :group 'games) (defcustom hanoi-horizontal-flag nil "*If non-nil, hanoi poles are oriented horizontally." :group 'hanoi :type 'boolean) (defcustom hanoi-move-period 1.0 "*Time, in seconds, for each pole-to-pole move of a ring. If nil, move rings as fast as possible while displaying all intermediate positions." :group 'hanoi :type '(restricted-sexp :match-alternatives (numberp 'nil))) (defcustom hanoi-use-faces nil "*If nil, all hanoi-*-face variables are ignored." :group 'hanoi :type 'boolean) (defcustom hanoi-pole-face 'highlight "*Face for poles. Ignored if hanoi-use-faces is nil." :group 'hanoi :type 'face) (defcustom hanoi-base-face 'highlight "*Face for base. Ignored if hanoi-use-faces is nil." :group 'hanoi :type 'face) (defcustom hanoi-even-ring-face 'region "*Face for even-numbered rings. Ignored if hanoi-use-faces is nil." :group 'hanoi :type 'face) (defcustom hanoi-odd-ring-face 'secondary-selection "*Face for odd-numbered rings. Ignored if hanoi-use-faces is nil." :group 'hanoi :type 'face) ;;; ;;; hanoi - user callable Towers of Hanoi ;;; ;;;###autoload (defun hanoi (nrings) "Towers of Hanoi diversion. Use NRINGS rings." (interactive (list (if (null current-prefix-arg) 3 (prefix-numeric-value current-prefix-arg)))) (if (< nrings 0) (error "Negative number of rings")) (hanoi-internal nrings (make-list nrings 0) (hanoi-current-time-float))) ;;;###autoload (defun hanoi-unix () "Towers of Hanoi, UNIX doomsday version. Displays 32-ring towers that have been progressing at one move per second since 1970-01-01 00:00:00 GMT. Repent before ring 31 moves." (interactive) (let* ((start (ftruncate (hanoi-current-time-float))) (bits (loop repeat 32 for x = (/ start (expt 2.0 31)) then (* x 2.0) collect (truncate (mod x 2.0)))) (hanoi-move-period 1.0)) (hanoi-internal 32 bits start))) ;;;###autoload (defun hanoi-unix-64 () "Like hanoi-unix, but pretend to have a 64-bit clock. This is, necessarily (as of emacs 20.3), a crock. When the current-time interface is made s2G-compliant, hanoi.el will need to be updated." (interactive) (let* ((start (ftruncate (hanoi-current-time-float))) (bits (loop repeat 64 for x = (/ start (expt 2.0 63)) then (* x 2.0) collect (truncate (mod x 2.0)))) (hanoi-move-period 1.0)) (hanoi-internal 64 bits start))) (defun hanoi-internal (nrings bits start-time) "Towers of Hanoi internal interface. Use NRINGS rings. Start after n steps, where BITS is a big-endian list of the bits of n. BITS must be of length nrings. Start at START-TIME." (switch-to-buffer "*Hanoi*") (buffer-disable-undo (current-buffer)) (unwind-protect (let* (;; These lines can cause emacs to crash if you ask for too ;; many rings. If you uncomment them, on most systems you ;; can get 10,000+ rings. ;;(max-specpdl-size (max max-specpdl-size (* nrings 15))) ;;(max-lisp-eval-depth (max max-lisp-eval-depth (+ nrings 20))) (vert (not hanoi-horizontal-flag)) (pole-width (length (format "%d" (max 0 (1- nrings))))) (pole-char (if vert ?\| ?\-)) (base-char (if vert ?\= ?\|)) (base-len (max (+ 8 (* pole-width 3)) (1- (if vert (window-width) (window-height))))) (max-ring-diameter (/ (- base-len 2) 3)) (pole1-coord (/ max-ring-diameter 2)) (pole2-coord (/ base-len 2)) (pole3-coord (- base-len (/ (1+ max-ring-diameter) 2))) (pole-coords (list pole1-coord pole2-coord pole3-coord)) ;; Number of lines displayed below the bottom-most rings. (base-lines (min 3 (max 0 (- (1- (if vert (window-height) (window-width))) (+ 2 nrings))))) ;; These variables will be set according to hanoi-horizontal-flag: ;; line-offset is the number of characters per line in the buffer. line-offset ;; fly-row-start is the buffer position of the leftmost or ;; uppermost position in the fly row. fly-row-start ;; Adding fly-step to a buffer position moves you one step ;; along the fly row in the direction from pole1 to pole2. fly-step ;; Adding baseward-step to a buffer position moves you one step ;; toward the base. baseward-step ) (setq buffer-read-only nil) (erase-buffer) (setq truncate-lines t) (if hanoi-horizontal-flag (progn (setq line-offset (+ base-lines nrings 3)) (setq fly-row-start (1- line-offset)) (setq fly-step line-offset) (setq baseward-step -1) (loop repeat base-len do (unless (zerop base-lines) (insert-char ?\ (1- base-lines)) (insert base-char) (hanoi-put-face (1- (point)) (point) hanoi-base-face)) (insert-char ?\ (+ 2 nrings)) (insert ?\n)) (delete-char -1) (loop for coord in pole-coords do (loop for row from (- coord (/ pole-width 2)) for start = (+ (* row line-offset) base-lines 1) repeat pole-width do (subst-char-in-region start (+ start nrings 1) ?\ pole-char) (hanoi-put-face start (+ start nrings 1) hanoi-pole-face)))) ;; vertical (setq line-offset (1+ base-len)) (setq fly-step 1) (setq baseward-step line-offset) (let ((extra-lines (- (1- (window-height)) (+ nrings 2) base-lines))) (insert-char ?\n (max 0 extra-lines)) (setq fly-row-start (point)) (insert-char ?\ base-len) (insert ?\n) (loop repeat (1+ nrings) with pole-line = (loop with line = (make-string base-len ?\ ) for coord in pole-coords for start = (- coord (/ pole-width 2)) for end = (+ start pole-width) do (hanoi-put-face start end hanoi-pole-face line) (loop for i from start below end do (aset line i pole-char)) finally return line) do (insert pole-line ?\n)) (insert-char base-char base-len) (hanoi-put-face (- (point) base-len) (point) hanoi-base-face) (set-window-start (selected-window) (1+ (* baseward-step (max 0 (- extra-lines))))))) (let (;; each pole is a pair of buffer positions: ;; the car is the position of the top ring currently on the pole, ;; (or the base of the pole if it is empty). ;; the cdr is in the fly-row just above the pole. (poles (loop for coord in pole-coords for fly-pos = (+ fly-row-start (* fly-step coord)) for base = (+ fly-pos (* baseward-step (+ 2 nrings))) collect (cons base fly-pos))) ;; compute the string for each ring and make the list of ;; ring pairs. Each ring pair is initially (str . diameter). ;; Once placed in buffer it is changed to (center-pos . diameter). (rings (loop ;; radii are measured from the edge of the pole out. ;; So diameter = 2 * radius + pole-width. When ;; there's room, we make each ring's radius = ;; pole-number + 1. If there isn't room, we step ;; evenly from the max radius down to 1. with max-radius = (min nrings (/ (- max-ring-diameter pole-width) 2)) for n from (1- nrings) downto 0 for radius = (1+ (/ (* n max-radius) nrings)) for diameter = (+ pole-width (* 2 radius)) with format-str = (format "%%0%dd" pole-width) for str = (concat (if vert "<" "^") (make-string (1- radius) (if vert ?\- ?\|)) (format format-str n) (make-string (1- radius) (if vert ?\- ?\|)) (if vert ">" "v")) for face = (if (eq (logand n 1) 1) ; oddp would require cl at runtime hanoi-odd-ring-face hanoi-even-ring-face) do (hanoi-put-face 0 (length str) face str) collect (cons str diameter))) ;; Disable display of line and column numbers, for speed. (line-number-mode nil) (column-number-mode nil)) ;; do it! (hanoi-n bits rings (car poles) (cadr poles) (caddr poles) start-time)) (message "Done")) (setq buffer-read-only t) (force-mode-line-update))) (defun hanoi-current-time-float () "Return values from current-time combined into a single float." (destructuring-bind (high low micros) (current-time) (+ (* high 65536.0) low (/ micros 1000000.0)))) (defun hanoi-put-face (start end value &optional object) "If hanoi-use-faces is non-nil, call put-text-property for face property." (if hanoi-use-faces (put-text-property start end 'face value object))) ;;; Functions with a start-time argument (hanoi-0, hanoi-n, and ;;; hanoi-move-ring) start working at start-time and return the ending ;;; time. If hanoi-move-period is nil, start-time is ignored and the ;;; return value is junk. ;;; ;;; hanoi-0 - work horse of hanoi (defun hanoi-0 (rings from to work start-time) (if (null rings) start-time (hanoi-0 (cdr rings) work to from (hanoi-move-ring (car rings) from to (hanoi-0 (cdr rings) from work to start-time))))) ;; start after n moves, where BITS is a big-endian list of the bits of n. ;; BITS must be of same length as rings. (defun hanoi-n (bits rings from to work start-time) (cond ((null rings) ;; All rings have been placed in starting positions. Update display. (hanoi-sit-for 0) start-time) ((zerop (car bits)) (hanoi-insert-ring (car rings) from) (hanoi-0 (cdr rings) work to from (hanoi-move-ring (car rings) from to (hanoi-n (cdr bits) (cdr rings) from work to start-time)))) (t (hanoi-insert-ring (car rings) to) (hanoi-n (cdr bits) (cdr rings) work to from start-time)))) ;; put never-before-placed RING on POLE and update their cars. (defun hanoi-insert-ring (ring pole) (decf (car pole) baseward-step) (let ((str (car ring)) (start (- (car pole) (* (/ (cdr ring) 2) fly-step)))) (setcar ring (car pole)) (loop for pos upfrom start by fly-step for i below (cdr ring) do (subst-char-in-region pos (1+ pos) (char-after pos) (aref str i)) (set-text-properties pos (1+ pos) (text-properties-at i str))) (hanoi-goto-char (car pole)))) ;; like goto-char, but if position is outside the window, then move to ;; corresponding position in the first row displayed. (defun hanoi-goto-char (pos) (goto-char (if (or hanoi-horizontal-flag (<= (window-start) pos)) pos (+ (window-start) (% (- pos fly-row-start) baseward-step))))) ;; do one pole-to-pole move and update the ring and pole pairs. (defun hanoi-move-ring (ring from to start-time) (incf (car from) baseward-step) (decf (car to) baseward-step) (let* ;; We move flywards-steps steps up the pole to the fly row, ;; then fly fly-steps steps across the fly row, then go ;; baseward-steps steps down the new pole. ((flyward-steps (/ (- (car ring) (cdr from)) baseward-step)) (fly-steps (abs (/ (- (cdr to) (cdr from)) fly-step))) (directed-fly-step (/ (- (cdr to) (cdr from)) fly-steps)) (baseward-steps (/ (- (car to) (cdr to)) baseward-step)) (total-steps (+ flyward-steps fly-steps baseward-steps)) ;; A step is a character cell. A tick is a time-unit. To ;; make horizontal and vertical motion appear roughly the ;; same speed, we allow one tick per horizontal step and two ;; ticks per vertical step. (ticks-per-pole-step (if hanoi-horizontal-flag 1 2)) (ticks-per-fly-step (if hanoi-horizontal-flag 2 1)) (flyward-ticks (* ticks-per-pole-step flyward-steps)) (fly-ticks (* ticks-per-fly-step fly-steps)) (baseward-ticks (* ticks-per-pole-step baseward-steps)) (total-ticks (+ flyward-ticks fly-ticks baseward-ticks)) (tick-to-pos ;; Return the buffer position of the ring after TICK ticks. (lambda (tick) (cond ((<= tick flyward-ticks) (+ (cdr from) (* baseward-step (- flyward-steps (/ tick ticks-per-pole-step))))) ((<= tick (+ flyward-ticks fly-ticks)) (+ (cdr from) (* directed-fly-step (/ (- tick flyward-ticks) ticks-per-fly-step)))) (t (+ (cdr to) (* baseward-step (/ (- tick flyward-ticks fly-ticks) ticks-per-pole-step)))))))) (if hanoi-move-period (loop for elapsed = (- (hanoi-current-time-float) start-time) while (< elapsed hanoi-move-period) with tick-period = (/ (float hanoi-move-period) total-ticks) for tick = (ceiling (/ elapsed tick-period)) do (hanoi-ring-to-pos ring (funcall tick-to-pos tick)) (hanoi-sit-for (- (* tick tick-period) elapsed))) (loop for tick from 1 to total-ticks by 2 do (hanoi-ring-to-pos ring (funcall tick-to-pos tick)) (hanoi-sit-for 0))) ;; Always make last move to keep pole and ring data consistent (hanoi-ring-to-pos ring (car to)) (if hanoi-move-period (+ start-time hanoi-move-period)))) ;; update display and pause, quitting with a pithy comment if the user ;; hits a key. (defun hanoi-sit-for (seconds) (sit-for seconds) (if (input-pending-p) (signal 'quit '("I can tell you've had enough")))) ;; move ring to a given buffer position and update ring's car. (defun hanoi-ring-to-pos (ring pos) (unless (= (car ring) pos) (let* ((start (- (car ring) (* (/ (cdr ring) 2) fly-step))) (new-start (- pos (- (car ring) start)))) (if hanoi-horizontal-flag (loop for i below (cdr ring) for j = (if (< new-start start) i (- (cdr ring) i 1)) for old-pos = (+ start (* j fly-step)) for new-pos = (+ new-start (* j fly-step)) do (transpose-regions old-pos (1+ old-pos) new-pos (1+ new-pos))) (let ((end (+ start (cdr ring))) (new-end (+ new-start (cdr ring)))) (if (< (abs (- new-start start)) (- end start)) ;; Overlap. Adjust bounds (if (< start new-start) (setq new-start end) (setq new-end start))) (transpose-regions start end new-start new-end t)))) ;; If moved on or off a pole, redraw pole chars. (unless (eq (hanoi-pos-on-tower-p (car ring)) (hanoi-pos-on-tower-p pos)) (let* ((pole-start (- (car ring) (* fly-step (/ pole-width 2)))) (pole-end (+ pole-start (* fly-step pole-width))) (on-pole (hanoi-pos-on-tower-p (car ring))) (new-char (if on-pole pole-char ?\ )) (curr-char (if on-pole ?\ pole-char)) (face (if on-pole hanoi-pole-face nil))) (if hanoi-horizontal-flag (loop for pos from pole-start below pole-end by line-offset do (subst-char-in-region pos (1+ pos) curr-char new-char) (hanoi-put-face pos (1+ pos) face)) (subst-char-in-region pole-start pole-end curr-char new-char) (hanoi-put-face pole-start pole-end face)))) (setcar ring pos)) (hanoi-goto-char pos)) ;; Check if a buffer position lies on a tower (vis. in the fly row). (defun hanoi-pos-on-tower-p (pos) (if hanoi-horizontal-flag (/= (% pos fly-step) fly-row-start) (>= pos (+ fly-row-start baseward-step)))) (provide 'hanoi) ;;; arch-tag: 7a901659-4346-495c-8883-14cbf540610c ;;; hanoi.el ends here