JSFiddle - React, Tailwind, and code Playground

by mlms13

HTML

<div id="gameBoard"></div>

CSS

body {
    font-family: sans-serif;
    text-align: center;
}
#gameBoard {
    border-left: 2px solid #999;
    border-top: 2px solid #999;
    display: inline-block;
    position: relative;
}
#gameBoard div {
    border-bottom: 2px solid #999;
    border-right: 2px solid #999;
    color: #999;
    cursor: default;
    float: left;
    font-size: 16px;
    height: 32px;
    line-height: 32px;
    overflow: hidden;
    text-align: center;
    -webkit-user-select: none;
    user-select: none;
    width: 32px;
}
#gameBoard div.first {
    clear: left;
}
#gameBoard div.adjacent {
    background: #eaf6ff;
}

#gameBoard div.valid {
    background: #dfc;
    cursor: pointer;
}

#gameBoard div.invalid {
    background: #fdd;
}
#gameBoard div#marker {
    border: 3px solid #68d;
    border-radius: 2px;
    position: absolute;
}

JavaScript

function Marker() {
    var self = this,
        boardElement = document.getElementById('gameBoard'),
        markerElement;
    
    this.position = {x : 0, y : 0};
    
    this.draw = function () {        
        markerElement = document.createElement('div');
        markerElement.setAttribute('id', 'marker');
        boardElement.appendChild(markerElement);
    };
    this.setPosition = function (x, y) {
        // assumptions: 1. boxes are square,
        // 2. marker's border is 1px thicker than normal box borders
        var borderWidth = parseInt(window.getComputedStyle(markerElement, null).getPropertyValue('border-left-width'), 10),
            boxWidth = markerElement.offsetWidth - borderWidth - 1;
        
        self.position.x = x;
        self.position.y = y;
        
        markerElement.style.left = x * boxWidth - borderWidth + 'px';
        markerElement.style.top = y * boxWidth - borderWidth + 'px';
    };
}

function Board(height, width) {
    var self = this,
        boardElement = document.getElementById('gameBoard'),
        selected = new Marker();
    this.height = height;
    this.width = width;
    
    function getElementByCoordinates(x, y) {
        var index = y * self.width + x,
            elem = boardElement.getElementsByTagName('div')[index];
        if (!elem) {
            throw {
                name: 'Out of Range',
                message: 'There is no box with the coordinates ' + x + ', ' + y
            };
        }
        return elem;
        
    }
    function addMarker() {
        var x = Math.floor(Math.random() * self.width),
            y = Math.floor(Math.random() * self.height),
            selectedElement = getElementByCoordinates(x, y);
        
        selected.draw();
        selected.setPosition(x, y);
        selectedElement.removeChild(selectedElement.childNodes[0]);
    }
    function determineValidity(x, y) {
        var i, xOffset = 0, yOffset = 0, currentX = x, currentY = y, isValid = true,
         ...