X-Git-Url: http://git.jkinsey.net/?p=adventofcode2019.git;a=blobdiff_plain;f=src%2Fadventofcode2019%2Fday13.clj;fp=src%2Fadventofcode2019%2Fday13.clj;h=9dfe83dae5e7c2ec946d01109067b435c0393349;hp=759b3b3ad35e11387221529673f5cb3b4ae7a15c;hb=ab32e54381280135a0df771d293438c195259dc2;hpb=2557180a5d7e409937099b91a1e0524e4238978a diff --git a/src/adventofcode2019/day13.clj b/src/adventofcode2019/day13.clj index 759b3b3..9dfe83d 100644 --- a/src/adventofcode2019/day13.clj +++ b/src/adventofcode2019/day13.clj @@ -3,12 +3,75 @@ [adventofcode2019.intcode :as i] [clojure.string :as str] [clojure.core.match :refer [match]] - [clojure.math.combinatorics :as combo]]) + [clojure.math.combinatorics :as combo] + [lanterna.terminal :as ts]]) + +(def term (ts/get-terminal :text)) + +(defn find-bounds [tiles] + (let [x-list (map first (keys tiles)) + y-list (map second (keys tiles)) + min-x (reduce min x-list) + max-x (reduce max x-list) + min-y (reduce min y-list) + max-y (reduce max y-list)] + [[min-x max-x] [min-y max-y]])) + +(defn make-field [[dx dy]] + (let [line (vec (repeat dx \space))] + (mapv (constantly line) (range dy)))) + +(defn draw-tiles [tiles term] + (let [to-text #(case % + 0 \space + 1 \| + 2 \- + 3 \_ + 4 \O) + paint-tile (fn [[[x y] tile]] + (ts/move-cursor term x y) + (ts/put-character term (to-text tile)))] + (doall (map paint-tile tiles)))) + +(defn print-field [field score] + (run! (comp println str/join) field) + (println score) + (flush)) + +(defn run-game [game [[min-x max-x] [min-y max-y]]] + (let [wait-for-output #(= (count (:output %)) 3) + get-next-ic-output (partial i/intcode-until wait-for-output) + new-game (assoc game :input [0]) + field (ts/get-terminal :swing)] + (ts/start field) + (ts/put-character field \a) + (loop [program-state (get-next-ic-output new-game) + score 0 + framerate 0 + ctr 0] + (Thread/sleep framerate) + (if (:exit program-state) + (do (ts/stop field) + score) + (let [[x y t] (:output program-state) + [new-score new-screen] (if (and (= x -1) (= y 0)) + [t {}] + [score {[x y] t}]) + input (case (ts/get-key-blocking field {:interval 1 :timeout framerate}) + \a -1 + \d 1 + 0)] + (draw-tiles new-screen field) + (recur (get-next-ic-output (assoc program-state + :output [] + :input [input])) + new-score (if (> ctr 814) 100 0) (inc ctr))))))) (defn day13 [] (let [input (i/get-program (input-file)) output (:output (i/intcode (i/build-state input))) draw-tiles (fn [screen [x y t]] (assoc screen [x y] t)) - screen (reduce draw-tiles {} (partition 3 output))] - (part1 (count (filter #(= % 4) (vals screen)))) - #_(part2))) + screen (reduce draw-tiles {} (partition 3 output)) + game (assoc-in (i/build-state input {:step true}) [:memory 0] 2)] + (part1 (count (filter #(= % 2) (vals screen)))) + (part2 (run-game game (find-bounds screen)))))