JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://unpkg.com/vue"></script>
<h2>
 whack a mole!
</h2> Whack moles! If you get them all, you win. Moles are orange. Click on them to whack them.

<div id="app">
  <h2 v-if="won()">
     YOU WIN!!!
  </h2>
  <table v-if="!won()">
    <tr v-for="(array, x_coord) in mole_grid">
      <td v-for="(value, y_coord) in array">
        <div class="circle" v-on:click="squash(x_coord, y_coord)" v-bind:style="{ background: value ? 'orange' : 'black'}"></div>
      </td>
    </tr>
  </table>
</div>

CSS

.circle {
  border-radius: 50%;
  width: 50px;
  height: 50px;
  /* width and height can be anything, as long as they're equal */
}

JavaScript

var app = new Vue({
  el: '#app',
  data: {
    mole_grid: [
      [0, 1, 0],
      [0, 0, 0],
      [1, 0, 1]
    ],
    has_won: false,
  },
  methods: {
    set_mole: function(x_coord, y_coord, value) {
      this.mole_grid[x_coord][y_coord] = value;
      Vue.set(this.mole_grid, x_coord, this.mole_grid[x_coord]);
    },
    squash: function(x_coord, y_coord) {
      this.set_mole(x_coord, y_coord, 0);
    },
    won: function () {
    	if (this.has_won) {
      	return true
      }
    	var sum = 0;
      for (var i in this.mole_grid) {
      	for (var j in this.mole_grid[i]) {
        	sum += parseInt(this.mole_grid[i][j]);
        }
      }
      if (sum == 0) {
      	this.has_won = true;
      }
      return this.has_won;
    }
  }
})

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

setInterval(function() {
console.log(app.won());
  app.set_mole(getRandomInt(0, app.mole_grid.length), getRandomInt(0, app.mole_grid[0].length), 1)
}, 500);

app.squash(0, 1)