Changes between Version 67 and Version 68 of Clojure Client Tutorial


Ignore:
Timestamp:
Aug 22, 2011 12:44:17 PM (13 years ago)
Author:
kedwar10
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Clojure Client Tutorial

    v67 v68  
    121121
    122122{{{
    123 client.core=> (run-ioquake "sat")                                                                                                     
     123client.core=> (run-ioquake "sat")
    124124#<UNIXProcess java.lang.UNIXProcess@56c3cf>
    125125}}}
     
    169169Now 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).
    170170
    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
     207The 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
     210If you don't need the reply data
    207211{{{
    208212client.core=> (doc send-and-forget)
     
    216220nil
    217221}}}
     222
     223If you want to get the data synchronously
    218224
    219225{{{
     
    228234  The args to the op should be in a vector.
    229235nil
    230 
    231 }}}
     236}}}
     237
     238If you want to get the data asynchronously
    232239
    233240{{{
     
    243250  should be in a vector.
    244251nil
    245 
    246 }}}
     252}}}
     253
     254If you want to dispatch on data individually
    247255
    248256{{{
     
    259267  zero codes. The args to the op should be in a vector.
    260268nil
    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
     271Notice 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.
    265272
    266273{{{
     
    301308client.core=> (send-and-get :Bob :radar :now [8000]
    302309                            {}
    303                             (fn [prev [_ item-type & pos]]
     310                            (fn [prev [_ item-type & pos]] ; data is destructured
    304311                              (assoc prev item-type pos)))
    305312{"quagent_item_gold" ("905.141357" "8.130102" "0.569713")... (output truncated)
     
    312319}}}
    313320
    314 This is progress but the data from the new replies is overriding the previous results. To get the right behaviour, the "merge-with" function must be used to combine the maps.
     321This 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.
    315322
    316323{{{
     
    347354                                          {item-type (list (map #(Double/parseDouble %)
    348355                                                                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)
    350357client.core=> (pp)
    351358{"quagent_item_gold"
     
    387394}}}
    388395
    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"))))
     396You 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{{{
     399client.core=> (apply (partial move :Bob)
     400                     (take 2 (second ((scan-area :Bob 8000) "quagent_item_gold"))))
    393401[]
    394402}}}
     
    401409                                    {}
    402410                                    (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))}))))
    404414#'client.core/scan-area2
    405415client.core=> (def items (scan-area2 :Bob 8000))
     
    410420true
    411421client.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)
    413423client.core=> (pp)
    414424{"quagent_item_gold"
     
    434444                                (fn [prev data]
    435445                                 (rest data))
    436                                 (fn [k r o n]
     446                                (fn [k r o n] ; short for "key", "reference", "old", and "new"
    437447                                 (println "Item:" (first n) "Distance:" (second n)))))
    438448#'client.core/scan-area3
     
    490500
    491501=== Scheduling Functions ===
    492 see [https://github.com/overtone/at-at]
    493502
    494503=== 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.
    497504
    498505----