Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Step 2: commands

  • Loading branch information...
commit 40e592b732251f741a52efceb1b8ee1c903d8cfd 1 parent f526ade
@technomancy authored
View
2  mire.sh
@@ -1,3 +1,3 @@
#!/bin/sh
-java -cp jars/clojure.jar:jars/clojure-contrib.jar clojure.main src/mire.clj
+java -cp jars/clojure.jar:jars/clojure-contrib.jar:src/ clojure.main src/mire.clj
View
41 src/mire.clj
@@ -1,43 +1,20 @@
#!/usr/bin/env clj
-(add-classpath (str "file://" (.getParent (java.io.File. *file*)) "/"))
-
(ns mire
- (:use [mire commands player rooms])
+ (:use [mire commands])
(:use [clojure.contrib server-socket duck-streams]))
(def port 3333)
-
-(defn welcome []
- (dosync (commute *players* conj {*name* *out*})
- (commute (:inhabitants @*current-room*) conj *name*))
- (println "Welcome to Mire, " *name* "\n")
- (println (look))
- (print prompt) (flush))
-
-(defn cleanup []
- "Drop all inventory and remove player from room and player list."
- (doseq [thing @*inventory*] (discard thing))
- (dosync (commute *players* dissoc *name*)
- (commute (:inhabitants @*current-room*)
- (partial remove #(= % *name*)))))
+(def prompt "> ")
(defn- mire-handle-client [in out]
(binding [*in* (reader in)
*out* (writer out)]
- ;; bindings doesn't work sequentially, so we need to nest them
- ;; otherwise the call to read-name uses the old value of *in*/*out*
- (binding [*name* (read-name)
- *inventory* (ref [])
- *current-room* (ref (@mire.rooms/*rooms* :start))]
- (welcome)
- (try
- (loop [input (read-line)]
- (when input
- (println (execute input))
- (print prompt) (flush)
- (recur (read-line))))
- (finally (cleanup))))))
+ (print prompt) (flush)
+ (loop [input (read-line)]
+ (println (execute input))
+ (print prompt)
+ (flush)
+ (recur (read-line)))))
-(load-rooms (str (.getParent (java.io.File. *file*)) "/../data/rooms/"))
-(defonce server (create-server port mire-handle-client))
+(def server (create-server port mire-handle-client))
View
122 src/mire/commands.clj
@@ -1,120 +1,16 @@
(ns mire.commands
- (:use [mire player rooms util])
- (:use [clojure.contrib str-utils seq-utils]))
+ (:use [clojure.contrib str-utils]))
-(declare commands)
+(defn current-time []
+ (str "It is now "(java.util.Date.)))
-;; Command functions
-
-(defn look "Get a description of the surrounding environs and its contents."
- []
- (let [room @*current-room*]
- (str (:desc room) "\n"
- (look-exits room)
- (look-items room)
- (look-inhabitants room))))
-
-(defn inventory
- "What are we carrying? Let's take a look."
- []
- (if (empty? @*inventory*)
- "You are not carrying anything."
- (str-join "\n" (map #(:desc (*items* %)) @*inventory*))))
-
-(defn move
- "\"♬ We gotta get out of this place... ♪\" Give a direction."
- [direction]
- (let [target-name (@(:exits @*current-room*) (keyword direction))
- target (@*rooms* target-name)]
- (if target-name
- (dosync
- (move-between-refs *name*
- (:inhabitants @*current-room*)
- (:inhabitants target))
- (ref-set *current-room* target)
- (look))
- "You can't go that way.")))
-
-(defn grab
- "Pick something up."
- [thing]
- (dosync
- (if (room-contains? @*current-room* thing)
- (do (move-between-refs (keyword thing)
- (:items @*current-room*)
- *inventory*)
- (str "You picked up the " thing "."))
- (str "There isn't any " thing " here."))))
-
-(defn discard
- "Put something down."
- [thing]
- (dosync
- (if (inventory-contains? thing)
- (do (move-between-refs (keyword thing)
- *inventory*
- (:items @*current-room*))
- (str "You dropped up the " thing "."))
- (str "You don't have a " thing "."))))
-
-(defn say
- "Speak some words so that they can be heard by everyone within earshot."
- [& words]
- (let [string (str "\"" (str-join " " words) "\"")]
- (doseq [player @(:inhabitants @*current-room*)]
- (if (not (= player *name*))
- (binding [*out* (*players* player)]
- (println *name* "says:" string)
- (print prompt) (flush))))
- (str "You say: " string)))
-
-(defn help
- "Print an explaination of available commands."
- []
- ;; TODO: remove non-commands from output
- (str-join "\n" (map #(str (key %) ": " (:doc (meta (val %))))
- (ns-publics 'mire.commands))))
-
-;; Command data
-
-(def commands {"move" move
- "north" (fn [] (move :north))
- "south" (fn [] (move :south))
- "east" (fn [] (move :east))
- "west" (fn [] (move :west))
-
- "look" look
- "inventory" inventory
- "grab" grab
- "discard" discard
- "say" say
- "help" help
-
- ;; aliases
- "speak" say
- "go" move
- "get" grab
- "take" grab
- "drop" discard
-
- ;; for debugging
- "who" (fn [& args] *name*)
-
- "l" look
- "i" inventory})
-
-(def unknown-responses ["What you say?" "Speak up!" "I don't get it."
- "Please rephrase that." "Your words confuse me."])
-
-;; Command handling
+(def commands {"time" current-time,
+ "look" (fn [] "You see an empty room, waiting to be filled.")})
(defn execute
"Execute a command that is passed to us."
[input]
- (let [[command & args] (re-split #"\s+" input)]
- (try
- (apply (commands (.toLowerCase command)) args)
- (catch java.lang.NullPointerException _
- (pick-rand unknown-responses))
- (catch java.lang.IllegalArgumentException _
- "You can't do that."))))
+ (let [input-words (re-split #"\s+" input)
+ command (first input-words)
+ args (rest input-words)]
+ (apply (commands command) args)))
View
32 src/mire/player.clj
@@ -1,32 +0,0 @@
-(ns mire.player
- (:use [mire rooms])
- (:use [clojure.contrib seq-utils str-utils]))
-
-(def *players* (ref {}))
-(def prompt "> ")
-
-(declare *current-room* *inventory* *name*)
-
-(defn look-exits [room]
- (str "There are exits to the "
- (str-join " and " (map name (keys @(:exits @*current-room*))))
- ".\n"))
-
-(defn look-items [room]
- (str-join "\n" (map #(str "There is " (name %) " here.\n") @(:items room))))
-
-(defn look-inhabitants [room]
- (str-join "\n" (map #(if (not (= % *name*)) (str % " is here."))
- @(:inhabitants room))))
-
-(defn inventory-contains? [thing]
- (includes? @*inventory* (keyword thing)))
-
-(defn read-name []
- (print "\nWhat is your name? ") (flush)
- (loop [name (read-line)]
- (if (not (@*players* name))
- name
- (do (print "\nThat name is taken; please choose another: ")
- (flush)
- (recur (read-line))))))
View
33 src/mire/rooms.clj
@@ -1,33 +0,0 @@
-(ns mire.rooms
- (:use [clojure.contrib seq-utils]))
-
-(def *rooms* (ref {}))
-
-;; A single item can be instantiated many places. This map simply
-;; provides the descriptions and other properties for items.
-(def *items* {:keys {:desc "some keys"}
- :bunny {:desc "a bunny"}})
-
-(defn room-contains? [room thing]
- (includes? @(room :items) (keyword thing)))
-
-(defn make-room
- [name contents]
- (dosync (commute *rooms* conj
- {name {:name name :desc (:desc contents)
- :exits (ref (:exits contents))
- :items (ref (or (:items contents) []))
- :inhabitants (ref []) }})))
-
-(defn load-rooms
- "Load room definitions from dir.
-
-Each room should be a map containing a :desc key for a description,
-an :exits key with a map of exit directions to room names, and
-an :items key with a vector of item names. The :items entry may be
-omitted for rooms containing no items. The filename should be the room
-name."
- [dir]
- (doseq [file (.listFiles (java.io.File. dir))]
- (make-room (keyword (.getName file)) (read (java.io.PushbackReader.
- (java.io.FileReader. file))))))
View
22 src/mire/util.clj
@@ -1,22 +0,0 @@
-(ns mire.util
- (:use [clojure.contrib seq-utils]))
-
-(defn remove-first
- "Returns a lazy seq of the items in coll excluding the first for
- which (pred item) returns false. pred must be free of side-effects."
- [pred coll]
- (when (seq coll)
- (if (pred (first coll))
- (rest coll)
- (lazy-cons (first coll) (remove pred (rest coll))))))
-
-(defn move-between-refs
- "Move one instance of obj between ref1 and ref2. Must be called in a transaction."
- [obj from to]
- (commute from (partial remove-first #(= % obj)))
- (commute to conj obj))
-
-(defn pick-rand
- "Return a random element of vect."
- [vect]
- (vect (rand-int (count vect))))
Please sign in to comment.
Something went wrong with that request. Please try again.