趁着休息,花了1小时参考网上各类简单的写了个五子棋,主要实现功能,未进行任何优化

修改画布大小及棋子布局

<template>
    <div class="board">
        <canvas id="board" width="600" height="600"></canvas>
    </div>
</template>

CSS相应如下

.board {
    border: 1px solid red;
    width: 630px;
    height: 630px;
    padding: 0 0;
    margin: 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
}

1、绘制棋盘,以30为一格,考虑棋子落在交叉点,故在绘制时右移和下移了15,并将数组进行重置(600的棋盘,30一个,共20个)

drawBoard() {
            const canvas = document.getElementById("board");
            const ctx = canvas.getContext("2d");

            // 设置线条颜色
            ctx.strokeStyle = "black";

            // 绘制横线
            for (let i = 0; i <= 19; i++) {
                ctx.beginPath();
                ctx.moveTo(15, i * 30 + 15);
                ctx.lineTo(570 + 15, i * 30 + 15);
                ctx.stroke();
            }

            // 绘制竖线
            for (let i = 0; i <= 19; i++) {
                ctx.beginPath();
                ctx.moveTo(i * 30 + 15, 0 + 15);
                ctx.lineTo(i * 30 + 15, 570 + 15);
                ctx.stroke();
            }
            // 重置为0
            for (let i = 0; i <= 19; i++) {
                this.board.push(new Array(20).fill(0))
            }
            // console.log(this.board)
        },

2、绘制棋子,考虑正负15的距离,此处在绘制完成后,进行了正负判断,选手交换

drawCell() {
            let container = document.getElementById("board");
            container.addEventListener("click", this.handleClickAndDraw)
        },
        handleClickAndDraw(event) {
            let x = event.offsetX;
            let y = event.offsetY;
            console.log(x + '   ' + y)
            // 计算棋子落在哪个方格中
            const cellX = Math.floor((event.offsetX) / 30);
            const cellY = Math.floor((event.offsetY) / 30);
            console.log(cellX, cellY)
            // 判断该位置是否有棋子
            if (this.board[cellX][cellY] !== 0) {
                alert("该位置已有棋子")
                return;
            }
            const canvas = document.getElementById("board");
            const ctx = canvas.getContext("2d");
            //画带渐变色的棋子,同心圆形式
            let grd = ctx.createRadialGradient(
                cellX * 30 + 15,
                cellY * 30 + 15,
                2,
                cellX * 30 + 15,
                cellY * 30 + 15,
                10
            )
            grd.addColorStop(0, this.player === 1 ? '#FFFFFF' : '#4C4C4C')
            grd.addColorStop(1, this.player === 1 ? '#DADADA' : '#000000')
            ctx.beginPath()
            ctx.fillStyle = grd
            ctx.arc(
                cellX * 30 + 15,
                cellY * 30 + 15,
                10,
                0,
                2 * Math.PI,
                false
            );
            ctx.fill();
            ctx.closePath();
            this.board[cellX][cellY] = this.player; //将黑白棋信息存储
            this.winner = this.checkWinner(this.board)
            if (this.winner != null) {
                alert(this.winner)
            }
            this.player = this.player === 1 ? 2 : 1
        },

3、正负判断,这个主要采取网上CSDN,并未进行过多加工

checkWinner(board) {
            // 检查横向是否有五子连线
            for (let i = 0; i < 19; i++) {
                let count = 0;
                for (let j = 0; j < 19; j++) {
                    if (board[i][j] === this.player) {
                        count++;
                    } else {
                        count = 0;
                    }

                    if (count >= 5) {
                        return this.player;
                    }
                }
            }

            // 检查纵向是否有五子连线
            for (let j = 0; j < 19; j++) {
                let count = 0;
                for (let i = 0; i < 19; i++) {
                    if (board[i][j] === this.player) {
                        count++;
                    } else {
                        count = 0;
                    }

                    if (count >= 5) {
                        return this.player;
                    }
                }
            }

            // 检查右斜线是否有五子连线
            for (let i = 0; i < 14; i++) {
                for (let j = 0; j < 14; j++) {
                    let count = 0;
                    for (let k = 0; k < 5; k++) {
                        if (board[i + k][j + k] === this.player) {
                            count++;
                        } else {
                            count = 0;
                        }

                        if (count >= 5) {
                            return this.player;
                        }
                    }
                }
            }

            // 检查左斜线是否有五子连线
            for (let i = 0; i < 14; i++) {
                for (let j = 4; j < 19; j++) {
                    let count = 0;
                    for (let k = 0; k < 5; k++) {
                        if (board[i + k][j - k] === this.player) {
                            count++;
                        } else {
                            count = 0;
                        }

                        if (count >= 5) {
                            return this.player;
                        }
                    }
                }
            }

            // 如果没有五子连线,则游戏继续
            return null;
        }

最后,完整代码如下App.vue

<script>
export default {
    data() {
        return {
            board: [],
            player: 1,//1--白棋;2--黑棋
            winner: null
        };
    },
    mounted() {
        this.drawBoard();
        this.drawCell();
    },
    methods: {
        drawBoard() {
            const canvas = document.getElementById("board");
            const ctx = canvas.getContext("2d");

            // 设置线条颜色
            ctx.strokeStyle = "black";

            // 绘制横线
            for (let i = 0; i <= 19; i++) {
                ctx.beginPath();
                ctx.moveTo(15, i * 30 + 15);
                ctx.lineTo(570 + 15, i * 30 + 15);
                ctx.stroke();
            }

            // 绘制竖线
            for (let i = 0; i <= 19; i++) {
                ctx.beginPath();
                ctx.moveTo(i * 30 + 15, 0 + 15);
                ctx.lineTo(i * 30 + 15, 570 + 15);
                ctx.stroke();
            }
            // 重置为0
            for (let i = 0; i <= 19; i++) {
                this.board.push(new Array(20).fill(0))
            }
            // console.log(this.board)
        },
        drawCell() {
            let container = document.getElementById("board");
            container.addEventListener("click", this.handleClickAndDraw)
        },
        handleClickAndDraw(event) {
            let x = event.offsetX;
            let y = event.offsetY;
            console.log(x + '   ' + y)
            // 计算棋子落在哪个方格中
            const cellX = Math.floor((event.offsetX) / 30);
            const cellY = Math.floor((event.offsetY) / 30);
            console.log(cellX, cellY)
            // 判断该位置是否有棋子
            if (this.board[cellX][cellY] !== 0) {
                alert("该位置已有棋子")
                return;
            }
            const canvas = document.getElementById("board");
            const ctx = canvas.getContext("2d");
            //画带渐变色的棋子,同心圆形式
            let grd = ctx.createRadialGradient(
                cellX * 30 + 15,
                cellY * 30 + 15,
                2,
                cellX * 30 + 15,
                cellY * 30 + 15,
                10
            )
            grd.addColorStop(0, this.player === 1 ? '#FFFFFF' : '#4C4C4C')
            grd.addColorStop(1, this.player === 1 ? '#DADADA' : '#000000')
            ctx.beginPath()
            ctx.fillStyle = grd
            ctx.arc(
                cellX * 30 + 15,
                cellY * 30 + 15,
                10,
                0,
                2 * Math.PI,
                false
            );
            ctx.fill();
            ctx.closePath();
            this.board[cellX][cellY] = this.player; //将黑白棋信息存储
            this.winner = this.checkWinner(this.board)
            if (this.winner != null) {
                alert(this.winner)
            }
            this.player = this.player === 1 ? 2 : 1
        },
        checkWinner(board) {
            // 检查横向是否有五子连线
            for (let i = 0; i < 19; i++) {
                let count = 0;
                for (let j = 0; j < 19; j++) {
                    if (board[i][j] === this.player) {
                        count++;
                    } else {
                        count = 0;
                    }

                    if (count >= 5) {
                        return this.player;
                    }
                }
            }

            // 检查纵向是否有五子连线
            for (let j = 0; j < 19; j++) {
                let count = 0;
                for (let i = 0; i < 19; i++) {
                    if (board[i][j] === this.player) {
                        count++;
                    } else {
                        count = 0;
                    }

                    if (count >= 5) {
                        return this.player;
                    }
                }
            }

            // 检查右斜线是否有五子连线
            for (let i = 0; i < 14; i++) {
                for (let j = 0; j < 14; j++) {
                    let count = 0;
                    for (let k = 0; k < 5; k++) {
                        if (board[i + k][j + k] === this.player) {
                            count++;
                        } else {
                            count = 0;
                        }

                        if (count >= 5) {
                            return this.player;
                        }
                    }
                }
            }

            // 检查左斜线是否有五子连线
            for (let i = 0; i < 14; i++) {
                for (let j = 4; j < 19; j++) {
                    let count = 0;
                    for (let k = 0; k < 5; k++) {
                        if (board[i + k][j - k] === this.player) {
                            count++;
                        } else {
                            count = 0;
                        }

                        if (count >= 5) {
                            return this.player;
                        }
                    }
                }
            }

            // 如果没有五子连线,则游戏继续
            return null;
        }
    }
};
</script>

<template>
    <div class="board">
        <canvas id="board" width="600" height="600"></canvas>
    </div>
</template>

<style scoped>
.board {
    border: 1px solid red;
    width: 630px;
    height: 630px;
    padding: 0 0;
    margin: 0 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
</style>

 

效果图

最后修改:2024 年 11 月 29 日
如果觉得我的文章对你有用,请随意赞赏