|
| 1 | +(ns halite3.mybot |
| 2 | + (:require [hlt.log :refer [log]] |
| 3 | + [hlt.random :refer [set-seed! rrand-int]] |
| 4 | + [hlt.input :refer [as-int]] |
| 5 | + [hlt.state :refer [constants]] |
| 6 | + [hlt.ship :as ship] |
| 7 | + [hlt.shipyard :as shipyard] |
| 8 | + [hlt.direction :as direction] |
| 9 | + [hlt.game-map :as game-map] |
| 10 | + [hlt.game :as game]) |
| 11 | + (:gen-class)) |
| 12 | + |
| 13 | +;; This Clojure API uses kebab-case instead of the snake_case as documented |
| 14 | +;; in the API docs. Otherwise the names of methods are analogous. |
| 15 | + |
| 16 | +(defn -main |
| 17 | + "MyBot in Clojure" |
| 18 | + [& args] |
| 19 | + ;; Initialize repeatable random number generator |
| 20 | + (set-seed! (if (seq args) (as-int (first args)) (System/nanoTime))) |
| 21 | + |
| 22 | + (game/new-game) ;; get initial map data |
| 23 | + |
| 24 | + ;; At this point the "game" atom is populated with the game state |
| 25 | + ;; This is a good place to do computationally expensive start-up pre-processing. |
| 26 | + ;; After calling ready below, the 2 second per turn timer will start. |
| 27 | + |
| 28 | + (game/ready "my-clojure-bot") |
| 29 | + |
| 30 | + ;; Now that your bot is initialized, save a message to yourself in |
| 31 | + ;; the log file with some important information. Here, you log here |
| 32 | + ;; your id, which you can always fetch from the game using my-id |
| 33 | + |
| 34 | + (log "Successfully created bot! My Player ID is " (game/my-id) ".") |
| 35 | + |
| 36 | + (while true |
| 37 | + ;; This loop handles each turn of the game. The game state |
| 38 | + ;; changes every turn, and you refresh that state by running update-frame |
| 39 | + (game/update-frame) |
| 40 | + |
| 41 | + ;; below is a naive example of handling a turn |
| 42 | + |
| 43 | + ;; For each of your ships, move randomly if the ship is on a low halite |
| 44 | + ;; location or the ship is full. Else, collect halite. |
| 45 | + (let [me (game/me) ;; option 1: get player, destructure by hand |
| 46 | + {:keys [shipyard halite ships dropoffs]} me] |
| 47 | + (doseq [[_ ship] ships] |
| 48 | + (let [{:keys [::ship/id position halite]} ship |
| 49 | + cell (game-map/at ship)] |
| 50 | + (log "Ship:" id "has" halite "halite.") |
| 51 | + (if (or (< (:halite cell) (/ (constants :MAX_HALITE) 10)) |
| 52 | + (ship/is-full? ship)) |
| 53 | + (game/command |
| 54 | + (ship/move ship |
| 55 | + (get (direction/get-all-cardinals) (rrand-int 4)))) |
| 56 | + (game/command (ship/stay-still ship)))))) |
| 57 | + |
| 58 | + ;; If the game is in the first 200 turns and you have enough |
| 59 | + ;; halite, spawn a ship. Don't spawn a ship if you currently have |
| 60 | + ;; a ship at port, though - the ships will collide. |
| 61 | + (when (and (< (game/turn-number) 200) |
| 62 | + (>= (game/me :halite) ;; option 2 destructure inline |
| 63 | + (constants :SHIP_COST)) |
| 64 | + (not (game-map/is-occupied? (game/me :shipyard)))) |
| 65 | + (log "Spawning a ship!") |
| 66 | + (game/command (shipyard/spawn))) |
| 67 | + |
| 68 | + ;; above is a naive example of handling a turn |
| 69 | + |
| 70 | + ;; Send your moves back to the game environment, ending this turn. |
| 71 | + (game/end-turn))) |
0 commit comments