Skip to content

Instantly share code, notes, and snippets.

@victoraldecoa
Last active December 29, 2024 19:03
Show Gist options
  • Save victoraldecoa/7fa12b7e969b43effa5696d492cf518e to your computer and use it in GitHub Desktop.
Save victoraldecoa/7fa12b7e969b43effa5696d492cf518e to your computer and use it in GitHub Desktop.
CodinGame Winter Challenge 2024
(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