Skip to content

Instantly share code, notes, and snippets.

@Arnauld
Created March 4, 2016 07:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Arnauld/4a347d0a45231e442cf2 to your computer and use it in GitHub Desktop.
Save Arnauld/4a347d0a45231e442cf2 to your computer and use it in GitHub Desktop.
Coders strike back
(ns Player
(:gen-class)
(:import (java.io StringReader)
(clojure.lang LineNumberingPushbackReader)))
;---------------------------------------------------------------
; _ _ _ _ _ _
; _ _| |_(_) (_) |_(_) ___ ___
; _____| | | | __| | | | __| |/ _ \/ __|
; |_____| |_| | |_| | | | |_| | __/\__ \
; \__,_|\__|_|_|_|\__|_|\___||___/
;---------------------------------------------------------------
(defn debug [& str]
(binding [*out* *err*]
(println str)))
(defn as-stream [s]
(-> (StringReader. s) LineNumberingPushbackReader.))
(def RAD_TO_DEG (/ 180 Math/PI))
(def TWO_PI (+ Math/PI Math/PI))
(defn rad-to-deg [angle]
(* angle RAD_TO_DEG))
(defn deg-to-rad [angle]
(/ angle RAD_TO_DEG))
(defn angle [dx dy]
(let [r (Math/atan2 dy dx)]
(if (neg? r)
(+ r TWO_PI)
r)))
(defn length [dx dy]
(Math/sqrt (+ (* dx dx) (* dy dy))))
;---------------------------------------------------------------
; _
; (_) ___
; _____| |/ _ \
; |_____| | (_) |
; |_|\___/
;---------------------------------------------------------------
(defn init-game [stream]
(let [laps (read stream)
checkpointCount (read stream)
checkpoints (loop [i 0
points {}]
(if (< i checkpointCount)
(let [checkpointX (read stream)
checkpointY (read stream)]
(recur (inc i)
(assoc points i {:x checkpointX
:y checkpointY})))
points))]
{:laps laps
:checkpointCount checkpointCount
:checkpoints checkpoints}))
(defn read-pod-status [stream]
{:x (read stream)
:y (read stream)
:vx (read stream)
:vy (read stream)
:angle (read stream)
:nextCheckPointId (read stream)})
(defn print-pod-action [acpod]
(println (:dstx acpod) (:dsty acpod) (:thrust acpod)))
;---------------------------------------------------------------
; _
; __ _ __ _ _ __ ___ ___ | | ___ ___ _ __
; _____ / _` |/ _` | '_ ` _ \ / _ \ | |/ _ \ / _ \| '_ \
; |_____| (_| | (_| | | | | | | __/ | | (_) | (_) | |_) |
; \__, |\__,_|_| |_| |_|\___| |_|\___/ \___/| .__/
; |___/ |_|
;---------------------------------------------------------------
(def podRadius 400)
(def podRadius2 (* 2 podRadius))
(def podRadius2_5 (* 2.5 podRadius))
(def podRadius3 (* 3 podRadius))
;
; straight case & rotating case
; N.B.: deltaAngle (in degree) should be clamped to fit [-18, 18]
;
; v(t + 1) = 0.85 * (v(t) + thrust * u_thetha)
;
(defn next-pos
([pod thrust]
(next-pos pod thrust 0))
([pod thrust deltaAngle]
(let [x (:x pod)
y (:y pod)
vx (:vx pod)
vy (:vy pod)
nangle (+ (:angle pod) deltaAngle)
angle (deg-to-rad nangle)
;
; P2 = P1 + V + thrust * u(pod_angle + delta)
;
nvx (+ vx (* (Math/cos angle) thrust))
nvy (+ vy (* (Math/sin angle) thrust))
nx (+ x nvx)
ny (+ y nvy)
scaled_vx (* 0.85 nvx)
scaled_vy (* 0.85 nvy)]
{:x (int nx)
:y (int ny)
:vx (int scaled_vx)
:vy (int scaled_vy)
:v (length scaled_vx scaled_vy)
:angle (int nangle)
:speed_angle (rad-to-deg (Player/angle nvx nvy))})))
(defn angle-speed [pod]
(angle (:vx pod) (:vy pod)))
(defn distance [pod target]
(let [dx (- (:x pod) (:x target))
dy (- (:y pod) (:y target))]
(Math/sqrt (+ (* dx dx) (* dy dy)))))
(defn angle-to-target [pod target]
(let [dx (- (:x target) (:x pod))
dy (- (:y target) (:y pod))]
(angle dx dy)))
(defn get-next-checkpoint [game pod]
(get-in game [:checkpoints (:nextCheckPointId pod)]))
(defn speed [pod]
(length (:vx pod) (:vy pod)))
(defn get-next-next-checkpoint [game pod]
(let [nbCheckPoint (:checkpointCount game)
nb (:nextCheckPointId pod)
next (inc nb)
id (if (< next nbCheckPoint) next 0)]
(get-in game [:checkpoints id])))
(defn let-me-think [game n mypod otherpod avpod1 avpod2]
(case n
;
; -- target the checkpoint
;
1 (let [dstCheckoint (get-next-checkpoint game mypod)
podSpeed (speed mypod)
distanceToCheckpoint (distance mypod dstCheckoint)
thrust (cond (< podSpeed 100) 150
(< distanceToCheckpoint (* 2 podSpeed)) 0
:else 200)
angleToTarget (rad-to-deg (angle-to-target mypod dstCheckoint))
angleSpeed (angle-speed mypod)
anglePod (:angle mypod)
deltaAngle (- anglePod angleToTarget)
;; ---
n2CheckPoint (get-next-next-checkpoint game mypod)
angleToN2Checkpoint (rad-to-deg (angle-to-target mypod n2CheckPoint))
nbRoundToRotateToFaceN2Point (int (/ (- anglePod angleToN2Checkpoint) 18))
[dstx dsty angleToTarget adjustedThrust] (if
;
; make sure one is still moving...
;
(and (< 50 podSpeed)
(< distanceToCheckpoint (* 4 podSpeed))
(< (distance mypod avpod1) podRadius3)
(< (distance mypod avpod2) podRadius3))
;
; attempt a free rotation while still moving towards the goal
;
(let [dstx (:x n2CheckPoint)
dsty (:y n2CheckPoint)
angleToTarget (rad-to-deg angleToN2Checkpoint)]
(debug "Free rides...")
[dstx dsty angleToTarget 0])
;
; target the checkpoint with
; higher correction to compensate actual inertie
;
(let [dstx (- (:x dstCheckoint) (* 2 (:vx mypod)))
dsty (- (:y dstCheckoint) (* 2 (:vy mypod)))
angleToTarget (rad-to-deg (angle-to-target mypod {:x dstx :y dsty}))
thrustAngleFactor (if (= -1 anglePod)
1
(max 0.1 (- 1 (Math/abs (float (/ deltaAngle 180))))))]
(debug "thrustAngleFactor" thrustAngleFactor)
[dstx dsty angleToTarget (int (* thrustAngleFactor thrust))]))]
(debug "distance" distanceToCheckpoint)
(debug "podSpeed" podSpeed)
(debug "angle pod........ " anglePod)
(debug "angle to target.. " angleToTarget)
(debug "angle speed...... " angleSpeed)
(debug "deltaAngle" deltaAngle)
(debug "angleToTarget" angleToTarget)
(debug "nextPos" (next-pos mypod thrust angleToTarget))
{:dstx dstx
:dsty dsty
:thrust adjustedThrust})
;
; --- kick the closest other
;
2 (let [distance1 (distance mypod avpod1)
distance2 (distance mypod avpod2)
target (if (< distance1 distance2)
avpod1
avpod2)]
{:dstx (:x target)
:dsty (:y target)
:thrust 150})))
(defn -main [& args]
(let [game (init-game *in*)]
(debug game)
(while true
(let [mypod1 (read-pod-status *in*)
mypod2 (read-pod-status *in*)
avpod1 (read-pod-status *in*)
avpod2 (read-pod-status *in*)
acpod1 (let-me-think game 1 mypod1 mypod2 avpod1 avpod2)
acpod2 (let-me-think game 2 mypod2 mypod1 avpod1 avpod2)]
(debug mypod1)
(debug mypod2)
(debug avpod1)
(debug avpod2)
(debug "dst1" acpod1)
(debug "dst2" acpod2)
; Write action to stdout
(print-pod-action acpod1)
(print-pod-action acpod2)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment