JSFiddle - React, Tailwind, and code Playground

by ozzon91

HTML

<div id="app"></div>

<template id="t">
  <table @click.once="go">
    <tr v-for="(r, ri) in canvas" :key="ri">
      <td v-for="(c, ci) in canvas[ri]" :class="{active: c, head: c === 2,  food: c === 3}" :key="ci">
        <div></div>
      </td>
    </tr>
  </table>
</template>

SCSS

table {
  background-image: url("https://img3.stockfresh.com/files/s/smithore/m/92/232622_stock-photo-dry-soil-texture.jpg")
}

td {
  border: 1px dashed #333;
  
  &.food {
    > div {
      background: red !important;
      visibility: visible;
    }
  }
  
  > div {
    visibility: hidden;
    width: 30px;
    height:30px;
    box-shadow: -3px 2px 4px #333;
  }
  
  &.head {
    > div {
      background: green !important;
    }
  }
  
  &.active {
    
    > div {
      background: tan;
      border-radius: 40%;
      visibility: visible;
    }
  }
}

JavaScript

new Vue({
	el: '#app',
  template: '#t',
  created() {
  	for(let i = 0; i<this.rowsNumber; i++) {
    	for(let j = 0; j<this.colsNumber; j++) {
    		if(this.canvas[i]) {
        	this.canvas[i].push(0);
        } else {
          this.$set(this.canvas, i, [0]);
        }
    	}
    }
  },
  mounted() {
  	window.addEventListener('keyup', event => {
    	this.turn(event);
    });
    
    this.drawSnake();
  },
  
  
  methods: {
  	go() {
    	setInterval(this.draw, 20);
    },
    
  	turn(e) {
    	let keyCode = e.keyCode || e.which;   
      this.direction = keyCode;    
    },
    
    setFood() {
    	if(Array.isArray(this.food)) {
      	this.$set(this.canvas[this.food[0]], this.food[1], 3);
      	return;
      }
    
    	let rRandom = this.getRandomInt(0, 9);
      let cRandom = this.getRandomInt(0, 9);
      
      let wrongCellForfood = this.snake.find(el => el[0] == rRandom && el[1] == cRandom);
      
      if(!wrongCellForfood) {
      	this.$set(this.canvas[rRandom], cRandom, 3);
        this.food = [rRandom, cRandom];
      }
    },
    
    draw() {
    	// clear canvas
    	this.canvas.forEach((row, i) => {                
        this.canvas[i].forEach((col, j) => {
          this.$set(this.canvas[i], j, 0);
        })
      })
      
      let r = this.snake[0][0];
      let c = this.snake[0][1];
      
     this.setFood();
     
      switch(this.direction) {
      	case this.keys.LEFT: 
        	if(c <= 0) {
          	c = this.colsNumber;
          } else {
          	--c
          }
        	if(this.food && this.canvas[r][c] != 3) {
          	this.snake.pop();
          } else {
          	this.food = null;
          }
          this.snake.unshift([r, c]);
          this.drawSnake();
        break;
        
        case this.keys.RIGHT: 
        	if(c == this.colsNumber) {
          	c = 0;
          } else {
          	++c
          }
        	if(this.food && this.canvas[r][c] != 3) {
          	this.snake.pop();
          } else {
   ...