用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)