diff clojure/com/aurellem/items.clj @ 99:9fad96094950

can now read and set the inventory of a state
author Robert McIntyre <rlm@mit.edu>
date Mon, 12 Mar 2012 09:59:26 -0500
parents 08cd8be1edc1
children 2090bcb78f44
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/items.clj	Mon Mar 12 00:31:10 2012 -0500
     1.2 +++ b/clojure/com/aurellem/items.clj	Mon Mar 12 09:59:26 2012 -0500
     1.3 @@ -1,403 +1,215 @@
     1.4  (ns com.aurellem.items
     1.5    (:use (com.aurellem gb-driver vbm title))
     1.6 -  ;; this is fucking bullshit
     1.7 +  ;; this is bullshit
     1.8    (:import [com.aurellem.gb_driver SaveState]))
     1.9  
    1.10 -
    1.11 -
    1.12  (defn game-name []
    1.13    (map char (subvec (vec (memory)) 0x134 0x142)))
    1.14  
    1.15 +(def item-list-start 0xD31C)
    1.16  
    1.17 -
    1.18 -                    
    1.19 -
    1.20 -(defn current-items [^SaveState state]
    1.21 -  (set-state! state)
    1.22 -  
    1.23 -
    1.24 -  )
    1.25 -
    1.26 -
    1.27 -
    1.28 -;; try just buying five potions in sequence and see what changes
    1.29 -;; each time.
    1.30 -
    1.31 -(defn common-differences [& seqs]
    1.32 -  (let [backbone (range (count (first seqs)))]
    1.33 -    (filter
    1.34 -     (comp (partial apply distinct?) second)
    1.35 -     (zipmap backbone
    1.36 -             (apply (partial map list) seqs)))))
    1.37 -
    1.38 -;; trying to find how items are represented in memory
    1.39 -
    1.40 -(comment
    1.41 -  (def empty-inventory @current-state)
    1.42 -  
    1.43 -  (def one-potion @current-state)
    1.44 -  
    1.45 -  (def two-potions @current-state)
    1.46 -  
    1.47 -  (def three-potions @current-state)
    1.48 -  
    1.49 -  (def four-potions @current-state)
    1.50 -  
    1.51 -  (def five-potions @current-state)
    1.52 -  
    1.53 -  
    1.54 -  ;; result
    1.55 -  (def canidates
    1.56 -    (apply common-differences
    1.57 -           (map (comp vec memory)
    1.58 -                [empty-inventory one-potion two-potions three-potions
    1.59 -                 four-potions five-potions])))
    1.60 -
    1.61 -  [55875 (37 15 49 27 14 44)]
    1.62 -  [55876 (30 1 49 56 55 23)]
    1.63 -  [49158 (154 191 78 135 70 73)]
    1.64 -  [54087 (49 40 37 34 25 22)]
    1.65 -  [49160 (7 24 59 243 50 217)]
    1.66 -  [49704 (31 14 72 33 84 27)]
    1.67 -  [49162 (126 159 183 110 176 179)]
    1.68 -  [39984 (0 254 251 248 127 252)]
    1.69 -  [49904 (29 72 64 78 1 95)]
    1.70 -  [65491 (222 127 149 132 226 38)]
    1.71 -  [65492 (44 20 89 11 253 163)]
    1.72 -  [49335 (52 15 6 14 3 17)]
    1.73 -  [49720 (78 152 96 60 83 103)]
    1.74 -  [65304 (19 89 214 33 18 113)]
    1.75 -  [53561 (132 185 145 162 159 183)]
    1.76 -  [54046 (0 1 2 3 4 5)])
    1.77 -
    1.78 -;;; hmmmmmm...... I guess that the potion quantities are at 54046,
    1.79 -;;;huh?
    1.80 -
    1.81 -
    1.82 -
    1.83 -(def item-hack (read-state 7999))
    1.84 -
    1.85 -(def item-hack2 (read-state 75882))
    1.86 -
    1.87 -(defn get-mem []
    1.88 -  (subvec (vec (memory @current-state)) 54040 (+ 54046 100)))
    1.89 -
    1.90 -
    1.91 -;; potion -- 99
    1.92 -[0 16 0 0 1 20 99 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 117 129 139 148 132 80 134 128 145 152 80 137 3 0 0 1 191 223 189 2 0 42 8 199 5 2 1 0 1 20 2 4 4 93 77 23 77 122 76 0 255 208 65 240 198 10 10 71 246 41 201 255 252 64 18 201 10 10]
    1.93 -
    1.94 -;; potion -- 95
    1.95 -[0 16 0 0 1 20 95 255 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 49 117 129 139 148 132 80 134 128 145 152 80 137 3 0 0 1 191 223 189 2 0 42 8 199 5 2 1 0 1 20 2 4 4 93 77 23 77 122 76 0 255 208 65 240 198 10 10 71 246 41 201 255 252 64 18 201 10 10]
    1.96 -
    1.97 -;; potion -- 95
    1.98 -;; pokeball -- 1
    1.99 -[0 16 0 0 2 20 95 4 1 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 41 117 129 139 148 132 80 134 128 145 152 80 137 3 0 0 1 191 223 189 2 0 42 8 199 5 2 1 0 1 20 2 4 4 93 77 23 77 122 76 0 255 208 65 240 198 10 10 71 246 41 201 255 252 64 18 201 10 10]
   1.100 -
   1.101 -;; potion -- 95
   1.102 -;; pokeball -- 10
   1.103 -[0 16 0 0 2 20 95 4 10 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 117 129 139 148 132 80 134 128 145 152 80 137 3 0 0 1 191 223 189 2 0 42 8 199 5 2 1 0 1 20 2 4 4 93 77 23 77 122 76 0 255 208 65 240 198 10 10 71 246 41 201 255 252 64 18 201 10 10]
   1.104 -
   1.105 -
   1.106 -;; pokeball -- 10
   1.107 -;; potion -- 95
   1.108 -[0 16 0 0 2 4 10 20 95 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 117 129 139 148 132 80 134 128 145 152 80 137 3 0 0 1 191 223 189 2 0 42 8 199 5 2 1 0 1 20 2 4 4 93 77 23 77 122 76 0 255 208 65 240 198 10 10 71 246 41 201 255 252 64 18 201 10 10]
   1.109 -
   1.110 -;; pokeball -- 10
   1.111 -;; potion -- 95
   1.112 -;; antidote -- 1
   1.113 -
   1.114 -;;prediction
   1.115 -;;[0 16 0 0 3 4 10 20 95 ?? 1 255 0 0 0 0 0 ....]
   1.116 -  [0 16 0 0 3 4 10 20 95 11 1 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 117 129 139 148 132 80 134 128 145 152 80 137 3 0 0 1 191 223 189 2 0 42 8 199 5 2 1 0 1 20 2 4 4 93 77 23 77 122 76 0 255 208 65 240 198 10 10 71 246 41 201 255 252 64 18 201 10 10]
   1.117 -
   1.118 -
   1.119 -
   1.120 -;; now it's time to learn the item codes
   1.121 +(defn item-list [^SaveState state]
   1.122 +  (subvec
   1.123 +   (vec (memory state))
   1.124 +   item-list-start
   1.125 +   (+ item-list-start 60)))
   1.126  
   1.127  (def item-hack-3 (read-state 77557))
   1.128 -(defn show-item
   1.129 -  "Run a saved pokemon with the first item replaced by the item named
   1.130 -   by n."
   1.131 -  [n]
   1.132 -  (set-state! item-hack-3)
   1.133 -  (let [mem (memory)]
   1.134 -    (aset mem 54045 n)
   1.135 -    (write-memory! mem))
   1.136 -  (step)
   1.137 -  (->> [[] @current-state]
   1.138 -       (play-moves
   1.139 -        [[:a] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
   1.140 -         [] [] [] [] []])))
   1.141  
   1.142 +(def item-code->item-name
   1.143 +  (hash-map
   1.144 +   1     :master-ball
   1.145 +   2     :ultra-ball
   1.146 +   3     :great-ball
   1.147 +   4     :poke-ball
   1.148 +   5     :town-map
   1.149 +   6     :bicycle
   1.150 +   8     :safari-ball
   1.151 +   9     :pokedex
   1.152 +   10    :moon-stone 
   1.153 +   11    :antidote
   1.154 +   12    :burn-heal
   1.155 +   13    :ice-heal
   1.156 +   14    :awakening
   1.157 +   15    :parlyz-heal
   1.158 +   16    :full-restore
   1.159 +   17    :max-potion
   1.160 +   18    :hyper-potion
   1.161 +   19    :super-potion
   1.162 +   20    :potion
   1.163 +   21    :boulderbadge
   1.164 +   22    :cascadebadge
   1.165 +   23    :thunderbadge
   1.166 +   24    :rainbowbadge
   1.167 +   25    :soulbadge
   1.168 +   26    :marshbadge
   1.169 +   27    :volcanobadge
   1.170 +   28    :earthbadge
   1.171 +   29    :escape-rope
   1.172 +   30    :repel
   1.173 +   31    :old-amber
   1.174 +   32    :fire-stone
   1.175 +   33    :thunderstone
   1.176 +   34    :water-stone
   1.177 +   35    :hp-up
   1.178 +   36    :protein
   1.179 +   37    :iron
   1.180 +   38    :carbos
   1.181 +   39    :calcium
   1.182 +   40    :rare-candy
   1.183 +   41    :dome-fossil
   1.184 +   42    :helix-fossil
   1.185 +   43    :secret-key
   1.186 +   45    :bike-voucher
   1.187 +   46    :x-accuracy
   1.188 +   47    :leaf-stone
   1.189 +   48    :card-key
   1.190 +   49    :nugget
   1.191 +   50    :pp-up
   1.192 +   51    :poke-doll
   1.193 +   52    :full-heal
   1.194 +   53    :revive
   1.195 +   54    :max-revive
   1.196 +   55    :guard-spec
   1.197 +   56    :super-repel
   1.198 +   57    :max-repel
   1.199 +   58    :dire-hit
   1.200 +   59    :coin
   1.201 +   60    :fresh-water
   1.202 +   61    :soda-pop
   1.203 +   62    :lemonade
   1.204 +   63    :s.s.ticket
   1.205 +   64    :gold-teeth
   1.206 +   65    :x-attach
   1.207 +   66    :x-defend
   1.208 +   67    :x-speed
   1.209 +   68    :x-special
   1.210 +   69    :coin-case
   1.211 +   70    :oaks-parcel
   1.212 +   71    :itemfinder
   1.213 +   72    :silph-scope
   1.214 +   73    :poke-flute
   1.215 +   74    :lift-key
   1.216 +   75    :exp.all
   1.217 +   76    :old-rod
   1.218 +   77    :good-rod
   1.219 +   78    :super-rod
   1.220 +   79    :pp-up
   1.221 +   80    :ether
   1.222 +   81    :max-ether
   1.223 +   82    :elixer
   1.224 +   83    :max-elixer
   1.225 +   196   :HM01
   1.226 +   197   :HM02
   1.227 +   198   :HM03
   1.228 +   199   :HM04
   1.229 +   200   :HM05
   1.230 +   201   :TM01
   1.231 +   202   :TM02
   1.232 +   203   :TM03
   1.233 +   204   :TM04
   1.234 +   205   :TM05
   1.235 +   206   :TM06
   1.236 +   207   :TM07
   1.237 +   208   :TM08
   1.238 +   209   :TM09
   1.239 +   210   :TM10
   1.240 +   211   :TM11
   1.241 +   212   :TM12
   1.242 +   213   :TM13
   1.243 +   214   :TM13
   1.244 +   215   :TM15
   1.245 +   216   :TM16
   1.246 +   217   :TM17
   1.247 +   218   :TM18
   1.248 +   219   :TM19
   1.249 +   220   :TM20
   1.250 +   221   :TM21
   1.251 +   222   :TM22
   1.252 +   223   :TM23
   1.253 +   224   :TM24
   1.254 +   225   :TM25
   1.255 +   226   :TM26
   1.256 +   227   :TM27
   1.257 +   228   :TM28
   1.258 +   229   :TM29
   1.259 +   230   :TM30
   1.260 +   231   :TM31
   1.261 +   232   :TM32
   1.262 +   233   :TM33
   1.263 +   234   :TM34
   1.264 +   235   :TM35
   1.265 +   236   :TM36
   1.266 +   237   :TM37
   1.267 +   238   :TM38
   1.268 +   239   :TM39
   1.269 +   240   :TM40
   1.270 +   241   :TM41
   1.271 +   242   :TM42
   1.272 +   243   :TM43
   1.273 +   244   :TM44
   1.274 +   245   :TM45
   1.275 +   246   :TM46
   1.276 +   247   :TM47
   1.277 +   248   :TM48
   1.278 +   249   :TM49
   1.279 +   250   :TM50
   1.280 +   251   :TM51
   1.281 +   252   :TM52
   1.282 +   253   :TM53
   1.283 +   254   :TM54
   1.284 +   255   :end-of-list-sentinel))
   1.285  
   1.286 -(defn get-item-names []
   1.287 -  (dorun (map (fn [n] (println n)
   1.288 -                (show-item n)
   1.289 -                (Thread/sleep 5000))
   1.290 -              (range 0x00 0xFF))))
   1.291 +(def item-name->item-code
   1.292 +  (zipmap (vals item-code->item-name)
   1.293 +          (keys item-code->item-name)))
   1.294  
   1.295 +(defn inventory [^SaveState state]
   1.296 +  (let [items (item-list state)]
   1.297 +    (map
   1.298 +     (fn [[item-code quantity]]
   1.299 +          [(item-code->item-name item-code)
   1.300 +           quantity])
   1.301 +     (partition
   1.302 +      2
   1.303 +      (next (take-while (partial not= 255) items))))))
   1.304  
   1.305 +(defn print-inventory [^SaveState state]
   1.306 +  (println
   1.307 +   (let [inv (inventory state)]
   1.308 +     (reduce
   1.309 +      str
   1.310 +      (concat
   1.311 +       ["+-------------------+----------+\n"
   1.312 +        "|##| Item           | Quantity |\n"
   1.313 +        "+--+----------------+----------+\n"]
   1.314  
   1.315 -;; 0   garbage
   1.316 -;; 1   master-ball
   1.317 -;; 2   ultra-ball
   1.318 -;; 3   great-ball
   1.319 -;; 4   poke-ball
   1.320 -;; 5   town-map
   1.321 -;; 6   bicycle
   1.322 -;; 7   ?????
   1.323 -;; 8   safari-ball
   1.324 -;; 9   pokedex
   1.325 -;; 10  moon-stone 
   1.326 -;; 11   antidote
   1.327 -;; 12   burn-heal
   1.328 -;; 13   ice-heal
   1.329 -;; 14   awakening
   1.330 -;; 15   parlyz-heal
   1.331 -;; 16   full-restore
   1.332 -;; 17   max-potion
   1.333 -;; 18   hyper-potion
   1.334 -;; 19   super-potion
   1.335 -;; 20   potion
   1.336 -;; 21   boulderbadge
   1.337 -;; 22   cascadebadge
   1.338 -;; 23   thunderbadge
   1.339 -;; 24   rainbowbadge
   1.340 -;; 25   soulbadge
   1.341 -;; 26   marshbadge
   1.342 -;; 27   volcanobadge
   1.343 -;; 28   earthbadge
   1.344 -;; 29   escape-rope
   1.345 -;; 30   repel
   1.346 -;; 31   old amber
   1.347 -;; 32   fire-stone
   1.348 -;; 33   thunderstone
   1.349 -;; 34   water-stone
   1.350 -;; 35   hp-up
   1.351 -;; 36   protein
   1.352 -;; 37   iron
   1.353 -;; 38   carbos
   1.354 -;; 39   calcium
   1.355 -;; 40   rare-candy
   1.356 -;; 41   dome-fossil
   1.357 -;; 42   helix-fossil
   1.358 -;; 43   secret-key
   1.359 -;; 44   ?????
   1.360 -;; 45   bike-voucher
   1.361 -;; 46   x-accuracy
   1.362 -;; 47   leaf-stone
   1.363 -;; 48   card-key
   1.364 -;; 49   nugget
   1.365 -;; 50   pp-up
   1.366 -;; 51   poke-doll
   1.367 -;; 52   full-heal
   1.368 -;; 53   revive
   1.369 -;; 54   max-revive
   1.370 -;; 55   guard-spec.
   1.371 -;; 56   super-repel
   1.372 -;; 57   max-repel
   1.373 -;; 58   dire-hit
   1.374 -;; 59   coin
   1.375 -;; 60   fresh-water
   1.376 -;; 61   soda-pop
   1.377 -;; 62   lemonade
   1.378 -;; 63   s.s.ticket
   1.379 -;; 64   gold-teeth
   1.380 -;; 65   x-attach
   1.381 -;; 66   x-defend
   1.382 -;; 67   x-speed
   1.383 -;; 68   x-special
   1.384 -;; 69   coin-case
   1.385 -;; 70   oak's-parcel
   1.386 -;; 71   itemfinder
   1.387 -;; 72   silph-scope
   1.388 -;; 73   poke-flute
   1.389 -;; 74   lift-key
   1.390 -;; 75   exp.all
   1.391 -;; 76   old-rod
   1.392 -;; 77   good-rod
   1.393 -;; 78   super-rod
   1.394 -;; 79   pp-up
   1.395 -;; 80   ether
   1.396 -;; 81   max-ether
   1.397 -;; 82   elixer
   1.398 -;; 83   max-elixer
   1.399 -;; 84   B2F
   1.400 -;; 85   B1F
   1.401 -;; 86   1F
   1.402 -;; 87   2F
   1.403 -;; 88   3F
   1.404 -;; 89   4F
   1.405 -;; 90   5F
   1.406 -;; 91   6F
   1.407 -;; 92   7F
   1.408 -;; 93   8F
   1.409 -;; 94   9F
   1.410 -;; 95   10F
   1.411 -;; 96   11F
   1.412 -;; 97   B4F
   1.413 -;; 98   garbage
   1.414 -;; 99   garbage
   1.415 -;; 100   garbage
   1.416 -;; 101   garbage
   1.417 -;; 102   garbage
   1.418 -;; 103   garbage
   1.419 -;; 104   garbage
   1.420 -;; 105   garbage
   1.421 -;; 106   garbage
   1.422 -;; 107   garbage
   1.423 -;; 108   garbage
   1.424 -;; 109   garbage
   1.425 -;; 110   garbage
   1.426 -;; 111   garbage
   1.427 -;; 112   garbage
   1.428 -;; 113   garbage
   1.429 -;; 114   garbage
   1.430 -;; 115   garbage
   1.431 -;; 116   garbage
   1.432 -;; 117   garbage
   1.433 -;; 118   garbage
   1.434 -;; 119   4
   1.435 -;; 120   garbage
   1.436 -;; 121   garbage
   1.437 -;; 122   slow
   1.438 -;; 123   garbage
   1.439 -;; 124   garbage
   1.440 -;; 125   garbage
   1.441 -;; 126   garbage
   1.442 -;; 127   garbage
   1.443 -;; 128   garbage
   1.444 -;; 129   garbage
   1.445 -;; 130   garbage
   1.446 -;; 131   slow
   1.447 -;; 132   slow
   1.448 -;; 133   garbage
   1.449 -;; 134   slow
   1.450 -;; 135   garbage
   1.451 -;; 136   garbage
   1.452 -;; 137   slow
   1.453 -;; 138   garbage
   1.454 -;; 139   garbage
   1.455 -;; 140   garbage
   1.456 -;; 141   slow
   1.457 -;; 142   garbage
   1.458 -;; 143   garbage
   1.459 -;; 144   garbage
   1.460 -;; 145   garbage
   1.461 -;; 146   garbage
   1.462 -;; 147   garbage
   1.463 -;; 148   garbage
   1.464 -;; 149   garbage
   1.465 -;; 150   slow
   1.466 -;; 151   garbage
   1.467 -;; 152   Q
   1.468 -;; 153   garbage
   1.469 -;; 154   garbage
   1.470 -;; 155   garbage
   1.471 -;; 156   garbage
   1.472 -;; 157   garbage
   1.473 -;; 158   garbage
   1.474 -;; 159   garbage
   1.475 -;; 160   garbage (alaphabet)
   1.476 -;; 161   garbage
   1.477 -;; 162   garbage
   1.478 -;; 163   garbage
   1.479 -;; 164   rival's
   1.480 -;; 165   name?
   1.481 -;; 166   nickname?
   1.482 -;; 167   slow
   1.483 -;; 168   garbage
   1.484 -;; 169   slow
   1.485 -;; 170   garbage
   1.486 -;; 171   garbage
   1.487 -;; 172   garbage
   1.488 -;; 173   garbage
   1.489 -;; 174   garbage
   1.490 -;; 175   yellow
   1.491 -;; 176   ash
   1.492 -;; 177   jack
   1.493 -;; 178   new-name
   1.494 -;; 179   blue
   1.495 -;; 180   gary
   1.496 -;; 181   john
   1.497 -;; 182   garbage
   1.498 -;; 183   garbage
   1.499 -;; 184   garbage
   1.500 -;; 185   garbage
   1.501 -;; 186   slow
   1.502 -;; 187   garbage
   1.503 -;; 188   garbage
   1.504 -;; 189   garbage
   1.505 -;; 190   garbage
   1.506 -;; 191   garbage
   1.507 -;; 192   garbage
   1.508 -;; 193   garbage
   1.509 -;; 194   garbage
   1.510 -;; 195   slow
   1.511 -;; 196   HM01
   1.512 -;; 197   HM02
   1.513 -;; 198   HM03
   1.514 -;; 199   HM04
   1.515 -;; 200   HM05
   1.516 -;; 201   TM01
   1.517 -;; 202   TM02
   1.518 -;; 203   TM03
   1.519 -;; 204   TM04
   1.520 -;; 205   TM05
   1.521 -;; 206   TM06
   1.522 -;; 207   TM07
   1.523 -;; 208   TM08
   1.524 -;; 209   TM09
   1.525 -;; 210   TM10
   1.526 -;; 211   TM11
   1.527 -;; 212   TM12
   1.528 -;; 213   TM13
   1.529 -;; 214   TM13
   1.530 -;; 215   TM15
   1.531 -;; 216   TM16
   1.532 -;; 217   TM17
   1.533 -;; 218   TM18
   1.534 -;; 219   TM19
   1.535 -;; 220   TM20
   1.536 -;; 221   TM21
   1.537 -;; 222   TM22
   1.538 -;; 223   TM23
   1.539 -;; 224   TM24
   1.540 -;; 225   TM25
   1.541 -;; 226   TM26
   1.542 -;; 227   TM27
   1.543 -;; 228   TM28
   1.544 -;; 229   TM29
   1.545 -;; 230   TM30
   1.546 -;; 231   TM31
   1.547 -;; 232   TM32
   1.548 -;; 233   TM33
   1.549 -;; 234   TM34
   1.550 -;; 235   TM35
   1.551 -;; 236   TM36
   1.552 -;; 237   TM37
   1.553 -;; 238   TM38
   1.554 -;; 239   TM39
   1.555 -;; 240   TM40
   1.556 -;; 241   TM41
   1.557 -;; 242   TM42
   1.558 -;; 243   TM43
   1.559 -;; 244   TM44
   1.560 -;; 245   TM45
   1.561 -;; 246   TM46
   1.562 -;; 247   TM47
   1.563 -;; 248   TM48
   1.564 -;; 249   TM49
   1.565 -;; 250   TM50
   1.566 -;; 251   TM51
   1.567 -;; 252   TM52
   1.568 -;; 253   TM53
   1.569 -;; 254   TM54
   1.570 -;; 255   end-of-list-sentinel   
   1.571 +       (map
   1.572 +        (fn [index [item-name quantity]]
   1.573 +         (str 
   1.574 +          (format "|%-2d| %-14s | %3d      |\n" index
   1.575 +                  (apply str (rest (str item-name)))
   1.576 +                  quantity)))
   1.577 +        (range 0 (count inv)) inv)
   1.578 +       ["+--+----------------+----------+\n"])))))
   1.579  
   1.580 -
   1.581 +(defn inventory-codes [inventory]
   1.582 +  (flatten
   1.583 +   (concat [(count inventory)]
   1.584 +           (map (fn [[item-name quantity]]
   1.585 +                  [(item-name->item-code item-name)
   1.586 +                   quantity]) inventory)
   1.587 +           [(item-name->item-code :end-of-list-sentinel)])))
   1.588    
   1.589 -
   1.590 +(defn set-inventory [^SaveState state new-inventory]
   1.591 +  (set-state! state)
   1.592 +  (let [mem (memory state)
   1.593 +        inv (inventory-codes new-inventory)]
   1.594    
   1.595 +    (dorun (map (fn [index val]
   1.596 +                  (aset mem index val))
   1.597 +                (range item-list-start
   1.598 +                       (+ item-list-start (count inv))) inv))
   1.599 +    (write-memory! mem)
   1.600 +    (update-state)))
   1.601    
   1.602 -