Roboter-Simulator

Dies ist eine kurze Anleitung zum Haskell-Roboter-Simulator, der auf dem Blatt 9 erwähnt wird und auch in der Vorlesung kurz gezeigt wurde. Auf den SUN- und FreeBSD-Maschinen des WSI ist der Simulator bereits installiert. Damit Hugs die Bibliotheken des Simulators auch findet, muss man allerdings noch eine Kleinigkeit tun.

Den Simulator starten

Hugs sollte auf den SUN-Rechnern mit diesen Parametern gestartet werden:
hugs -h8192k -P/afs/wsi/pu/fp-2003/lib/hugs/sun4x_58/x11:

Auf den FreeBSD-Rechnern sieht der Aufruf so aus:
hugs -h8192k -P/afs/wsi/pu/fp-2003/lib/hugs/i386_fbsd46/x11:
Nun kann mit :load Robot der Simulator geladen werden. Ein Program das den Simulator verwendet kann mit import Robot das entsprechende Modul öffnen.

Simulatoren

Das Modul Robot beinhaltet drei verschiedene Simulatoren, die sich jedoch alle nur in ihrer Implementierung unterscheiden. Das heisst, die Roboter sollten sich in allen Varianten des Simulators gleich verhalten. Die Simulatoren unterscheiden sich nur hinsichtlich der Methode, wie das Fenster neu gezeichnet wird. Dadurch ergeben sich unterschiedliche Ablaufgeschwindigkeiten.
Die Simulatoren werden mit den Funktionen runRobot, runInvisibleRobot und runT3Arnie gestartet. runRobot startet den langsamen Simulator, der aber immer alles korrekt neu zeichnet, runT3Arnie kümmert sich nicht sonderlich um diese Thematik und ist deshalb sehr viel schneller. Startet man den Simulator mit runInvisibleRobot, so ist der Roboter unsichtbar und extrem schnell.

Simulation starten

Die Funktionen runRobot, runT3Arnie und runInvisibleRobot nehmen einen Roboter Robot () als Argument und setzen ihn einer leeren Welt aus. Diese Funktionen sind vom Typ runRobot,runT3Arnie,runInvisibleRobot :: Robot () -> IO ().
In diesem Beispiel wird ein Roboter, der sich gelegentlich in eine zufällige Richtung dreht, losgelassen:
[knauel@orionis fp-09] hugs -h8192k -P/afs/wsi/pu/fp-2003/lib/hugs/sun4x_58/x11:
[ ... Hugs Meldungen ...]
Prelude> :load Robot
[ ... noch mehr Hugs Meldungen ...]
Robot> runT3Arnie randomRobot
Der Simulator öffnet nun ein Fenster und wartet darauf das der Benutzer die Leertaste drückt, um die Simulation zu starten.
Bei den erwähnten drei Simulatoren ist die Welt immer leer und der Roboter wird in der Mitte des Welt ausgesetzt.

Simulation mit Labyrinth

Neben den erwähnten drei Simulatoren gibt es noch Simulaoren, die den Roboter in einem Labyrinth aussetzen. Auch hier stehen wieder drei Varianten zur Verfügung: runRobotInMaze, runT3ArnieInMaze und runInvisibleRobotInMaze. Diese Funktionen haben die Signaturen runRobotInMaze,runT3ArnieInMaze,runInvisibleRobotInMaze :: Robot () -> IO().
Bei jedem Start der Simulatoren wird ein neues zufälliges Labyrinth erzeugt und der Roboter in der linken unteren Ecke plaziert. Wie auf dem Aufgabenblatt beschrieben soll der Roboter nun einen Weg durch das Labyrinth finden, sich also in die rechte obere Ecke bewegen. Die Labyrinthe werden gerade so erzeugt, das es diesen Weg immer gibt.
Das Bild oben auf dieser Seite wurde gerade mit diesem Aufruf erzeugt und zeigt einen verwirrt (weil zufällig) in der Gegend umherlaufenden Roboter:
[knauel@orionis fp-09] hugs -h8192k -P/afs/wsi/pu/fp-2003/lib/hugs/sun4x_58/x11:
[ ... Hugs Meldungen ...]
Prelude> :load Robot
[ ... noch mehr Hugs Meldungen ...]
Robot> runT3ArnieInMaze randomRobot2
Hinweis für coole Hacker: Die Simulatoren sorgen dafür, dass der Roboter nach dem Start 100 Goldstücke bei sich hat. Vielleicht kann man (muss man aber nicht) diese Tatsache nutzen, um schneller einen Weg durch das Labyrinth zu finden?

Die Simulatoren aus dem XEmacs starten

Um die Simulatoren direkt aus dem XEmacs heraus zu starten, sind kleine Anpassungen an der ~/.xemacs/init.el bzw. ~/.emacs notwendig. Dort ist der folgende Eintrag vorzunehmen, bzw. der schon bestehende Eintrag für den Haskell-Mode durch diesen hier zu ersetzen:
Der Text zum Download.
;; Haskell mode
;; ############
(setq load-path (cons "/afs/informatik.uni-tuebingen.de/pu/fp-2003/lib/lisp" load-path))

(defun my-haskell-constants ()
  (let ((systype (getenv "SYSTYPE"))
	(std-switches '("+." "-h4096k"))
	(fp2003-lib-path "/afs/wsi/pu/fp-2003/lib/hugs"))
    (if (not (and systype 
		  (member systype 
			  '("i386_fbsd46" "sun4x_58" "ppc_macx66"))))
	(progn
	  (setq haskell-prog-switches std-switches)
	  (message 
	   (concat "Could not determine SYSTYPE / unsupported SYSTYPE. "
		   "Will not load Hugs Graphics library")))
      (setq haskell-prog-switches 
	    (cons (concat "-P" fp2003-lib-path "/" systype "/x11:") std-switches))))
   (setq haskell-prog-name (executable-find "hugs")
	 haskell-use-left-delim ""
	 haskell-use-right-delim ""
	 comint-prompt-pattern "^[A-Za-z0-9\-_]+> ")
   (set-face-background haskell-indentation-face
			(make-color-specifier "yellow"))
   (set-face-background haskell-indentation-face-2
			(make-color-specifier "yellow"))
   (define-key haskell-mode-map [delete] 'delete-char))

(add-hook 'haskell-mode-hook 'my-haskell-constants)

(setq auto-mode-alist 
      (cons '("\\.hs$" . haskell-mode)
	    (cons '("\\.lhs$" . haskell-mode)
		  auto-mode-alist)))
(autoload 'haskell-mode "haskell-mode" "Major mode for editing Haskell." t)


Eric Knauel
Last modified: Thu Jul 10 09:50:31 CEST 2003