用uniapp写一个黑白棋游戏

用uniapp写一个黑白棋游戏


实现过程

1.定义一个棋盘组件

定义一个棋盘组件 Chessboard.vue,其中包含一个二维数组 matrix,代表棋盘上的每个格子,以及一个 currentColor 变量,表示当前下棋的颜色(黑色或白色)。

<template>
  <div class="chessboard">
    <div v-for="(row, i) in matrix" :key="i" class="chessboard-row">
      <div v-for="(col, j) in row" :key="j" class="chessboard-col">
        <div :class="[col === 0 ? 'white' : col === 1 ? 'black' : '']"></div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      matrix: [
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, 0, 1, null, null, null],
        [null, null, null, 1, 0, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
      ],
      currentColor: 1,
    };
  },
};
</script>

<style scoped>
.chessboard {
  width: 400px;
  height: 400px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.chessboard-row {
  display: flex;
}

.chessboard-col {
  width: 50px;
  height: 50px;
}

.chessboard-col > div {
  width: 100%;
  height: 100%;
  border-radius: 25px;
  background-color: white;
}

.white {
  background-color: white;
}

.black {
  background-color: black;
}
</style>

2.添加点击事件,实现下棋功能

在 Chessboard.vue 中添加一个 clickSquare 方法,当用户点击一个棋盘格子时,如果该格子为空,则调用该方法,将该格子设置为当前棋子的颜色,并将棋盘上所有与该棋子连通的同色棋子颜色设置为当前棋子颜色。具体实现可以参考以下代码:

<template>
  <div class="chessboard">
    <div v-for="(row, i) in matrix" :key="i" class="chessboard-row">
      <div v-for="(col, j) in row" :key="j" class="chessboard-col">
        <div :class="[col === 0 ? 'white' : col === 1 ? 'black' : '']" @click="clickSquare(i, j)"></div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      matrix: [
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, 0, 1, null, null, null],
        [null, null, null, 1, 0, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
      ],
      currentColor: 1,
    };
  },
  methods: {
    clickSquare(row, col) {
      // 如果该格子已有棋子,则不能下棋
      if (this.matrix[row][col] !== null) return;

      const directions = [
        [0, 1],
        [0, -1],
        [1, 0],
        [-1, 0],
        [1, 1],
        [1, -1],
        [-1, 1],
        [-1, -1],
      ];
      const toFlip = [];
      // 搜索与该棋子直接相邻的八个方向
      for (let d of directions) {
        let x = row + d[0];
        let y = col + d[1];
        let count = 0;
        let temp = [];
        // 如果在该方向上出现了同色棋子,则继续朝该方向搜索,直到搜索到不同色棋子或边界
        while (x >= 0 && y >= 0 && x < 8 && y < 8 && this.matrix[x][y] === 1 - this.currentColor) {
          count++;
          temp.push([x, y]);
          x += d[0];
          y += d[1];
        }
        // 如果最后搜到的棋子是与当前棋子同色,则需要翻转中间的所有棋子
        if (x >= 0 && y >= 0 && x < 8 && y < 8 && this.matrix[x][y] === this.currentColor) {
          toFlip.push(...temp);
        }
      }
      // 如果有需要翻转的棋子,则将它们的颜色设置为当前棋子的颜色
      if (toFlip.length > 0) {
        this.matrix[row][col] = this.currentColor;
        for (let [x, y] of toFlip) {
          this.matrix[x][y] = this.currentColor;
        }
        this.currentColor = 1 - this.currentColor;
      }
    },
  },
};
</script>

3.添加游戏结束判断

当棋盘上所有格子都有棋子时,游戏结束。可以通过定义一个 computed 属性,检查棋盘上是否还有空格子来实现。

<template>
  <div class="chessboard">
    <div v-for="(row, i) in matrix" :key="i" class="chessboard-row">
      <div v-for="(col, j) in row" :key="j" class="chessboard-col">
        <div :class="[col === 0 ? 'white' : col === 1 ? 'black' : '']" @click="clickSquare(i, j)"></div>
      </div>
    </div>
    <div v-if="gameOver" class="game-over">游戏结束</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      matrix: [
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, 0, 1, null, null, null],
        [null, null, null, 1, 0, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
        [null, null, null, null, null, null, null, null],
      ],
      currentColor: 1,
    };
  },
  computed: {
    gameOver() {
      for (let row of this.matrix) {
        if (row.indexOf(null) !== -1) {
          return false;
        }
      }
      return true;
    },
  },
  methods: {
    clickSquare(row, col) {
      // 如果该格子已有棋子,则不能下棋
      if (this.matrix[row][col] !== null) return;

      const directions = [
        [0, 1],
        [0, -1],
        [1, 0],
        [-1, 0],
        [1, 1],
        [1, -1],
        [-1, 1],
        [-1, -1],
      ];
      const toFlip = [];
      // 搜索与该棋子直接相邻的八个方向
      for (let d of directions) {
        let x = row + d[0];
        let y = col + d[1];
        let count = 0;
        let temp = [];
        // 如果在该方向上出现了同色棋子,则继续朝该方向搜索,直到搜索到不同色棋子或边界
        while (x >= 0 && y >= 0 && x < 8 && y < 8 && this.matrix[x][y] === 1 - this.currentColor) {
          count++;
          temp.push([x, y]);
          x += d[0];
          y += d[1];
        }
        // 如果最后搜到的棋子是与当前棋子同色,则需要翻转中间的所有棋子
        if (x >= 0 && y >= 0 && x < 8 && y < 8 && this.matrix[x][y] === this.currentColor) {
          toFlip.push(...temp);
        }
      }
      // 如果有需要翻转的棋子,则将它们的颜色设置为当前棋子的颜色
      if (toFlip.length > 0) {
        this.matrix[row][col] = this.currentColor;
        for (let [x, y] of toFlip) {
          this.matrix[x][y] = this.currentColor;
        }
        this.currentColor = 1 - this.currentColor;
      }
    },
  },
};
</script>

<style scoped>
.chessboard {
  width: 400px;
  height: 400px;
  border: 1px solid black;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.chessboard-row {
  display: flex;
}

.chessboard-col {
  width: 50px;
  height: 50px;
}

.chessboard-col > div {
  width: 100%;
  height: 100%;
  border-radius: 25px;
  background-color: white;
}

.white {
  background-color: white;
}

.black {
  background-color: black;
}

.game-over {
  font-size: 24px;
  margin-top: 20px;
  color: red;
}
</style>

以上代码仅供参考,具体实现细节和样式可以根据需求自行调整。


源码获取方法:

需要完整源码的朋友,希望你能点赞+收藏+评论,然后私信我即可~

会员学习群:【一对一答疑】

如果教程中有不懂的地方,可添加学习会员小助手咨询(微信:mifankeji77)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值