Basic Mithril validation mixin

A basic mixin for Mithril with no sugar.

by ramnathv

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/mithril/0.1.21/mithril.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>

CSS

.cell {
    position: absolute;
    width: 6px;
    height: 6px;
    background: green;
}

JavaScript

var blinker = [[1, 0], [1, 1], [1, 2]].map(toCell);
var pentomino = [[0, 1], [1, 0], [1, 1], [1, 2], [2, 0]].map(toCell);
var acorn = [[0, 2], [1, 0], [1, 2], [3, 1], [4, 2], [5, 2], [6, 2]].map(toCell);

var aliveCells;
var aliveCellsById;

setAliveCells(acorn);

function toCell(tuple) {
    var x  = tuple[0],
        y  = tuple[1],
        id = '' + x + y;

    return {id: id, x: x, y: y};
}

function neighbours(cell) {
    var x = cell.x, 
        y = cell.y;

    return [
        [x - 1, y],
        [x - 1, y - 1],
        [x - 1, y + 1],
        [x, y - 1],
        [x, y + 1],
        [x + 1, y],
        [x + 1, y - 1],
        [x + 1, y + 1]
    ].map(toCell);
}

function isAlive(cell) {
    return aliveCellsById[cell.id];
}

function setAliveCells(value) {
   aliveCells = value;
   aliveCellsById = _.indexBy(value, 'id');
}

function filterCell(cell) {
    var cellNeighbours = neighbours(cell);
    var aliveNeighbours = cellNeighbours.filter(isAlive).length;

    return isAlive(cell)
        ? (aliveNeighbours == 2 || aliveNeighbours == 3)
        : (aliveNeighbours == 3);
}

function renderNext() {
   var nearCells = _.uniq(_.flatten(aliveCells.map(neighbours)), 'id');
   var newAliveCells = nearCells.filter(filterCell);

   setAliveCells(newAliveCells);
   m.redraw();
}

var game = {

  controller: _.noop,
    
  view: function (ctrl) {
    var cellSize = 6;
    var offset = 200;
     
    var cells = aliveCells.map(function(cell) {
        var style = {
            top: (offset + cell.y * cellSize) + 'px',
            left: (offset + cell.x * cellSize) + 'px'
        };
        return m('div.cell', {style: style});
    });
      
    return m('div', cells)
    
  }
};

m.module(document.body, game);
setInterval(renderNext, 3);