advent-of-code/2019/Scala/day11/Robot.scala

76 lines
2.5 KiB
Scala
Raw Normal View History

2019-12-11 07:36:48 +01:00
package day11
import day11.direction._
import intcode.{Finished, Input, Machine, Ready}
import scala.collection.mutable
2019-12-11 18:47:35 +01:00
class Robot(software: Array[Long], init: Byte = 0) {
2019-12-11 07:36:48 +01:00
private[this] val brain: Machine = new Machine(software)
2019-12-11 18:47:35 +01:00
private[this] val map: mutable.HashMap[(Int, Int), Byte] = new mutable.HashMap()
2019-12-11 12:17:28 +01:00
private[this] var location: (Int, Int) = (0, 0)
2019-12-11 07:36:48 +01:00
private[this] var direction: Direction = Up
2019-12-11 12:17:28 +01:00
if (init != 0) map.addOne((0,0), init) // when starting on white
2019-12-11 07:36:48 +01:00
2019-12-11 12:17:28 +01:00
def paintedPanels: Int = map.size
2019-12-11 07:36:48 +01:00
2019-12-11 18:47:35 +01:00
def updateColor(point: (Int, Int), color: Byte): Unit = map(point) = color
2019-12-11 07:36:48 +01:00
2019-12-11 18:47:35 +01:00
def findColor(point: (Int, Int)): Byte = map.getOrElse(point, 0)
2019-12-11 07:36:48 +01:00
2019-12-11 12:17:28 +01:00
def nextLocation(point: (Int, Int), direction: Direction, command: Int): ((Int, Int), Direction) = {
(point, direction, command) match {
case ((x, y), Up, 0) => ((x-1, y), Left)
case ((x, y), Up, 1) => ((x+1, y), Right)
case ((x, y), Down, 0) => ((x+1, y), Right)
case ((x, y), Down, 1) => ((x-1, y), Left)
case ((x, y), Left, 0) => ((x, y-1), Down)
case ((x, y), Left, 1) => ((x, y+1), Up)
case ((x, y), Right, 0) => ((x, y+1), Up)
case ((x, y), Right, 1) => ((x, y-1), Down)
2019-12-11 07:36:48 +01:00
case _ => throw new Exception("Something went wrong")
}
}
// This print function uses a naive approach of having stuff hardcoded for my output, so might require calibration
2019-12-11 12:33:00 +01:00
// TODO make this better
2019-12-11 07:36:48 +01:00
def printMap(): Unit = {
2019-12-11 18:47:35 +01:00
val list = map.toList // map as list, order irrelevant
val p = list.head._1 // some random first point
2019-12-11 07:36:48 +01:00
val matrix = Array.ofDim[Char](6, 46)
map.foreach(tuple => {
2019-12-11 12:17:28 +01:00
matrix(tuple._1._2+5)(tuple._1._1) = if (tuple._2 == 0) '.' else '#'
2019-12-11 07:36:48 +01:00
})
for (i <- matrix.indices.reverse; j <- matrix(0).indices) {
print(matrix(i)(j))
if (j == 0) println()
}
println()
}
@scala.annotation.tailrec
final def run(): Unit = {
brain.getState match {
// Ready to run
case Ready =>
brain.run()
this.run()
// Finished the program
case Finished => ()
// Program requires input of some sorts
case Input =>
brain.enqueue(findColor(location))
brain.run()
2019-12-11 18:47:35 +01:00
updateColor(location, brain.output.toByte) // 1st output -> color
2019-12-11 07:36:48 +01:00
val (p, d) = nextLocation(location, direction, brain.output.toInt) // 2nd output -> direction
location = p
direction = d
this.run()
}
}
}