Skip to content

Instantly share code, notes, and snippets.

@torgeir
Last active June 26, 2022 15:14
Show Gist options
  • Save torgeir/c0dd1fc4d7dbcd8306cb938bc3b4e619 to your computer and use it in GitHub Desktop.
Save torgeir/c0dd1fc4d7dbcd8306cb938bc3b4e619 to your computer and use it in GitHub Desktop.
Codingame: Snake AI, random safe moves
import java.util.*
import java.lang.Integer.parseInt
typealias Coord = Pair<Int, Int>
fun Coord.x() = first
fun Coord.y() = second
typealias Move = Pair<Direction, Coord>
enum class Direction {
N, S, W, E
}
fun coords(s: String) =
s.split(",")
.chunked(2)
.map { (x, y) -> Coord(parseInt(x), parseInt(y)) }
fun moveCoord(coord: Coord, dir: Direction) =
when (dir) {
Direction.N -> Coord(coord.x(), coord.y() - 1)
Direction.E -> Coord(coord.x() + 1, coord.y())
Direction.S -> Coord(coord.x(), coord.y() + 1)
else -> Coord(coord.x() - 1, coord.y())
}
fun main(args: Array<String>) {
val input = Scanner(System.`in`)
val width = input.nextInt()
val height = input.nextInt()
val playercount = input.nextInt()
val foodcount = input.nextInt()
val myid = input.nextInt()
// game loop
while (true) {
var others = mutableListOf<Coord>();
var me = listOf<Coord>()
fun debug(any: Any) = System.err.println(any)
val aliveplayers = input.nextInt()
for (i in 0 until aliveplayers) {
val id = input.nextInt()
val score = input.nextInt()
val size = input.nextInt()
val snake = input.next()
if (id == myid) {
me = coords(snake)
debug(
"""
aliveplayers:
id: $id
score: $score
size: $size
snake: $snake
""".trimIndent()
)
} else {
others.addAll(coords(snake))
}
}
val foods = mutableListOf<Coord>()
for (i in 0 until foodcount) {
val x = input.nextInt()
val y = input.nextInt()
foods.plus(Coord(x, y))
//debug("food @ $x,$y")
}
fun isIllegalMove(c: Coord) =
me.plus(others).contains(c)
|| c.x() >= width
|| c.y() >= height
|| c.x() < 0
|| c.y() < 0
fun randMove(c: Coord) =
Direction
.values()
.random()
.let { Move(it, moveCoord(c, it)) }
me.first()
.let { pos -> generateSequence { randMove(pos) } }
.dropWhile { move -> isIllegalMove(move.second) }
.map { it.first }
.first()
.also(::println)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment