4 ; Copyright © 2016 Keith Packard <keithp@keithp.com>
6 ; This program is free software; you can redistribute it and/or modify
7 ; it under the terms of the GNU General Public License as published by
8 ; the Free Software Foundation, either version 2 of the License, or
9 ; (at your option) any later version.
11 ; This program is distributed in the hope that it will be useful, but
12 ; WITHOUT ANY WARRANTY; without even the implied warranty of
13 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ; General Public License for more details.
18 ; ANSI control sequences
20 (defun move-to (col row)
21 (patom "\033[" row ";" col "H" nil)
28 (defun display-string (x y str)
33 ; Here's the pieces to display
35 (setq stack '("*" "**" "***" "****" "*****" "******" "*******"))
37 (setq top (+ (length stack) 3))
40 ; Here's all of the stacks of pieces
41 ; This is generated when the program is run
45 ; Display one stack, clearing any
48 (defun display-stack (x y clear stack)
51 (display-string x y (car stack))
52 (display-stack x (1+ y) 0 (cdr stack))
58 (display-string x y " ")
59 (display-stack x (1+ y) (1- clear) stack)
65 ; This should probably be included in the rom image...
68 (cond (list (1+ (length (cdr list))))
73 ; Position of the top of the stack on the screen
74 ; Shorter stacks start further down the screen
76 (defun stack-pos (y stack)
80 ; Display all of the stacks, spaced 20 columns apart
82 (defun display-stacks (x y stacks)
84 (display-stack x 0 (stack-pos y (car stacks)) (car stacks))
85 (display-stacks (+ x 20) y (cdr stacks)))
90 ; Display all of the stacks, then move the cursor
91 ; out of the way and flush the output
94 (display-stacks 0 top stacks)
99 ; Reset stacks to the starting state, with
100 ; all of the pieces in the first stack and the
103 (defun reset-stacks ()
104 (setq stacks (list stack nil nil))
108 ; more functions which could usefully
109 ; be in the rom image
118 (cond ((= n 0) (car list))
119 ((nth (cdr list) (1- n)))
123 ; Replace a stack in the list of stacks
126 (defun replace (list pos member)
127 (cond ((= pos 0) (cons member (cdr list)))
128 ((cons (car list) (replace (cdr list) (1- pos) member)))
132 ; Move a piece from the top of one stack
133 ; to the top of another
135 (defun move-piece (from to)
136 (let ((from-stack (nth stacks from))
137 (to-stack (nth stacks to))
138 (piece (car from-stack)))
139 (setq from-stack (cdr from-stack))
140 (setq to-stack (cons piece to-stack))
141 (setq stacks (replace stacks from from-stack))
142 (setq stacks (replace stacks to to-stack))
148 ; The implementation of the game
150 (defun _hanoi (n from to use)
158 (_hanoi (1- n) from use to)
159 (_hanoi 1 from to use)
160 (_hanoi (1- n) use to from)
166 ; A pretty interface which
167 ; resets the state of the game,
168 ; clears the screen and runs
172 (setq len (reset-stacks))