Created
March 4, 2016 07:33
-
-
Save Arnauld/4a347d0a45231e442cf2 to your computer and use it in GitHub Desktop.
Coders strike back
This file contains 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 | |
(: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