Changes between Version 67 and Version 68 of Clojure Client Tutorial
- Timestamp:
- Aug 22, 2011 12:44:17 PM (13 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Clojure Client Tutorial
v67 v68 121 121 122 122 {{{ 123 client.core=> (run-ioquake "sat") 123 client.core=> (run-ioquake "sat") 124 124 #<UNIXProcess java.lang.UNIXProcess@56c3cf> 125 125 }}} … … 169 169 Now say you want to define a function on the fly to send an op to the server, this can be done with either "send-and-forget", "send-and-get", "send-and-get-later", and "send-and-watch". These functions provide a human-readable interface to protocol zero by mapping all of the op codes to keywords. Here is the full list of keyword arguments subject to change). 170 170 171 * :move-indefinitely "mi" 172 * :move-for "mf" 173 * :move-by "mb" 174 * :move-to "mt" 175 * :jump-once "ju" 176 * :rotate "ro" 177 * :fire-weapon "fw" 178 * :switch-weapon "sw" 179 * :set-crouch "sc" 180 * :shove "sv" 181 * :say "sy" 182 * :pick-up "pu" 183 * :put-down "pd" 184 * :current-health "hc" 185 * :max-health "hm" 186 * :current-armor "ac" 187 * :max-armor "am" 188 * :current-location "lc" 189 * :current-facing "fc" 190 * :can-see "cs" 191 * :radar "ra" 192 * :what-is "wi" 193 * :current-ammo "mc" 194 * :range-finder "rf" 195 * :check-inventory "ci" 196 * :follow "fo" 197 * :batch-range-finder "rb" 198 * :pop "po" 199 * :pause "pa" 200 * :forget-all-tasks "fa" 201 * :skip "sk" 202 * :peek "pk" 203 * :now "n" 204 * :then "t" 205 * :replace "r" 206 171 * :move-indefinitely --> "mi" 172 * :move-for --> "mf" 173 * :move-by --> "mb" 174 * :move-to --> "mt" 175 * :jump-once --> "ju" 176 * :rotate --> "ro" 177 * :fire-weapon --> "fw" 178 * :switch-weapon --> "sw" 179 * :set-crouch --> "sc" 180 * :shove --> "sv" 181 * :say --> "sy" 182 * :pick-up --> "pu" 183 * :put-down --> "pd" 184 * :current-health --> "hc" 185 * :max-health --> "hm" 186 * :current-armor --> "ac" 187 * :max-armor --> "am" 188 * :current-location --> "lc" 189 * :current-facing --> "fc" 190 * :can-see --> "cs" 191 * :radar --> "ra" 192 * :what-is --> "wi" 193 * :current-ammo --> "mc" 194 * :range-finder --> "rf" 195 * :check-inventory --> "ci" 196 * :follow --> "fo" 197 * :batch-range-finder --> "rb" 198 * :pop --> "po" 199 * :pause --> "pa" 200 * :forget-all-tasks --> "fa" 201 * :skip --> "sk" 202 * :peek --> "pk" 203 * :now --> "n" 204 * :then --> "t" 205 * :replace --> "r" 206 207 The client interacts with the server via four functions, each of which has a unique way of processing the return data. (If you are unsure which to use, try "send-and-get", as it is by far the most common.) 208 209 210 If you don't need the reply data 207 211 {{{ 208 212 client.core=> (doc send-and-forget) … … 216 220 nil 217 221 }}} 222 223 If you want to get the data synchronously 218 224 219 225 {{{ … … 228 234 The args to the op should be in a vector. 229 235 nil 230 231 }}} 236 }}} 237 238 If you want to get the data asynchronously 232 239 233 240 {{{ … … 243 250 should be in a vector. 244 251 nil 245 246 }}} 252 }}} 253 254 If you want to dispatch on data individually 247 255 248 256 {{{ … … 259 267 zero codes. The args to the op should be in a vector. 260 268 nil 261 262 }}} 263 264 Notice that the room has a few items scattered around it, let's define a function "scan-area" that takes two arguments (a quagent key and a radius) and returns a hash map of the positions of the items. Before trying to write the full function it is a good idea just to print out what the server is returning. 269 }}} 270 271 Notice that the room has a few items scattered around it; in order to find out where these are relative to the quagent, we need to define a function "scan-area" that takes two arguments (a quagent key and a radius) and returns a hash map of the positions of the items. Before trying to write the full function it is a good idea just to print out what the server is returning. 265 272 266 273 {{{ … … 301 308 client.core=> (send-and-get :Bob :radar :now [8000] 302 309 {} 303 (fn [prev [_ item-type & pos]] 310 (fn [prev [_ item-type & pos]] ; data is destructured 304 311 (assoc prev item-type pos))) 305 312 {"quagent_item_gold" ("905.141357" "8.130102" "0.569713")... (output truncated) … … 312 319 }}} 313 320 314 This is progress but the data from the new replies is over riding the previous results. To get the right behaviour, the "merge-with" function must be used to combine the maps.321 This is progress but the data from the new replies is overwriting the previous results. To get the right behaviour, the "merge-with" function must be used to combine the maps. 315 322 316 323 {{{ … … 347 354 {item-type (list (map #(Double/parseDouble %) 348 355 pos))}))) 349 {"quagent_item_gold" ((375.085327 56.309933 1.374918) (1019.278626 42.455196 0.505915)... (output-truncated)356 {"quagent_item_gold" ((375.085327 56.309933 1.374918) ... (output-truncated) 350 357 client.core=> (pp) 351 358 {"quagent_item_gold" … … 387 394 }}} 388 395 389 You can now use the predefined "move" command to make the quagent walk to an item. 390 391 {{{ 392 client.core=> (apply (partial move :Bob) (take 2 (second (get (scan-area :Bob 8000) "quagent_item_gold")))) 396 You can now use the predefined "move" command to make the quagent walk to the second gold item (note that these positions are relative, not absolute). 397 398 {{{ 399 client.core=> (apply (partial move :Bob) 400 (take 2 (second ((scan-area :Bob 8000) "quagent_item_gold")))) 393 401 [] 394 402 }}} … … 401 409 {} 402 410 (fn [prev [_ item-type & pos]] 403 (merge-with concat prev {item-type (list (seq->doubles pos))})))) 411 (merge-with concat 412 prev 413 {item-type (list (seq->doubles pos))})))) 404 414 #'client.core/scan-area2 405 415 client.core=> (def items (scan-area2 :Bob 8000)) … … 410 420 true 411 421 client.core=> @items 412 {"quagent_item_gold" ([375.085327 56.309933 1.374918] [1019.278626 42.455196 0.505915]... (output truncated)422 {"quagent_item_gold" ([375.085327 56.309933 1.374918] ... (output truncated) 413 423 client.core=> (pp) 414 424 {"quagent_item_gold" … … 434 444 (fn [prev data] 435 445 (rest data)) 436 (fn [k r o n] 446 (fn [k r o n] ; short for "key", "reference", "old", and "new" 437 447 (println "Item:" (first n) "Distance:" (second n))))) 438 448 #'client.core/scan-area3 … … 490 500 491 501 === Scheduling Functions === 492 see [https://github.com/overtone/at-at]493 502 494 503 === Logic Programming === 495 * core.logic tutorial [https://github.com/clojure/core.logic] and [https://github.com/frenchy64/Logic-Starter/wiki]496 * The Reasoned Schemer, by Daniel P. Friedman, William E. Byrd and Oleg Kiselyov.497 504 498 505 ----