Mercurial > vba-clojure
diff clojure/com/aurellem/run/util.clj @ 313:8e63b0bb8ea3
major refactoring; made (walk) more robust
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 02 Apr 2012 10:58:16 -0500 |
parents | |
children | 073600cba28a |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/clojure/com/aurellem/run/util.clj Mon Apr 02 10:58:16 2012 -0500 1.3 @@ -0,0 +1,184 @@ 1.4 +(ns com.aurellem.run.util 1.5 + (:use (com.aurellem.gb util gb-driver vbm characters)) 1.6 + (:import [com.aurellem.gb.gb_driver SaveState])) 1.7 + 1.8 +(def ↑ [:u]) 1.9 +(def ↓ [:d]) 1.10 +(def ← [:l]) 1.11 +(def → [:r]) 1.12 + 1.13 +(defn first-difference 1.14 + [base alt difference-metric [moves root :as script]] 1.15 + (loop [branch-point root 1.16 + actions moves] 1.17 + (let [base-branch (step branch-point base) 1.18 + base-val (difference-metric base-branch) 1.19 + alt-branch (step branch-point alt) 1.20 + alt-val (difference-metric alt-branch)] 1.21 + (if (not= base-val alt-val) 1.22 + [(conj actions alt) alt-branch] 1.23 + (recur base-branch (conj actions base)))))) 1.24 + 1.25 + 1.26 +(defn repeat-until-different 1.27 + [buttons metric [moves root]] 1.28 + (let [baseline (metric root)] 1.29 + (loop [actions (vec moves) 1.30 + state root] 1.31 + (let [new-state (step state buttons) 1.32 + new-actions (conj actions buttons)] 1.33 + (if (not= (metric new-state) baseline) 1.34 + [new-actions new-state] 1.35 + (recur new-actions new-state)))))) 1.36 + 1.37 + 1.38 + 1.39 +;; (defn advance 1.40 +;; ([base alt difference-metric [commands state]] 1.41 +;; (let [[c s] 1.42 +;; (first-difference base alt difference-metric state)] 1.43 +;; [(concat commands c) s])) 1.44 +;; ([base alt [commands state]] 1.45 +;; (advance base alt AF [commands state])) 1.46 +;; ([alt [commands state]] 1.47 +;; (advance [] alt [commands state]))) 1.48 + 1.49 + 1.50 +(def x-position-address 0xD361) 1.51 +(def y-position-address 0xD362) 1.52 + 1.53 +(defn x-position 1.54 + ([^SaveState state] 1.55 + (aget (memory state) x-position-address)) 1.56 + ([] (x-position @current-state))) 1.57 + 1.58 +(defn y-position 1.59 + ([^SaveState state] 1.60 + (aget (memory state) y-position-address)) 1.61 + ([] (y-position @current-state))) 1.62 + 1.63 +(defn move 1.64 + [dir script] 1.65 + (let [current-position-fn 1.66 + (cond (#{← →} dir) x-position 1.67 + (#{↑ ↓} dir) y-position)] 1.68 + (repeat-until-different dir current-position-fn script))) 1.69 + 1.70 +(defn walk 1.71 + "Move the character along the given directions." 1.72 + [directions script] 1.73 + (reduce (fn [script dir] 1.74 + (move dir script)) script directions)) 1.75 + 1.76 +(defn scroll-text 1.77 + ([script] 1.78 + (advance [:b] [:a :b] script)) 1.79 + ([n script] 1.80 + (reduce (fn [script _] 1.81 + (scroll-text script)) 1.82 + script 1.83 + (range n)))) 1.84 + 1.85 +(defn menu 1.86 + [directions script] 1.87 + (reduce (fn [script direction] 1.88 + (move direction script)) 1.89 + script directions)) 1.90 + 1.91 +(defn end-text [script] 1.92 + (->> script 1.93 + (scroll-text) 1.94 + (play-moves [[] [:a]]))) 1.95 + 1.96 +(defn search-string 1.97 + [array string] 1.98 + (let [codes 1.99 + (str->character-codes string) 1.100 + codes-length (count codes) 1.101 + mem (vec array) 1.102 + mem-length (count mem)] 1.103 + (loop [idx 0] 1.104 + (if (< (- mem-length idx) codes-length) 1.105 + nil 1.106 + (if (= (subvec mem idx (+ idx codes-length)) 1.107 + codes) 1.108 + idx 1.109 + (recur (inc idx))))))) 1.110 + 1.111 + 1.112 +(defn do-nothing [n script] 1.113 + (->> script 1.114 + (play-moves 1.115 + (repeat n [])))) 1.116 + 1.117 + 1.118 +(defn critical-hit 1.119 + "Put the cursor over the desired attack. This program will 1.120 + determine the appropriate amount of blank frames to 1.121 + insert before pressing [:a] to ensure that the attack is 1.122 + a critical hit." 1.123 + [script] 1.124 + (loop [blanks 6] 1.125 + (let [new-script 1.126 + (->> script 1.127 + (play-moves 1.128 + (concat (repeat blanks []) 1.129 + [[:a][]])))] 1.130 + (if (let [future-state 1.131 + (run-moves (second new-script) 1.132 + (repeat 400 [])) 1.133 + 1.134 + result (search-string (memory future-state) 1.135 + "Critical")] 1.136 + (if result 1.137 + (println "critical hit with" blanks "blank frames")) 1.138 + result) 1.139 + new-script 1.140 + (recur (inc blanks)))))) 1.141 + 1.142 +(defn move-thru-grass 1.143 + [direction script] 1.144 + (loop [blanks 0] 1.145 + (let [new-script 1.146 + (->> script 1.147 + (play-moves (repeat blanks [])) 1.148 + (move direction)) 1.149 + 1.150 + future-state 1.151 + (run-moves (second new-script) 1.152 + (repeat 600 [])) 1.153 + 1.154 + result (search-string (memory future-state) 1.155 + "Wild")] 1.156 + (if (nil? result) 1.157 + (do 1.158 + (if (< 0 blanks) 1.159 + (do 1.160 + (println "avoided pokemon with" 1.161 + blanks "blank frames"))) 1.162 + new-script) 1.163 + (recur (inc blanks)))))) 1.164 + 1.165 +(defn walk-thru-grass 1.166 + [directions script] 1.167 + (reduce (fn [script direction] 1.168 + (move-thru-grass direction script)) 1.169 + script directions)) 1.170 + 1.171 +(defn slowly 1.172 + [delay moves script] 1.173 + (reduce 1.174 + (fn [script move] 1.175 + (->> script 1.176 + (do-nothing delay) 1.177 + (play-moves (vector move)))) 1.178 + script moves)) 1.179 + 1.180 +(defn multiple-times 1.181 + ([n command args script] 1.182 + (reduce (fn [script _] 1.183 + (apply command (concat args [script]))) 1.184 + script 1.185 + (range n))) 1.186 + ([n command script] 1.187 + (multiple-times n command [] script)))