home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / lisp / interpre / xlispplu / lsp / turtles.lsp < prev    next >
Encoding:
Lisp/Scheme  |  1992-01-14  |  4.9 KB  |  202 lines

  1. (unless (fboundp 'defclass) (load 'classes))
  2.  
  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.
  5.  
  6. ; This is a sample XLISP program
  7. ; It implements a simple form of programmable turtle for VT100 compatible
  8. ; terminals.
  9.  
  10. ; To run it:
  11.  
  12. ;    A>xlisp turtles
  13.  
  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.
  17.  
  18. ; Get some more memory
  19. (expand 1)
  20.  
  21. ; delay a while
  22. (if (fboundp 'get-internal-run-time)
  23.     (defun pause (time) 
  24.        (let ((fintime (+ (* time internal-time-units-per-second)
  25.                  (get-internal-run-time))))
  26.         (loop (when (> (get-internal-run-time) fintime)
  27.                 (return-from pause)))))
  28.     (defun pause () (dotimes (x (* time 1000)))))
  29.  
  30. (defmacro delay () (pause 0.5))
  31.  
  32.  
  33. ; Clear the screen
  34. (defun clear ()
  35.     (princ "\033[H\033[2J"))
  36.  
  37. ; Move the cursor
  38. (defun setpos (x y)
  39.     (princ "\033[") (princ y) (princ ";") (princ x) (princ "H"))
  40.  
  41. ; Kill the remainder of the line
  42. (defun kill ()
  43.     (princ "\033[K"))
  44.  
  45. ; Move the cursor to the currently set bottom position and clear the line
  46. ;  under it
  47. (defun bottom ()
  48.     (setpos *bx* (+ *by* 1))
  49.     (kill)
  50.     (setpos *bx* *by*)
  51.     (kill))
  52.  
  53. ; Clear the screen and go to the bottom
  54. (defun cb ()
  55.     (clear)
  56.     (bottom))
  57.  
  58.  
  59. ; ::::::::::::
  60. ; :: Turtle ::
  61. ; ::::::::::::
  62.  
  63. ; Define "Turtle" class
  64. (defclass Turtle ((xpos (setq *newx* (+ *newx* 1))) (ypos 12) (char "*")))
  65.  
  66. ; Message ":display" prints its char at its current position
  67. (defmethod Turtle :display () 
  68.     (setpos xpos ypos)
  69.     (princ char)
  70.     (bottom)
  71.     self)
  72.  
  73. ; When the character is set, we want to redisplay
  74. (defmethod Turtle :set-char (c)
  75.     (setq char c)
  76.     (send self :display))
  77.  
  78. ; Message ":char" sets char to its arg and displays it
  79. (defmethod Turtle :set-char (c) 
  80.     (setq char c)
  81.     (send self :display))
  82.  
  83. ; Message ":goto" goes to a new place after clearing old one
  84. (defmethod Turtle :goto (x y)
  85.     (setpos xpos ypos) (princ " ")
  86.     (setq xpos x)
  87.     (setq ypos y)
  88.     (send self :display))
  89.  
  90. ; Message ":up" moves up if not at top
  91. (defmethod Turtle :up ()
  92.     (if (> ypos 0)
  93.     (send self :goto xpos (- ypos 1))
  94.     (bottom)))
  95.  
  96. ; Message ":down" moves down if not at bottom
  97. (defmethod Turtle :down ()
  98.     (if (< ypos *by*)
  99.     (send self :goto xpos (+ ypos 1))
  100.     (bottom)))
  101.  
  102. ; Message ":right" moves right if not at right
  103. (defmethod Turtle :right ()
  104.     (if (< xpos 80)
  105.     (send self :goto (+ xpos 1) ypos)
  106.     (bottom)))
  107.  
  108. ; Message ":left" moves left if not at left
  109. (defmethod Turtle :left ()
  110.     (if (> xpos 0)
  111.     (send self :goto (- xpos 1) ypos)
  112.     (bottom)))
  113.  
  114. ; :::::::::::::::::::
  115. ; :: Circular-List ::
  116. ; :::::::::::::::::::
  117.  
  118.  
  119. ; Define a class to represent a circular list
  120. (defclass Circular-List (prog pc))
  121.  
  122. ; Replace :isnew with something more appropriate
  123. (defmethod Circular-List :isnew (&optional list)
  124.     (setf prog list pc list)
  125.     self)    ; return self
  126.  
  127. ; Method to get next item in list
  128. (defmethod Circular-List :next ()
  129.     (when (null pc) (setq pc prog))
  130.     (prog1 (car pc) (setq pc (cdr pc))))
  131.  
  132.  
  133. ; :::::::::::::
  134. ; :: PTurtle ::
  135. ; :::::::::::::
  136.  
  137. ; Define "PTurtle" programable turtle class
  138. (defclass PTurtle (prog) () Turtle)
  139.  
  140. ; Message ":program" stores a program
  141. (defmethod PTurtle :program (p)
  142.     (setf prog (send Circular-List :new p))
  143.     self)
  144.  
  145. ; Message ":step" executes a single program step
  146. (defmethod PTurtle :step () 
  147.     (when prog (send self (send prog :next)))
  148.     (delay)
  149.     self)
  150.  
  151. ; Message ":step#" steps each turtle program n times
  152. (defmethod PTurtle :step# (n)
  153.     (dotimes (x n) (send self :step))
  154.     self)
  155.  
  156.  
  157. ; ::::::::::::::
  158. ; :: PTurtles ::
  159. ; ::::::::::::::
  160.  
  161. ; Define "PTurtles" class
  162. (defclass PTurtles (Turtles))
  163.  
  164. ; Message ":make" makes a programable turtle and adds it to the collection
  165. (defmethod PTurtles :make (x y &aux newturtle)
  166.     (setq newturtle (send PTurtle :new :xpos x :ypos y))
  167.     (setq Turtles (cons newturtle Turtles))
  168.     newturtle)
  169.  
  170. ; Message ":step" steps each turtle program once
  171. (defmethod PTurtles :step ()
  172.     (mapcar #'(lambda (Turtle) (send Turtle :step)) Turtles)
  173.     self)
  174.  
  175. ; Message ":step#" steps each turtle program n times
  176. (defmethod PTurtles :step# (n)
  177.     (dotimes (x n) (send self :step))
  178.     self)
  179.  
  180.  
  181. ; Initialize things and start up
  182. (defvar *bx* 0)
  183. (defvar *by* 20)
  184. (defvar *newx* 0)
  185.  
  186. ; Create some programmable turtles
  187. (cb)
  188. (definst PTurtles Turtles)
  189. (setq t1 (send Turtles :make 40 10))
  190. (setq t2 (send Turtles :make 41 10))
  191. (send t1 :program '(:left :left :right :right :up :up :down :down))
  192. (send t2 :program '(:right :right :down :down :left :left :up :up))
  193. (send t1 :set-char "+")
  194. (defun doit () 
  195.     (progn
  196.         (cb)
  197.         (send t1 :step# 8)
  198.         (send t2 :step# 8)
  199.         (send Turtles :step# 8)))
  200. (doit)
  201.  
  202.