检测用户是否在div的4x4网格中创建了4x4线

时间:2019-07-12 01:44:30

标签: vue.js

因此,我正在使用vue构建自己的自定义宾果表4x4。除了如何检测用户是否形成了水平,对角或垂直的4x4线之外,我的一切都没有了

enter image description here

在我的数据函数中,我有一个表示4x4的数组

[9, 13, 28, 24],
[11, 22, 15, 43],
[54, 5, 37, 4],
[27, 40, 12, 36]

我的问题是如何检查用户是否单击了4x4线?不需要任何代码作为答案,我只是想知道如何解决这个问题。

2 个答案:

答案 0 :(得分:1)

给出一个n x n矩阵

水平

是否有n个选择的元素具有相同的rowIndex

垂直:

是否有n个选择的元素具有相同的columnIndex

对角线(从左上到右下)

是否有n个元素与它们的rowIndex具有相同的columnIndex

对角线(从右上到左下)

是否有n个元素满足(length(row) - 1) - rowIndex == columnIndex

const Card = Vue.component('card', {
  template: '#card',
  props: {
    playerCard: Array
  },
  data() {
    return {
      selectedVals: [],
      rowCounts: {},
      colCounts: {}
    }
  },
  computed: {
    horizontalNumberToWin() {
      return this.playerCard[0].length;
    },
    verticalNumberToWin() {
      return this.playerCard.length;
    },
    diagonalNumberToWin() {
      return this.playerCard.length;
    },
    isDiagonal() {
      if (this.selectedVals.length < this.diagonalNumberToWin) return false;
      // top left to bottom right
      // [0, 0] [1, 1], [2, 2], [3, 3], etc..
      const isTLtoBR = this.selectedVals.filter(val => val[0] === val[1]);
      if (isTLtoBR.length >= this.diagonalNumberToWin) return true;

      // top right to bottom left
      // [0, 3], [1, 2], [2, 1], [3, 0], etc..
      const rowLen = this.playerCard[0].length;
      const isTRtoBL = this.selectedVals.filter(val => {
        return (rowLen -1) - val[0] === val[1];
      });      
      if (isTRtoBL.length >= this.diagonalNumberToWin) return true;

      return false;
    },
    isHorizontal() {
      if (this.selectedVals.length < this.horizontalNumberToWin) return false;
      return Object.values(this.rowCounts).some(row => row >= this.horizontalNumberToWin);
    },
    isVertical() {
      if (this.selectedVals.length < this.verticalNumberToWin) return false;
      return Object.values(this.colCounts).some(col => col >= this.verticalNumberToWin);
    },
  },
  methods: {
    onCardClicked(coord) {
      this.selectedVals.push(coord);
      this.updateCounts(coord);
    },
    cardDisabled(coord) {
      return this.selectedVals.some(vals => vals[0] === coord[0] && vals[1] === coord[1]);
    },
    updateCounts(coord) {
      const rowIndex = coord[0];
      const colIndex = coord[1];
      this.rowCounts[rowIndex] = this.rowCounts[rowIndex] ? this.rowCounts[rowIndex] + 1 : 1;
      this.colCounts[colIndex] = this.colCounts[colIndex] ? this.colCounts[colIndex] + 1 : 1;
    }
  }
});

new Vue({
  el: '#app',
  components: {
    Card,
  },
  data: {
    playerCard: [
      [9, 13, 28, 24],
      [11, 22, 15, 43],
      [54, 5, 37, 4],
      [27, 40, 12, 36]
    ],
  },
})
#app { 
  display: flex;
  flex-direction: row;
  justify-content: center;
}

.board {
  max-width: 500px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  <card :player-card="playerCard" />
</div>

<template id="card">
  <div>
    <p>Horizontal: {{ isHorizontal }}</p>
    <p>Vertical: {{ isVertical }}</p>
    <p>Diagonal: {{ isDiagonal }}</p>
    <div class="board">
      <template v-for="(row, rowIndex) in playerCard">
        <button
          v-for="(col, colIndex) in row"
          :key="col"
          :disabled="cardDisabled([rowIndex, colIndex])"
          @click="onCardClicked([rowIndex, colIndex])">
          {{ col }}
        </button>
      </template>
    </div>
  </div>

</template>

答案 1 :(得分:0)

首先,我认为您应该添加isClick来检查用户是否单击了卡。

[
  [
    { Number: 9 , isClick: false },
    { Number: 13 , isClick: false },
    { Number: 28 , isClick: false },
    { Number: 24 , isClick: false }
  ],
  // other array ...
]

第二,将您的数据绑定到html(也许您应该使用两次v-for来实现它)。用户单击卡时,设置isClick = true

第三,编写您自己的逻辑,以检查用户是否单击了4x4线。