N square calculations with Vue.js

by bc_rikko

HTML

<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<main id="game">
  <table>
    <tr>
      <th>\</th>
      <th v-for="n in cols" :key="n">
        {{ n }}
      </th>
    </tr>
    
    <tr v-for="(m, i) in rows" :key="m">
      <th>{{ m }}</th>
      <td v-for="(_, j) in boxes" :key="j">
        <div contenteditable="true" @blur="onBlur($event, i, j)"></div>
      </td>
    </tr>
  </table>
  
  <button type="button" @click="finish">Finish</button>
</main>

CSS

body {
  padding: 20px;
  background-color: white;
}

table {
  text-align: center;
  border-collapse: collapse;
}



table tr {
  height: 40px;
}

table th, td {
  border: 3px solid #39B885;
  width: 40px;
}

table th {
  background-color: #39B885;
  color: white;
}

JavaScript

new Vue({
  el: '#game',
  data() {
    return {
      boxes: 10,
      rows: [],
      cols: [],
      result: []
    }
  },
  created() {
    this.rows = this.randomNumbers();
    this.cols = this.randomNumbers();
  
    let rows = new Array(this.boxes);
    [...Array(this.boxes)].forEach((_, i) => rows[i] = new Array(this.boxes).fill(0));
    
    this.result = rows;
  },
  methods: {
    // computedだと再計算されないためmethodsで定義
    randomNumbers() {
  		const nums = [...Array(this.boxes)].map((_, a) => a + 1);
      for (let i = nums.length - 1; 0 < i; i--) {
        let r = Math.floor(Math.random() * (i + 1));
        // nums[i] <-> nums[r]
        [nums[i], nums[r]] = [nums[r], nums[i]];
      }
      return nums;
    },
    onBlur(e, i, j) {
      this.result[i][j] = /^[0-9]+$/.test(e.target.innerText) ? +e.target.innerText : 0; 
    },
    finish() {
      const result = !this.cols.some((v, i) => {
        return this.rows.some((w, j) => {
          return this.result[i][j] !== v + w;
        });
      });
      
      alert(result ? '正解' : '不正解');
    }
  }
});