1 #-
:classes
(load "classes")
3 ; On an IBM PC, ANSI escape sequences probably won't work unless you use
4 ; NNANSI.SYS because the buffered output used bypasses the BIOS.
6 ; This is a sample XLISP program
7 ; It implements a simple form of programmable turtle for VT100 compatible
14 ; This should cause the screen to be cleared and two turtles to appear.
15 ; They should each execute their simple programs and then the prompt
16 ; should return. Look at the code to see how all of this works.
18 ; Get some more memory
22 #+:times
(defun pause (time)
23 (let ((fintime (+ (* time internal-time-units-per-second
)
24 (get-internal-run-time))))
25 (loop (when (> (get-internal-run-time) fintime
)
26 (return-from pause
)))))
27 #-
:times
(defun pause () (dotimes (x (* time
1000))))
29 (defmacro delay
() (pause 0.5))
34 (princ "\033[H\033[2J"))
38 (princ "\033[") (princ y
) (princ ";") (princ x
) (princ "H"))
40 ; Kill the remainder of the line
44 ; Move the cursor to the currently set bottom position and clear the line
47 (setpos *bx
* (+ *by
* 1))
52 ; Clear the screen and go to the bottom
62 ; Define "Turtle" class
63 (defclass Turtle
((xpos (setq *newx
* (+ *newx
* 1))) (ypos 12) (char "*")))
65 ; Message ":display" prints its char at its current position
66 (defmethod Turtle :display
()
72 ; When the character is set, we want to redisplay
73 (defmethod Turtle :set-char
(c)
77 ; Message ":char" sets char to its arg and displays it
78 (defmethod Turtle :set-char
(c)
82 ; Message ":goto" goes to a new place after clearing old one
83 (defmethod Turtle :goto
(x y
)
84 (setpos xpos ypos
) (princ " ")
89 ; Message ":up" moves up if not at top
90 (defmethod Turtle :up
()
92 (send self
:goto xpos
(- ypos
1))
95 ; Message ":down" moves down if not at bottom
96 (defmethod Turtle :down
()
98 (send self
:goto xpos
(+ ypos
1))
101 ; Message ":right" moves right if not at right
102 (defmethod Turtle :right
()
104 (send self
:goto
(+ xpos
1) ypos
)
107 ; Message ":left" moves left if not at left
108 (defmethod Turtle :left
()
110 (send self
:goto
(- xpos
1) ypos
)
113 ; :::::::::::::::::::
114 ; :: Circular-List ::
115 ; :::::::::::::::::::
118 ; Define a class to represent a circular list
119 (defclass Circular-List
(prog pc
))
121 ; Replace :isnew with something more appropriate
122 (defmethod Circular-List :isnew
(&optional list
)
123 (setf prog list pc list
)
126 ; Method to get next item in list
127 (defmethod Circular-List :next
()
128 (when (null pc
) (setq pc prog
))
129 (prog1 (car pc
) (setq pc
(cdr pc
))))
136 ; Define "PTurtle" programable turtle class
137 (defclass PTurtle
(prog) () Turtle
)
139 ; Message ":program" stores a program
140 (defmethod PTurtle :program
(p)
141 (setf prog
(send Circular-List
:new p
))
144 ; Message ":step" executes a single program step
145 (defmethod PTurtle :step
()
146 (when prog
(send self
(send prog
:next
)))
150 ; Message ":step#" steps each turtle program n times
151 (defmethod PTurtle :step
# (n)
152 (dotimes (x n
) (send self
:step
))
160 ; Define "PTurtles" class
161 (defclass PTurtles
(Turtles))
163 ; Message ":make" makes a programable turtle and adds it to the collection
164 (defmethod PTurtles :make
(x y
&aux newturtle
)
165 (setq newturtle
(send PTurtle
:new
:xpos x
:ypos y
))
166 (setq Turtles
(cons newturtle Turtles
))
169 ; Message ":step" steps each turtle program once
170 (defmethod PTurtles :step
()
171 (mapcar #'(lambda (Turtle) (send Turtle
:step
)) Turtles
)
174 ; Message ":step#" steps each turtle program n times
175 (defmethod PTurtles :step
# (n)
176 (dotimes (x n
) (send self
:step
))
180 ; Initialize things and start up
185 ; Create some programmable turtles
187 (definst PTurtles Turtles
)
188 (setq t1
(send Turtles
:make
40 10))
189 (setq t2
(send Turtles
:make
41 10))
190 (send t1
:program
'(:left
:left
:right
:right
:up
:up
:down
:down
))
191 (send t2
:program
'(:right
:right
:down
:down
:left
:left
:up
:up
))
192 (send t1
:set-char
"+")
198 (send Turtles
:step
# 8)))