Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import kotlin.math.*
import java.util.*
data class Coord(val x: Int, val y: Int) {
constructor(input: Scanner) : this(input.nextInt(), input.nextInt())
operator fun plus(other: Coord): Coord {
return Coord(x + other.x, y + other.y)
}
operator fun minus(other: Coord): Coord {
return Coord(x - other.x, y - other.y)
}
// Manhattan distance (for 4 directions maps)
// see: https://en.wikipedia.org/wiki/Taxicab_geometry
fun distance(other: Coord): Int {
return abs(x - other.x) + abs(y - other.y)
}
override fun toString(): String {
return "$x $y"
}
}
class Cell(val ore: Int?, val hole: Boolean) {
constructor(input: Scanner) : this(input.next().toIntOrNull(), input.next() != "0")
}
sealed class Action {
object None : Action() {
override fun toString(): String = "WAIT"
}
class Move(val pos: Coord) : Action() {
override fun toString(): String = "MOVE $pos"
}
class Dig(val pos: Coord) : Action() {
override fun toString(): String = "DIG $pos"
}
class Request(val item: EntityType) : Action() {
override fun toString(): String = "REQUEST $item"
}
}
enum class EntityType {
NOTHING, ALLY_ROBOT, ENEMY_ROBOT, RADAR, TRAP, AMADEUSIUM;
companion object {
fun valueOf(id: Int): EntityType {
return values()[id + 1]
}
}
}
class Entity(// Updated every turn
val id: Int,
val type: EntityType, val pos: Coord, val item: EntityType) {
constructor(input: Scanner) : this(
id = input.nextInt(),
type = EntityType.valueOf(input.nextInt()),
pos = Coord(input),
item = EntityType.valueOf(input.nextInt())
)
// Computed for my robots
var action: Action = Action.None
var message: String? = null
val isAlive: Boolean
get() = DEAD_POS != pos
fun printAction() {
if (message == null) println(action)
else println("$action $message")
}
companion object {
private val DEAD_POS = Coord(-1, -1)
}
}
class Team {
var score: Int = 0
val robots: MutableCollection<Entity> = mutableListOf()
fun readScore(input: Scanner) {
score = input.nextInt()
robots.clear()
}
}
class Board(// Given at startup
val width: Int, val height: Int,// Updated each turn
val myTeam: Team, val opponentTeam: Team) {
constructor(input: Scanner) : this(
width = input.nextInt(),
height = input.nextInt(),
myTeam = Team(),
opponentTeam = Team()
)
private val cells: Array<Array<Cell?>> = Array(height) { arrayOfNulls<Cell>(width) }
var myRadarCooldown: Int = 0
var myTrapCooldown: Int = 0
val entitiesById: MutableMap<Int, Entity> = mutableMapOf()
val myRadarPos: MutableCollection<Coord> = mutableSetOf()
val myTrapPos: MutableCollection<Coord> = mutableSetOf()
fun update(input: Scanner) {
// Read new data
myTeam.readScore(input)
opponentTeam.readScore(input)
for (y in 0 until height) {
for (x in 0 until width) {
cells[y][x] = Cell(input)
}
}
val entityCount = input.nextInt()
myRadarCooldown = input.nextInt()
myTrapCooldown = input.nextInt()
myRadarPos.clear()
myTrapPos.clear()
repeat(entityCount) {
val entity = Entity(input)
entitiesById[entity.id] = entity
when {
entity.type == EntityType.ALLY_ROBOT -> myTeam.robots.add(entity)
entity.type == EntityType.ENEMY_ROBOT -> opponentTeam.robots.add(entity)
entity.type == EntityType.RADAR -> myRadarPos.add(entity.pos)
entity.type == EntityType.TRAP -> myTrapPos.add(entity.pos)
}
}
}
fun cellExist(pos: Coord): Boolean {
return pos.x in 0 until width &&
pos.y in 0 until height
}
fun getCell(pos: Coord): Cell {
return cells[pos.y][pos.x]!!
}
}
class Player {
private val input = Scanner(System.`in`)
fun run() {
// Parse initial conditions
val board = Board(input)
while (true) {
// Parse current state of the game
board.update(input)
// Insert your strategy here
for (robot in board.myTeam.robots) {
robot.action = Action.None
robot.message = "Kotlin Starter AI"
}
// Send your actions for this turn
for (robot in board.myTeam.robots) {
robot.printAction()
}
}
}
}
fun main() {
Player().run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment