Mercurial > vba-clojure
comparison clojure/com/aurellem/run/bootstrap_0.clj @ 345:3b3cd62b6106
script: made it to cereulean with TM55s worth 2 million.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 08 Apr 2012 20:58:14 -0500 |
parents | 9366539d29b6 |
children | 08f8284e2f1b |
comparison
equal
deleted
inserted
replaced
344:9366539d29b6 | 345:3b3cd62b6106 |
---|---|
395 | 395 |
396 (defn set-quantity | 396 (defn set-quantity |
397 "Set the quantity of an item to buy or sell to the desired value | 397 "Set the quantity of an item to buy or sell to the desired value |
398 using the fewest possible button presses." | 398 using the fewest possible button presses." |
399 ([total-quantity desired-quantity [moves state :as script]] | 399 ([total-quantity desired-quantity [moves state :as script]] |
400 (let [current-quantity (item-quantity-selected state) | 400 (cond (= desired-quantity 1) (do (println "1 of 1") script) |
401 loop-point (if (> total-quantity 99) 0xFF 99) | 401 (= total-quantity desired-quantity) |
402 distance (- desired-quantity current-quantity) | 402 (do (println "get everything!") |
403 loop-distance (int(* -1 (Math/signum (float distance)) | 403 (delayed-difference [] ↓ 5 item-quantity-selected |
404 (- loop-point (Math/abs distance)))) | 404 script)) |
405 best-path (first (sort-by #(Math/abs %) | 405 true |
406 [distance loop-distance])) | 406 (let [current-quantity (item-quantity-selected state) |
407 direction (if (< 0 best-path) ↑ ↓)] | 407 loop-point (if (= 0 total-quantity) 0x100 total-quantity) |
408 (println "best-path" best-path) | 408 distance (- desired-quantity current-quantity) |
409 (reduce | 409 loop-distance (int(* -1 (Math/signum (float distance)) |
410 (fn [script _] | 410 (- loop-point (Math/abs distance)))) |
411 (delayed-difference [] direction 5 item-quantity-selected | 411 best-path (first (sort-by #(Math/abs %) |
412 script)) | 412 [distance loop-distance])) |
413 | 413 direction (if (< 0 best-path) ↑ ↓)] |
414 script | 414 (println "best-path" best-path) |
415 (range (Math/abs best-path))))) | 415 (println "current-quantity" current-quantity) |
416 (println "desired-quantity" desired-quantity) | |
417 (println "options" [distance loop-distance]) | |
418 (reduce | |
419 (fn [script _] | |
420 (delayed-difference [] direction 5 item-quantity-selected | |
421 script)) | |
422 script | |
423 (range (Math/abs best-path)))))) | |
416 ([desired-quantity [moves state :as script]] | 424 ([desired-quantity [moves state :as script]] |
417 (set-quantity 99 desired-quantity script))) | 425 (set-quantity 99 desired-quantity script))) |
418 | 426 |
419 (defn activate-start-menu [script] | 427 (defn activate-start-menu [script] |
420 (first-difference [:b] [:b :start] AF script)) | 428 (first-difference [:b] [:b :start] AF script)) |
424 (- (dec (count (first (script-fn script)))) | 432 (- (dec (count (first (script-fn script)))) |
425 (count (first script)))] | 433 (count (first script)))] |
426 (println "wait-time" wait-time) | 434 (println "wait-time" wait-time) |
427 (do-nothing wait-time script))) | 435 (do-nothing wait-time script))) |
428 | 436 |
429 (defn select-menu-entry [script] | 437 (defn select-menu-entry |
430 (->> script | 438 ([test-direction [moves state :as script]] |
431 (wait-until (partial set-cursor-relative 1)) | 439 (->> script |
432 (play-moves [[:a] []]))) | 440 (wait-until (partial set-cursor-relative test-direction)) |
433 | 441 (play-moves [[] [:a] []]))) |
442 ([[moves state :as script]] | |
443 (select-menu-entry | |
444 1 script))) | |
445 | |
434 (defn restart | 446 (defn restart |
435 "The two button presses after a restart event are converted to | 447 "The two button presses after a restart event are converted to |
436 blanks. Due to weirdness with the VBM format. To compensate, ensure | 448 blanks. Due to weirdness with the VBM format. To compensate, ensure |
437 that the two button presses after restart are both blanks." | 449 that the two button presses after restart are both blanks." |
438 [script] | 450 [script] |
439 (play-moves [[:restart] [] []] script)) | 451 (play-moves [[:restart] [] []] script)) |
440 | 452 |
441 (defn-memo do-save-corruption | 453 (defn-memo do-save-corruption |
442 ([] (do-save-corruption | 454 ([] (do-save-corruption |
443 (walk-to-counter))) | 455 (walk-to-counter))) |
444 ([script] | 456 ([script] (do-save-corruption 4 script)) |
457 ([n script] | |
445 (->> script | 458 (->> script |
446 activate-start-menu | 459 activate-start-menu |
447 (set-cursor 4) | 460 (set-cursor n) |
448 select-menu-entry | 461 select-menu-entry |
449 select-menu-entry | 462 select-menu-entry |
450 (play-moves | 463 (play-moves |
451 ;; this section is copied from speedrun-2942 and corrupts | 464 ;; this section is copied from speedrun-2942 and corrupts |
452 ;; the save so that the total number of pokemon is set to | 465 ;; the save so that the total number of pokemon is set to |
468 [(read-moves "cor-checkpoint") | 481 [(read-moves "cor-checkpoint") |
469 (read-state "cor-checkpoint")]) | 482 (read-state "cor-checkpoint")]) |
470 | 483 |
471 (def menu do-nothing ) | 484 (def menu do-nothing ) |
472 | 485 |
486 | |
487 (defn investivate-close-menu [] | |
488 (clojure.pprint/pprint | |
489 (apply harmonic-compare | |
490 (map read-state | |
491 ["start-up-1" | |
492 "start-down-1" | |
493 ;;"start-up-2" | |
494 ;;"start-down-2" | |
495 ;;"start-up-3" | |
496 ;;"start-down-3" | |
497 ;;"computer-up-1" | |
498 ;;"computer-down-2" | |
499 "computer-up-2" | |
500 "computer-down-2" | |
501 "pokemon-up-1" | |
502 "pokemon-down-1" | |
503 "pokemon-up-2" | |
504 "pokemon-down-2" | |
505 "item-up-1" | |
506 "item-down-1" | |
507 "save-up-1" | |
508 "save-down-1" | |
509 "item-nest-up-1" | |
510 "item-nest-down-1"])))) | |
511 | |
512 (def list-nesting-depth-address 50339) | |
513 | |
514 (defn current-depth | |
515 ([^SaveState state] (aget (memory state) list-nesting-depth-address)) | |
516 ([] (current-depth @current-state))) | |
517 | |
518 | |
473 (defn close-menu [script] | 519 (defn close-menu [script] |
474 (first-difference [] [:b] AF script)) | 520 (delayed-difference |
521 [] [:b] 50 | |
522 current-depth | |
523 script)) | |
524 | |
475 | 525 |
476 (defn purchase-item | 526 (defn purchase-item |
477 "Assumes that the cursor is over the desired item, and purchases | 527 "Assumes that the cursor is over the desired item, and purchases |
478 quantity of that item." | 528 quantity of that item." |
479 [n script] | 529 [n script] |
490 into out-of-bounds memory." | 540 into out-of-bounds memory." |
491 ([] (corrupt-item-list | 541 ([] (corrupt-item-list |
492 ;;(corrupted-checkpoint) | 542 ;;(corrupted-checkpoint) |
493 (do-save-corruption) | 543 (do-save-corruption) |
494 )) | 544 )) |
495 ([script] | 545 ([script] (corrupt-item-list 1)) |
546 ([n script] | |
496 (->> script | 547 (->> script |
497 activate-start-menu | 548 activate-start-menu |
498 (set-cursor 1) ; select "POKEMON" from | 549 (set-cursor n) ; select "POKEMON" |
499 select-menu-entry ; from main menu. | 550 select-menu-entry ; from main menu. |
500 (set-cursor 5) ; select 6th pokemon | 551 (set-cursor 5) ; select 6th pokemon |
501 select-menu-entry | 552 select-menu-entry |
502 (set-cursor 1) | 553 (set-cursor 1) |
503 select-menu-entry | 554 select-menu-entry |
1040 (run-moves (reduce concat | 1091 (run-moves (reduce concat |
1041 (repeat 10 [[:a :b :start :select] []]))) | 1092 (repeat 10 [[:a :b :start :select] []]))) |
1042 ((fn [_] (println "===========") _)) | 1093 ((fn [_] (println "===========") _)) |
1043 (print-listing 0xD162 (+ 0xD162 20))))) | 1094 (print-listing 0xD162 (+ 0xD162 20))))) |
1044 | 1095 |
1045 (defn pc-item-writer-program | |
1046 [] | |
1047 (let [limit 201 | |
1048 [target-high target-low] (disect-bytes-2 0xD162)] | |
1049 (flatten | |
1050 [[0x00 ;; (item-hack) set increment stack pointer no-op | |
1051 0x1E ;; load limit into E | |
1052 limit | |
1053 0x3F ;; (item-hack) set carry flag no-op | |
1054 | |
1055 ;; load 2 into C. | |
1056 0x0E ;; C == 1 means input-first nybble | |
1057 0x04 ;; C == 0 means input-second nybble | |
1058 | |
1059 0x21 ;; load target into HL | |
1060 target-low | |
1061 target-high | |
1062 0x37 ;; (item-hack) set carry flag no-op | |
1063 | |
1064 0x00 ;; (item-hack) no-op | |
1065 0x37 ;; (item-hack) set carry flag no-op | |
1066 | |
1067 0x00 ;; (item-hack) no-op | |
1068 0xF3 ;; disable interrupts | |
1069 ;; Input Section | |
1070 | |
1071 0x3E ;; load 0x20 into A, to measure buttons | |
1072 0x10 | |
1073 | |
1074 0x00 ;; (item-hack) no-op | |
1075 0xE0 ;; load A into [FF00] | |
1076 0x00 | |
1077 | |
1078 0xF0 ;; load 0xFF00 into A to get | |
1079 0x00 ;; button presses | |
1080 | |
1081 0xE6 | |
1082 0x0F ;; select bottom four bits of A | |
1083 0x37 ;; (item-hack) set carry flag no-op | |
1084 | |
1085 0x00 ;; (item-hack) no-op | |
1086 0xB8 ;; see if input is different (CP A B) | |
1087 | |
1088 0x00 ;; (item-hack) (INC SP) | |
1089 0x28 ;; repeat above steps if input is not different | |
1090 ;; (jump relative backwards if B != A) | |
1091 0xED ;; (literal -19) (item-hack) -19 == egg bomb (TM37) | |
1092 | |
1093 0x47 ;; load A into B | |
1094 | |
1095 0x0D ;; dec C | |
1096 0x37 ;; (item-hack) set-carry flag | |
1097 ;; branch based on C: | |
1098 0x20 ;; JR NZ | |
1099 23 ;; skip "input second nybble" and "jump to target" below | |
1100 | |
1101 ;; input second nybble | |
1102 | |
1103 0x0C ;; inc C | |
1104 0x0C ;; inc C | |
1105 | |
1106 0x00 ;; (item-hack) no-op | |
1107 0xE6 ;; select bottom bits | |
1108 0x0F | |
1109 0x37 ;; (item-hack) set-carry flag no-op | |
1110 | |
1111 0x00 ;; (item-hack) no-op | |
1112 0xB2 ;; (OR A D) -> A | |
1113 | |
1114 0x22 ;; (do (A -> (HL)) (INC HL)) | |
1115 | |
1116 0x1D ;; (DEC E) | |
1117 | |
1118 0x00 ;; (item-hack) | |
1119 0x20 ;; jump back to input section if not done | |
1120 0xDA ;; literal -36 == TM 18 (counter) | |
1121 0x01 ;; (item-hack) set BC to literal (no-op) | |
1122 | |
1123 ;; jump to target | |
1124 0x00 ;; (item-hack) these two bytes can be anything. | |
1125 0x01 | |
1126 | |
1127 0x00 ;; (item-hack) no-op | |
1128 0xBF ;; (CP A A) ensures Z | |
1129 | |
1130 0xCA ;; (item-hack) jump if Z | |
1131 target-low | |
1132 target-high | |
1133 0x01 ;; (item-hack) will never be reached. | |
1134 | |
1135 ;; input first nybble | |
1136 0x00 | |
1137 0xCB | |
1138 0x37 ;; swap nybbles on A | |
1139 | |
1140 0x57 ;; A -> D | |
1141 | |
1142 0x37 ;; (item-hack) set carry flag no-op | |
1143 0x18 ;; relative jump backwards | |
1144 0xCD ;; literal -51 == TM05; go back to input section | |
1145 0x01 ;; (item-hack) will never reach this instruction | |
1146 | |
1147 ] | |
1148 (repeat 8 [0xFF 0x01]) | |
1149 | |
1150 [;; jump to actual program | |
1151 0x00 | |
1152 0x37 ;; (item-hack) set carry flag no-op | |
1153 | |
1154 0x2E ;; 0x3A -> L | |
1155 0x3A | |
1156 | |
1157 | |
1158 0x00 ;; (item-hack) no-op | |
1159 0x26 ;; 0xD5 -> L | |
1160 0xD5 | |
1161 0x01 ;; (item-hack) set-carry BC | |
1162 | |
1163 0x00 ;; (item-hack) these can be anything | |
1164 0x00 | |
1165 | |
1166 ;; 0x00 | |
1167 ;; 0x44 ;; H -> B | |
1168 | |
1169 ;; 0x00 | |
1170 ;; 0x7D ;; L -> A | |
1171 | |
1172 ;; 0x00 | |
1173 ;; 0x7C ;; A -> H | |
1174 | |
1175 ;; 0x00 | |
1176 ;; 0x68 ;; B -> L | |
1177 | |
1178 0x00 | |
1179 0xE9 ;; jump to (HL) | |
1180 ]]))) | |
1181 | |
1182 | |
1183 (defn test-pc-item-writer [] | |
1184 (-> (read-state "bootstrap-init") | |
1185 (set-memory pc-item-list-start 50) | |
1186 (set-memory-range | |
1187 map-function-address-start | |
1188 [0x8B 0xD5]) | |
1189 (set-memory-range | |
1190 (inc pc-item-list-start) | |
1191 (pc-item-writer-program)))) | |
1192 | |
1193 (defn test-pc-item-writer-2 [] | |
1194 (let [orig (read-state "pc-item-writer")] | |
1195 (-> orig | |
1196 (print-listing 0xD162 (+ 0xD162 20)) | |
1197 (run-moves (reduce concat | |
1198 (repeat 10 [[:a :b :start :select] []]))) | |
1199 ((fn [_] (println "===========") _)) | |
1200 (print-listing 0xD162 (+ 0xD162 20))))) |