Advertisement
Guest User

Untitled

a guest
Mar 21st, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.57 KB | None | 0 0
  1. class ControlFunction {
  2. def respond(input: String): String = {
  3. val (opcode, paramMap) = CommandParser(input)
  4. if( opcode == "React" ) {
  5. val viewString = paramMap("view")
  6. val view = View(viewString)
  7. val generation = paramMap("generation").toInt
  8.  
  9. if ( generation > 0 ) {
  10. view.offsetToNearest('b') match {
  11. case Some(offset) =>
  12. val unitOffset = offset.signum
  13. "Move(direction=" + unitOffset + ")"
  14. case None => {
  15. view.offsetToNearest('P') match {
  16. case Some(offset) =>
  17. val unitOffset = offset.signum
  18. "Move(direction=" + unitOffset + ")"
  19. case None => ""
  20. }
  21. }
  22. }
  23. }
  24. else {
  25.  
  26. var spawn = new String
  27.  
  28. view.offsetToNearest('b') match {
  29. case Some(offset) =>
  30. val unitOffset = offset.signum
  31. if ( paramMap("energy").toInt > 500 ) {
  32. spawn = "|Spawn(direction=" + unitOffset + ",energy=100,heading=" + unitOffset + ")"
  33. }
  34. case None => ""
  35. }
  36.  
  37. view.offsetToNearest('P') match {
  38. case Some(offset) =>
  39. val unitOffset = offset.signum
  40. "Move(direction=" + unitOffset + ")" + spawn
  41.  
  42. case None =>
  43. view.offsetToNearest('W') match {
  44. case Some(offset) =>
  45. if( offset.signum.x > 0 && offset.signum.y == 0 ) {
  46. "Move(direction=" + XY.Left + ")"
  47. } else if ( offset.signum.x < 0 && offset.signum.y == 0 ) {
  48. "Move(direction=" + XY.Right + ")"
  49. } else if ( offset.signum.y > 0 ) {
  50. "Move(direction=" + XY.Down + ")"
  51. } else if ( offset.signum.y < 0 ) {
  52. "Move(direction=" + XY.Up + ")"
  53. } else ""
  54. case None =>
  55. ""
  56. }
  57. }
  58. }
  59. } else ""
  60. }
  61. }
  62.  
  63. case class View(cells: String) {
  64. val size = math.sqrt(cells.length).toInt
  65. val center = XY(size/2, size/2)
  66.  
  67. def apply(relPos: XY) = cellAtRelPos(relPos)
  68.  
  69. def indexFromAbsPos(absPos: XY) = absPos.x + absPos.y * size
  70. def absPosFromIndex(index: Int) = XY(index % size, index / size)
  71. def absPosFromRelPos(relPos: XY) = relPos + center
  72. def cellAtAbsPos(absPos: XY) = cells.apply(indexFromAbsPos(absPos))
  73.  
  74. def indexFromRelPos(relPos: XY) = indexFromAbsPos(absPosFromRelPos(relPos))
  75. def relPosFromAbsPos(absPos: XY) = absPos - center
  76. def relPosFromIndex(index: Int) = relPosFromAbsPos(absPosFromIndex(index))
  77. def cellAtRelPos(relPos: XY) = cells(indexFromRelPos(relPos))
  78.  
  79. def offsetToNearest(c: Char) = {
  80. var nearestPosOpt : Option[XY] = None
  81. var nearestDistance = Double.MaxValue
  82. for (i <- 0 until cells.length) {
  83. if(c == cells(i)) {
  84. val pos = absPosFromIndex(i)
  85. val distanceToCenter = pos.distanceTo(center)
  86. if (distanceToCenter < nearestDistance) {
  87. nearestDistance = distanceToCenter
  88. nearestPosOpt = Some(pos - center)
  89. }
  90. }
  91. }
  92. nearestPosOpt
  93. }
  94. }
  95.  
  96. case class XY(x: Int, y: Int) {
  97. override def toString = x + ":" + y
  98.  
  99. def +(pos: XY) = XY(x+pos.x, y+pos.y)
  100. def -(pos: XY) = XY(x-pos.x, y-pos.y)
  101. def *(factor: Double) = XY((x*factor).intValue, (y*factor).intValue)
  102.  
  103. def distanceTo(pos: XY) : Double = (this-pos).length
  104. def length : Double = math.sqrt(x*x + y*y)
  105.  
  106. def signum = XY(x.signum, y.signum)
  107.  
  108. def negate = XY(-x, -y)
  109. def negateX = XY(-x, y)
  110. def negateY = XY(x, -y)
  111. }
  112.  
  113. object XY {
  114. def apply(s: String) : XY = {
  115. val xy = s.split(':').map(_.toInt)
  116. XY(xy(0), xy(1))
  117. }
  118.  
  119. val Zero = XY(0,0)
  120. val One = XY(1,1)
  121.  
  122. val Right = XY( 1, 0)
  123. val RightUp = XY( 1, -1)
  124. val Up = XY( 0, 1)
  125. val UpLeft = XY(-1, -1)
  126. val Left = XY(-1, 0)
  127. val LeftDown = XY(-1, 1)
  128. val Down = XY( 0, -1)
  129. val DownRight = XY( 1, 1)
  130. }
  131.  
  132. object CommandParser {
  133. def apply(command: String) = {
  134. def splitParam(param: String) = {
  135. val segments = param.split('=')
  136. if( segments.length != 2 )
  137. throw new IllegalStateException("invalid key/value pair: " + param)
  138. (segments(0),segments(1))
  139. }
  140.  
  141. val segments = command.split('(')
  142. if( segments.length != 2 )
  143. throw new IllegalStateException("invalid command: " + command)
  144.  
  145. val params = segments(1).dropRight(1).split(',')
  146. val keyValuePairs = params.map( splitParam ).toMap
  147. (segments(0), keyValuePairs)
  148. }
  149. }
  150.  
  151. class ControlFunctionFactory {
  152. def create = new ControlFunction().respond _
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement