Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ControlFunction {
- def respond(input: String): String = {
- val (opcode, paramMap) = CommandParser(input)
- if( opcode == "React" ) {
- val viewString = paramMap("view")
- val view = View(viewString)
- val generation = paramMap("generation").toInt
- if ( generation > 0 ) {
- view.offsetToNearest('b') match {
- case Some(offset) =>
- val unitOffset = offset.signum
- "Move(direction=" + unitOffset + ")"
- case None => {
- view.offsetToNearest('P') match {
- case Some(offset) =>
- val unitOffset = offset.signum
- "Move(direction=" + unitOffset + ")"
- case None => ""
- }
- }
- }
- }
- else {
- var spawn = new String
- view.offsetToNearest('b') match {
- case Some(offset) =>
- val unitOffset = offset.signum
- if ( paramMap("energy").toInt > 500 ) {
- spawn = "|Spawn(direction=" + unitOffset + ",energy=100,heading=" + unitOffset + ")"
- }
- case None => ""
- }
- view.offsetToNearest('P') match {
- case Some(offset) =>
- val unitOffset = offset.signum
- "Move(direction=" + unitOffset + ")" + spawn
- case None =>
- view.offsetToNearest('W') match {
- case Some(offset) =>
- if( offset.signum.x > 0 && offset.signum.y == 0 ) {
- "Move(direction=" + XY.Left + ")"
- } else if ( offset.signum.x < 0 && offset.signum.y == 0 ) {
- "Move(direction=" + XY.Right + ")"
- } else if ( offset.signum.y > 0 ) {
- "Move(direction=" + XY.Down + ")"
- } else if ( offset.signum.y < 0 ) {
- "Move(direction=" + XY.Up + ")"
- } else ""
- case None =>
- ""
- }
- }
- }
- } else ""
- }
- }
- case class View(cells: String) {
- val size = math.sqrt(cells.length).toInt
- val center = XY(size/2, size/2)
- def apply(relPos: XY) = cellAtRelPos(relPos)
- def indexFromAbsPos(absPos: XY) = absPos.x + absPos.y * size
- def absPosFromIndex(index: Int) = XY(index % size, index / size)
- def absPosFromRelPos(relPos: XY) = relPos + center
- def cellAtAbsPos(absPos: XY) = cells.apply(indexFromAbsPos(absPos))
- def indexFromRelPos(relPos: XY) = indexFromAbsPos(absPosFromRelPos(relPos))
- def relPosFromAbsPos(absPos: XY) = absPos - center
- def relPosFromIndex(index: Int) = relPosFromAbsPos(absPosFromIndex(index))
- def cellAtRelPos(relPos: XY) = cells(indexFromRelPos(relPos))
- def offsetToNearest(c: Char) = {
- var nearestPosOpt : Option[XY] = None
- var nearestDistance = Double.MaxValue
- for (i <- 0 until cells.length) {
- if(c == cells(i)) {
- val pos = absPosFromIndex(i)
- val distanceToCenter = pos.distanceTo(center)
- if (distanceToCenter < nearestDistance) {
- nearestDistance = distanceToCenter
- nearestPosOpt = Some(pos - center)
- }
- }
- }
- nearestPosOpt
- }
- }
- case class XY(x: Int, y: Int) {
- override def toString = x + ":" + y
- def +(pos: XY) = XY(x+pos.x, y+pos.y)
- def -(pos: XY) = XY(x-pos.x, y-pos.y)
- def *(factor: Double) = XY((x*factor).intValue, (y*factor).intValue)
- def distanceTo(pos: XY) : Double = (this-pos).length
- def length : Double = math.sqrt(x*x + y*y)
- def signum = XY(x.signum, y.signum)
- def negate = XY(-x, -y)
- def negateX = XY(-x, y)
- def negateY = XY(x, -y)
- }
- object XY {
- def apply(s: String) : XY = {
- val xy = s.split(':').map(_.toInt)
- XY(xy(0), xy(1))
- }
- val Zero = XY(0,0)
- val One = XY(1,1)
- val Right = XY( 1, 0)
- val RightUp = XY( 1, -1)
- val Up = XY( 0, 1)
- val UpLeft = XY(-1, -1)
- val Left = XY(-1, 0)
- val LeftDown = XY(-1, 1)
- val Down = XY( 0, -1)
- val DownRight = XY( 1, 1)
- }
- object CommandParser {
- def apply(command: String) = {
- def splitParam(param: String) = {
- val segments = param.split('=')
- if( segments.length != 2 )
- throw new IllegalStateException("invalid key/value pair: " + param)
- (segments(0),segments(1))
- }
- val segments = command.split('(')
- if( segments.length != 2 )
- throw new IllegalStateException("invalid command: " + command)
- val params = segments(1).dropRight(1).split(',')
- val keyValuePairs = params.map( splitParam ).toMap
- (segments(0), keyValuePairs)
- }
- }
- class ControlFunctionFactory {
- def create = new ControlFunction().respond _
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement