Last active
December 29, 2024 19:03
-
-
Save victoraldecoa/7fa12b7e969b43effa5696d492cf518e to your computer and use it in GitHub Desktop.
CodinGame Winter Challenge 2024
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns Player | |
(:require [clojure.string :as str] | |
[clojure.set :as set]) | |
(:gen-class)) | |
; Grow and multiply your organisms to end up larger than your opponent. | |
(defn output [msg] (println msg) (flush)) | |
(defn debug [msg] (binding [*out* *err*] (println msg) (flush) msg)) | |
(def protein-types #{"A" "B" "C" "D"}) | |
(defn dist [{fx :x fy :y} {tx :x ty :y}] | |
(+ (abs (- ty fy)) (abs (- tx fx)))) | |
(defn get-direction | |
[{from-x :x from-y :y} {to-x :x to-y :y}] | |
(cond | |
(> to-x from-x) "E" | |
(< to-x from-x) "W" | |
(> to-y from-y) "S" | |
(< to-y from-y) "N")) | |
(defn adjacent-entities | |
[grid {:keys [x y]}] | |
(let [[rx ry :as right] [(inc x) y] | |
[dx dy :as down] [x (inc y)] | |
[lx ly :as left] [(dec x) y] | |
[ux uy :as up] [x (dec y)]] | |
[(or (grid right) {:x rx :y ry}) | |
(or (grid down) {:x dx :y dy}) | |
(or (grid left) {:x lx :y ly}) | |
(or (grid up) {:x ux :y uy})])) | |
(defn get-growth-type | |
[grid from to [_ myB myC myD] enemy-root] | |
(let [adjacent-protein (->> (adjacent-entities grid to) | |
(filter #(protein-types (:type %))) | |
first) | |
adjacent-enemies (->> (adjacent-entities grid to) | |
(filter #(= (:owner %) :enemy))) | |
adjacent-enemy (if (seq adjacent-enemies) | |
(apply min-key #(dist % enemy-root) adjacent-enemies) | |
nil)] | |
(cond | |
(and (pos? myB) (pos? myC) (some? adjacent-enemy)) | |
["TENTACLE" (get-direction to adjacent-enemy)] | |
(and (pos? myC) (pos? myD) (not (nil? adjacent-protein))) | |
["HARVESTER" (get-direction to adjacent-protein)] | |
:else ["BASIC"]))) | |
(defn is-obstacle? | |
[grid {:keys [x y]}] | |
(let [{:keys [type owner]} (grid [x y]) | |
obstacles (set/union protein-types #{"WALL"})] | |
(or (obstacles type) | |
(= owner :player)))) | |
(defn -main [& _args] | |
(let [; width: columns in the game grid | |
; height: rows in the game grid | |
[_width _height] (map #(Integer/parseInt %) (filter #(not-empty %) (str/split (read-line) #" ")))] | |
(loop [{spawned-x :x spawned-y :y} nil] | |
(let [entityCount (Integer/parseInt (read-line)) | |
entities | |
(->> (range entityCount) | |
(map (fn [_] | |
(let [; y: grid coordinate | |
; type: WALL, ROOT, BASIC, TENTACLE, HARVESTER, SPORER, A, B, C, D | |
; owner: 1 if your organ, 0 if enemy organ, -1 if neither | |
; organId: id of this entity if it's an organ, 0 otherwise | |
; organDir: N,E,S,W or X if not an organ | |
[x y type owner organId organDir organParentId organRootId] (filter #(not-empty %) (str/split (read-line) #" "))] | |
{:x (Integer/parseInt x) | |
:y (Integer/parseInt y) | |
:owner ({-1 :neither | |
0 :enemy | |
1 :player} (Integer/parseInt owner)) | |
:type type | |
:id (Integer/parseInt organId) | |
:organDir organDir | |
:organParentId (Integer/parseInt organParentId) | |
:organRootId (Integer/parseInt organRootId)}))) | |
(doall)) | |
[myA myB myC myD :as my-proteins] (map #(Integer/parseInt %) (filter #(not-empty %) (str/split (read-line) #" "))) | |
; oppD: opponent's protein stock | |
[oppA oppB oppC oppD] (map #(Integer/parseInt %) (filter #(not-empty %) (str/split (read-line) #" "))) | |
; your number of organisms, output an action for each one in any order | |
requiredActionsCount (Integer/parseInt (read-line)) | |
grid (into {} (map (fn [{:keys [x y] :as e}] [[x y] e]) entities)) | |
my-organs (filter #(= (% :owner) :player) entities) | |
enemy (filter #(= (% :owner) :enemy) entities) | |
root (first (filter #(= (% :type) "ROOT") my-organs)) | |
enemy-root (first (filter #(= (% :type) "ROOT") enemy)) | |
spawned-organ (or (grid [spawned-x spawned-y]) root) | |
adjacent (adjacent-entities grid spawned-organ) | |
available-to-grow (remove (partial is-obstacle? grid) adjacent) | |
{:keys [x y]} (apply min-key #(dist % enemy-root) available-to-grow) | |
rightmost-organ (->> my-organs (sort-by :y) reverse (sort-by :x) last) | |
{from :from | |
{growth-x :x | |
growth-y :y :as to} :to} {:from spawned-organ | |
:to {:x x | |
:y y}}] | |
; (dotimes [i requiredActionsCount] | |
; (debug "Debug messages...") | |
; Write action to stdout | |
(output | |
(str/join " " (concat ["GROW" (:id from) growth-x growth-y] (get-growth-type grid from to my-proteins enemy-root)))) | |
(recur to))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment