Mercurial > vba-clojure
view clojure/com/aurellem/run/util.clj @ 314:073600cba28a
scroll text works robustly but is slow
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 02 Apr 2012 20:30:02 -0500 |
parents | 8e63b0bb8ea3 |
children | d263df762c59 |
line wrap: on
line source
1 (ns com.aurellem.run.util2 (:use (com.aurellem.gb util gb-driver vbm characters saves))3 (:import [com.aurellem.gb.gb_driver SaveState]))5 (def ↑ [:u])6 (def ↓ [:d])7 (def ← [:l])8 (def → [:r])10 (defn first-difference11 [base alt difference-metric [moves root :as script]]12 (loop [branch-point root13 actions moves]14 (let [base-branch (step branch-point base)15 base-val (difference-metric base-branch)16 alt-branch (step branch-point alt)17 alt-val (difference-metric alt-branch)]18 (if (not= base-val alt-val)19 [(conj actions alt) alt-branch]20 (recur base-branch (conj actions base))))))22 (defn repeat-until-different23 [buttons metric [moves root :as script]]24 (let [baseline (metric root)]25 (loop [actions (vec moves)26 state root]27 (let [new-state (step state buttons)28 new-actions (conj actions buttons)]29 (if (not= (metric new-state) baseline)30 [new-actions new-state]31 (recur new-actions new-state))))))33 (defn delayed-difference34 [base alt delay difference-metric [moves root :as script]]35 (loop [branch-point root36 actions moves]37 (let [base-branch (step branch-point base)38 base-val39 (difference-metric40 (run-moves base-branch41 (repeat delay base)))42 alt-branch (step branch-point alt)43 alt-val44 (difference-metric45 (run-moves alt-branch46 (repeat delay base)))]47 (if (not= base-val alt-val)48 [(conj actions alt) alt-branch]49 (recur base-branch (conj actions base))))))53 ;; (defn advance54 ;; ([base alt difference-metric [commands state]]55 ;; (let [[c s]56 ;; (first-difference base alt difference-metric state)]57 ;; [(concat commands c) s]))58 ;; ([base alt [commands state]]59 ;; (advance base alt AF [commands state]))60 ;; ([alt [commands state]]61 ;; (advance [] alt [commands state])))64 (def x-position-address 0xD361)65 (def y-position-address 0xD362)67 (defn x-position68 ([^SaveState state]69 (aget (memory state) x-position-address))70 ([] (x-position @current-state)))72 (defn y-position73 ([^SaveState state]74 (aget (memory state) y-position-address))75 ([] (y-position @current-state)))77 (defn move78 [dir script]79 (let [current-position-fn80 (cond (#{← →} dir) x-position81 (#{↑ ↓} dir) y-position)]82 (repeat-until-different dir current-position-fn script)))84 (defn walk85 "Move the character along the given directions."86 [directions script]87 (reduce (fn [script dir]88 (move dir script)) script directions))90 (defn menu91 [directions script]92 (reduce (fn [script direction]93 (move direction script))94 script directions))97 (defn search-string98 [^SaveState state string]99 (let [codes100 (str->character-codes string)101 codes-length (count codes)102 mem (vec (memory state))103 mem-length (count mem)]104 (loop [idx 0]105 (if (< (- mem-length idx) codes-length)106 nil107 (if (= (subvec mem idx (+ idx codes-length))108 codes)109 idx110 (recur (inc idx)))))))112 (def text-address 0x9DC1)114 (defn displayed-text115 ([^SaveState state]116 (character-codes->str117 (subvec (vec (memory state))118 text-address119 (+ text-address 82))))120 ([] (displayed-text @current-state)))122 ;; (defn scroll-text123 ;; ([script]124 ;; (first-difference [:b] [:a :b] AF script))125 ;; ([n script]126 ;; (reduce (fn [script _]127 ;; (scroll-text script))128 ;; script129 ;; (range n))))131 (defn scroll-text132 ([script]133 (delayed-difference134 [:b] [:a :b] 25 displayed-text script))135 ([n script]136 (reduce (fn [script _]137 (scroll-text script))138 script139 (range n))))142 (defn end-text [script]143 (->> script144 (scroll-text)145 (play-moves [[] [:a]])))149 (common-differences150 (vec (memory (step (talk-to-oak) [:a])))151 (vec (memory (step (talk-to-oak) []))))157 (defn do-nothing [n script]158 (->> script159 (play-moves160 (repeat n []))))163 (defn critical-hit164 "Put the cursor over the desired attack. This program will165 determine the appropriate amount of blank frames to166 insert before pressing [:a] to ensure that the attack is167 a critical hit."168 [script]169 (loop [blanks 6]170 (let [new-script171 (->> script172 (play-moves173 (concat (repeat blanks [])174 [[:a][]])))]175 (if (let [future-state176 (run-moves (second new-script)177 (repeat 400 []))179 result (search-string (memory future-state)180 "Critical")]181 (if result182 (println "critical hit with" blanks "blank frames"))183 result)184 new-script185 (recur (inc blanks))))))187 (defn move-thru-grass188 [direction script]189 (loop [blanks 0]190 (let [new-script191 (->> script192 (play-moves (repeat blanks []))193 (move direction))195 future-state196 (run-moves (second new-script)197 (repeat 600 []))199 result (search-string (memory future-state)200 "Wild")]201 (if (nil? result)202 (do203 (if (< 0 blanks)204 (do205 (println "avoided pokemon with"206 blanks "blank frames")))207 new-script)208 (recur (inc blanks))))))210 (defn walk-thru-grass211 [directions script]212 (reduce (fn [script direction]213 (move-thru-grass direction script))214 script directions))216 (defn slowly217 [delay moves script]218 (reduce219 (fn [script move]220 (->> script221 (do-nothing delay)222 (play-moves (vector move))))223 script moves))225 (defn multiple-times226 ([n command args script]227 (reduce (fn [script _]228 (apply command (concat args [script])))229 script230 (range n)))231 ([n command script]232 (multiple-times n command [] script)))