参考教学视频:
Canvas画布案例--五子棋(1)基础_哔哩哔哩_bilibili
1.棋盘设计,落子功能
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>五子棋</title>
<style>
#map{
background-color: saddlebrown;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="map" height="800" width="800"></canvas>
<script>
//画棋盘
/** @type {HTMLCanvasElement} */
var mapcanv = document.getElementById("map");
var ctx = mapcanv.getContext("2d");
for(let i=1;i<16;i++){
ctx.beginPath();
ctx.moveTo(50*i,50);
ctx.lineTo(50*i,750);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50,50*i);
ctx.lineTo(750,50*i);
ctx.stroke();
}
//棋子信息
var chessinfo=[{'name':'黑子','color':'black'},{'name':'白子','color':'white'}];
var chessrec = [];
let chess=0;
//画棋子
function setChess(x,y,c){
ctx.save();
ctx.beginPath();
ctx.fillStyle=c;
ctx.arc(x,y,25,0,2*Math.PI);
ctx.fill();
ctx.restore();
}
//点击事件监听
mapcanv.addEventListener('click',function(ev){
let x=Math.round(ev.offsetX/50);
let y=Math.round(ev.offsetY/50);
let pos=x+'-'+y;
if(x*y>0&&x<16&&y<16&&!chessrec.includes(pos)){
setChess(x*50,y*50,chessinfo[chess].color);
chess^=1;
chessrec.push(pos);
console.log(chessrec);
}
})
</script>
</body>
</html>
2.胜负判断
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>五子棋</title>
<style>
#map{
background-color: saddlebrown;
border-radius: 10px;
}
</style>
</head>
<body>
<canvas id="map" height="800" width="800"></canvas>
<script>
//画棋盘
/** @type {HTMLCanvasElement} */
var mapcanv = document.getElementById("map");
var ctx = mapcanv.getContext("2d");
for(let i=1;i<16;i++){
ctx.beginPath();
ctx.moveTo(50*i,50);
ctx.lineTo(50*i,750);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(50,50*i);
ctx.lineTo(750,50*i);
ctx.stroke();
}
//棋子信息
var chessinfo=[{'name':'黑子','color':'black'},{'name':'白子','color':'white'}];
var chessrec = [];
let chess=0;
//画棋子
function setChess(x,y,c){
ctx.save();
ctx.beginPath();
ctx.fillStyle=c;
ctx.arc(x,y,25,0,2*Math.PI);
ctx.fill();
ctx.restore();
}
//点击事件监听
mapcanv.addEventListener('click',function(ev){
let x=Math.round(ev.offsetX/50);
let y=Math.round(ev.offsetY/50);
let pos=x+'-'+y;
if(x*y>0&&x<16&&y<16&&!chessrec.includes(pos)){
setChess(x*50,y*50,chessinfo[chess].color);
chessrec.push(pos);
if(chessrec.length>=9)
checkover(x,y,chess);
chess^=1;
}
})
function checkover(x,y,ch){
let chs=chessrec.filter((n,i)=>i%2==ch);
let win=judgewin_5(x,y).some(arr=>arr.every(n=>chs.includes(n)))
if(win){
setTimeout(()=>{
alert(`恭喜${chessinfo[ch].name}获胜`,100);
location.reload();
})
}
}
function judgewin_9(x,y){
var wins=[[],[],[],[]];
for(let i=-4;i<=4;i++){
let hx=(x+i)>0&&(x+i)<16,
zx=(y+i)>0&&(y+i)<16,
zxzx=(y-i)<16&&(y-i)>0
//横向9子,注意${}中为反单引号,用于字符串拼接
if(hx) wins[0].push(`${x+i}-${y}`);
//纵向9子
if(zx) wins[1].push(`${x}-${y+i}`);
//左上右下
if(hx&&zx) wins[2].push(`${x+i}-${y+i}`);
//右上左下
if(hx&&zxzx) wins[3].push(`${x+i}-${y-i}`);
}
return wins.filter(arr=>arr.length>=5);
}
function judgewin_5(x,y){
var wins=[];
judgewin_9(x,y).forEach(arr=>{
for(let i=0;i<arr.length-4;i++){
wins.push(arr.slice(i,i+5));
}
})
return wins;
}
</script>
</body>
</html>