JSFiddle - React, Tailwind, and code Playground

by rigor789

HTML

<table id="map">
  <tr>
    <td>
      <div class="entity laser"></div>
    </td>
    <td></td>
    <td>
      <div class="entity checkpoint"></div>
    </td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

<table id="inv">
  <tr>
    <td></td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td></td>
  </tr>
  <tr>
    <td></td>
  </tr>
</table>

CSS

* {
  margin: 0;
  box-sizing: border-box;
}

table {
  border: 1px solid #333;
  border-collapse: collapse;
}

table td {
  position: relative;
  width: 80px;
  height: 80px;
  border: 1px solid #333;
  padding: 0;
}

#map {
  float: left;
}

#inv {
  float: left;
  margin-left: 40px;
}

table label {
  position: absolute;
  top: 10px;
  left: 10px;
}

.entity {
  display: block;
  background: #eee;
  width: 78px;
  height: 78px;
}

.laser {
  background: red;
}

.mirror {
  background: blue;
}

.double_mirror {
  background: lime;
}

.checkpoint {
  background: yellow;
}

JavaScript

const DEBUG = true

let Entity = {
  laser: 'laser',
  mirror: 'mirror',
  double_mirror: 'double_mirror',
  checkpoint: 'checkpoint'
}

let map = document.getElementById('map')
let inv = document.getElementById('inv')

if (map && inv) {
  init()
}

function init() {
  if (DEBUG) {
    addLabels()
  }

  walk(map, (s, i, j) => {
    // random testing
    if (i % 2 == 0 && j % 2 == 0) addEntity(i, j, Entity.mirror)
  })
}

function addEntity(i, j, type) {
  let target = getEntityAt(i, j)
  if (target) {
    return false
  }
  let entity = document.createElement('div')
  entity.className = 'entity'
  entity.classList.add(type)
  map.rows[i].cells[j].appendChild(entity)

  return entity;
}

function getEntityAt(i, j) {
  let children = Array.from(map.rows[i].cells[j].childNodes)

  return children.find((node) => {
    if (node.tagName !== 'DIV') {
      return false
    }
    return node.classList.contains('entity');
  })
}

function addLabels() {
  walk(map, (s, i, j) => {
    let label = document.createElement('label')
    label.innerText = `${i}:${j}`
    s.appendChild(label)
  })

  walk(inv, (s, i, j) => {
    let label = document.createElement('label')
    label.innerText = `${i}:${j}`
    s.appendChild(label)
  })
}

function walk(el, cb) {
  let rows = Array.from(el.rows)

  rows.forEach((row, i) => {
    let cols = Array.from(row.cells)

    cols.forEach((col, j) => {
      cb(col, i, j)
    })
  })
}