Skip to content

Instantly share code, notes, and snippets.

@DariusL
Created March 21, 2014 07:54
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 DariusL/9681569 to your computer and use it in GitHub Desktop.
Save DariusL/9681569 to your computer and use it in GitHub Desktop.
class ControlFunctionFactory {
def create = new ControlFunction().respond _
}
object Main {
def main(args: Array[String]) {
println(new ControlFunctionFactory().create("React(generation=0,time=100,view=_________________bWWW____WWW___bWWW_____PW____WWW,energy=100)"))
}
}
class ControlFunction {
def respond(input: String): String = {
val (opcode, params) = Parser(input)
opcode match {
case "React" => new Bot(params).react
case _ => "" // OK
}
}
}
class Bot(params: Map[String, String]) {
val dir = new ViewParser(params("view")).best
def react = "Move(direction=" + dir + ")"
}
object Parser {
def apply(command: String): (String, Map[String, String]) = {
val segments = command.split('(')
val params = segments(1).dropRight(1).split(',')
(segments(0), params.map(splitParam).toMap)
}
private def splitParam(param: String) = {
val segments = param.split('=')
(segments(0), if (segments.length > 1) segments(1) else "")
}
}
case class Vec(x: Int, y: Int) {
override def toString = x + ":" + y
def +(other: Vec) = Vec(x + other.x, y + other.y)
def -(other: Vec) = Vec(x - other.x, y - other.y)
def incX() = Vec(x + 1, y)
def dist = x.abs.max(y.abs)
}
object Vec {
def fromString(input: String) = {
val coords = input.split(':')
Vec(input(0).toInt, input(1).toInt)
}
var dirs = Array(
Vec(1, 0),
Vec(1, 1),
Vec(0, 1),
Vec(-1, 1),
Vec(-1, 0),
Vec(-1, -1),
Vec(0, -1),
Vec(1, -1))
}
class Cell(pos: Vec, c: Char){
def attractiveness(offset: Vec) = {
val dist = (pos - offset).dist
val value: Double = c match{
case 'P' => 20000;
case 'p' => if(dist < 8) -10000 else -5000;
case 'B' => 50000;
case 'b' => if(dist < 8) -10000 else -5000;
case 'W' => if(dist < 8) -10000 else -5000;
case _ => 0;
}
value / (dist + 1)
}
def p = this.pos
}
class ViewParser(input: String) {
val size = math.sqrt(input.length()).toInt
val center = Vec(size / 2, size / 2)
val best = parse
private def parse = {
val cells = input.zipWithIndex.map(cell => new Cell(pos(cell._2), cell._1))
Vec.dirs.map(dir => (dir, cells.foldLeft(0.0)((value, cell) => value + cell.attractiveness(dir)))).maxBy(_._2)._1
}
private def pos(index: Int) = {
Vec(index % size, index / size) - center
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment