Playground

by Evgeniy Lukovsky

HTML

<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
<script src="https://unpkg.com/[email protected]"></script>

<div id="app">
  <div class="panel">
    <div class="cell">
    
      <textarea v-model.trim="waypoints" v-on:input="start"></textarea>
      <div class="explain">
        <div v-for="cmd in lines">
          {{cmd}}
        </div>
      </div>
    </div>
  </div>
</div>

SCSS

.panel {
  position: fixed;
  width: 400px;
  display: block;
  right: 20px;
  top: 20px;
  height: 600px;
  background: grey;
  .cell {
    margin: 20px;
    position: relative;
  }
  textarea {
    margin: 0px auto;
    width: 100%;
    height: 100px;
  }
  .explain > {
    height: 1.5em;
    background: white;
  }
}

Vue

class Processor {
  constructor({
    waypoints: wp
  }) {
    this.waypoints = wp
    this.rovers = []
    this.currentRover = null
    this.maxPoint = {
      x: 0,
      y: 0
    }
    this.minPoint = {
      x: 0,
      y: 0
    }
  }

  start() {
    if (typeof(this.waypoints) != 'string') return
    this.processLines()
    this.printResults()
  }

  processLines() {
    this.lines = this.waypoints.split("\n").reduce((acc, i) => {
      let trimmed = i.trim()
      if (trimmed) {
        this.parseLine(trimmed)
        acc.push(trimmed)
      }
      return acc
    }, [])
  }

  parseLine(line) {
    const maxSizePattern = /^(\d+)\s(\d+)$/
    const startPattern = /^(\d+)\s(\d+)\s([NWSE])$/
    const guidancePattern = /^(:?([LRM])\s?)+$/

    switch (true) {
      case maxSizePattern.test(line):
        console.log("• Matched 'max plateau size' test");
        let [size, x, y] = maxSizePattern.exec(line)
        this.maxPoint = {
          x: parseInt(x, 10),
          y: parseInt(y, 10)
        }
        console.log(this.maxPoint)
        break;
      case startPattern.test(line):
        console.log("• Matched 'rover start command' test")
        let [cmd, rx, ry, heading] = startPattern.exec(line)
        this.currentRover = new Rover({
          x: parseInt(rx, 10),
          y: parseInt(ry, 10),
          heading: heading
        })
        this.rovers.push(this.currentRover)
        break;
      case guidancePattern.test(line):
        console.log("• Matched 'rover guidance command' test");
        let commands = guidancePattern.exec(line)[0].split(/\s/)
        this.currentRover.sendGuidance(commands, this.moved.bind(this))
        break;
      default:
        console.log("• Unknown command", line);
        break;
    }
  }

  moved({
    x: x,
    y: y
  }) {
    if (x < this.minPoint.x || x > this.maxPoint.x || y < this.minPoint.y || y > this.maxPoint.y) {
      this.currentRover.leftPlateau = true
    }
  }

  printResults() {
   ...