Category : Miscellaneous Language Source Code
Archive   : XLISP21D.ZIP
Filename : TURTLES.LSP

 
Output of file : TURTLES.LSP contained in archive : XLISP21D.ZIP
(unless (fboundp 'defclass) (load 'classes))

; On an IBM PC, ANSI escape sequences probably won't work unless you use
; NNANSI.SYS because the buffered output used bypasses the BIOS.

; This is a sample XLISP program
; It implements a simple form of programmable turtle for VT100 compatible
; terminals.

; To run it:

; A>xlisp turtles

; This should cause the screen to be cleared and two turtles to appear.
; They should each execute their simple programs and then the prompt
; should return. Look at the code to see how all of this works.

; Get some more memory
(expand 1)

; delay a while
(if (fboundp 'get-internal-run-time)
(defun pause (time)
(let ((fintime (+ (* time internal-time-units-per-second)
(get-internal-run-time))))
(loop (when (> (get-internal-run-time) fintime)
(return-from pause)))))
(defun pause () (dotimes (x (* time 1000)))))

(defmacro delay () (pause 0.5))


; Clear the screen
(defun clear ()
(princ "\033[H\033[2J"))


; Move the cursor
(defun setpos (x y)
(princ "\033[") (princ y) (princ ";") (princ x) (princ "H"))

; Kill the remainder of the line
(defun kill ()
(princ "\033[K"))

; Move the cursor to the currently set bottom position and clear the line
; under it
(defun bottom ()
(setpos *bx* (+ *by* 1))
(kill)
(setpos *bx* *by*)
(kill))

; Clear the screen and go to the bottom
(defun cb ()
(clear)
(bottom))


; ::::::::::::
; :: Turtle ::
; ::::::::::::

; Define "Turtle" class
(defclass Turtle ((xpos (setq *newx* (+ *newx* 1))) (ypos 12) (char "*")))

; Message ":display" prints its char at its current position
(defmethod Turtle :display ()
(setpos xpos ypos)
(princ char)
(bottom)
self)

; When the character is set, we want to redisplay
(defmethod Turtle :set-char (c)
(setq char c)
(send self :display))

; Message ":char" sets char to its arg and displays it
(defmethod Turtle :set-char (c)
(setq char c)
(send self :display))

; Message ":goto" goes to a new place after clearing old one
(defmethod Turtle :goto (x y)
(setpos xpos ypos) (princ " ")
(setq xpos x)
(setq ypos y)
(send self :display))

; Message ":up" moves up if not at top
(defmethod Turtle :up ()
(if (> ypos 0)
(send self :goto xpos (- ypos 1))
(bottom)))

; Message ":down" moves down if not at bottom
(defmethod Turtle :down ()
(if (< ypos *by*)
(send self :goto xpos (+ ypos 1))
(bottom)))

; Message ":right" moves right if not at right
(defmethod Turtle :right ()
(if (< xpos 80)
(send self :goto (+ xpos 1) ypos)
(bottom)))

; Message ":left" moves left if not at left
(defmethod Turtle :left ()
(if (> xpos 0)
(send self :goto (- xpos 1) ypos)
(bottom)))

; :::::::::::::::::::
; :: Circular-List ::
; :::::::::::::::::::


; Define a class to represent a circular list
(defclass Circular-List (prog pc))

; Replace :isnew with something more appropriate
(defmethod Circular-List :isnew (&optional list)
(setf prog list pc list)
self) ; return self

; Method to get next item in list
(defmethod Circular-List :next ()
(when (null pc) (setq pc prog))
(prog1 (car pc) (setq pc (cdr pc))))


; :::::::::::::
; :: PTurtle ::
; :::::::::::::

; Define "PTurtle" programable turtle class
(defclass PTurtle (prog) () Turtle)

; Message ":program" stores a program
(defmethod PTurtle :program (p)
(setf prog (send Circular-List :new p))
self)

; Message ":step" executes a single program step
(defmethod PTurtle :step ()
(when prog (send self (send prog :next)))
(delay)
self)

; Message ":step#" steps each turtle program n times
(defmethod PTurtle :step# (n)
(dotimes (x n) (send self :step))
self)


; ::::::::::::::
; :: PTurtles ::
; ::::::::::::::

; Define "PTurtles" class
(defclass PTurtles (Turtles))

; Message ":make" makes a programable turtle and adds it to the collection
(defmethod PTurtles :make (x y &aux newturtle)
(setq newturtle (send PTurtle :new :xpos x :ypos y))
(setq Turtles (cons newturtle Turtles))
newturtle)

; Message ":step" steps each turtle program once
(defmethod PTurtles :step ()
(mapcar #'(lambda (Turtle) (send Turtle :step)) Turtles)
self)

; Message ":step#" steps each turtle program n times
(defmethod PTurtles :step# (n)
(dotimes (x n) (send self :step))
self)


; Initialize things and start up
(defvar *bx* 0)
(defvar *by* 20)
(defvar *newx* 0)

; Create some programmable turtles
(cb)
(definst PTurtles Turtles)
(setq t1 (send Turtles :make 40 10))
(setq t2 (send Turtles :make 41 10))
(send t1 :program '(:left :left :right :right :up :up :down :down))
(send t2 :program '(:right :right :down :down :left :left :up :up))
(send t1 :set-char "+")
(defun doit ()
(progn
(cb)
(send t1 :step# 8)
(send t2 :step# 8)
(send Turtles :step# 8)))
(doit)



  3 Responses to “Category : Miscellaneous Language Source Code
Archive   : XLISP21D.ZIP
Filename : TURTLES.LSP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/