canvas绘制五子棋

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        canvas{
          background-color: red;
          /*把canvas变成块级元素 就可以使用margin移动位置了 */
          display: block; 
          margin: 0 auto;
        }
        .tip{
            text-align: center;
            padding: 20px;
        }

    </style>
    <div class="tip">
           请黑子落子 
    </div>
</head>
<body>
    <script>
        //创建canvas
        var canvas=document.createElement('canvas')
        //设置宽高
        canvas.width=600;
        canvas.height=600;
        //把标签放入body
        document.body.append(canvas)
        //创建画笔
        var context=canvas.getContext('2d');
        //设置每个格子
        for (let index = 1; index <=11; index++) {
            //设置横线
            //设置起点
            context.moveTo(50,50*index);
            //移动位置 下右移动
            context.lineTo(550,50*index)
            //设置画线
            context.stroke();

            //设置垂直线
            //设置起点
            context.moveTo(50*index,50);
            //移动位置 右下移动
            context.lineTo(50*index,550)
            //设置画线
            context.stroke();
        }

        //true 黑子 ,false 白子
        var flag=true;
        //创建二维数组 保存棋子
        var qizi=[[]];
        for (let i = 0; i <=11; i++) {
            qizi[i]=[];
        }
       

        //点击棋盘 显示棋子
        canvas.addEventListener('click',e=>{
            //获取坐标距离父级的偏移量
            let {offsetX,offsetY}=e;
            //边界判断 不能点击格子外面的范围
            if(offsetX<25 || offsetY<25 || offsetX>550 || offsetY>550){
                return;    
            }
            //向下取整数 在*50 就会显示在十字中心的位置
            //x y加25就是防止偏移 加一半的位置
            let i=Math.floor((offsetX+25)/50);
            let j=Math.floor((offsetY+25)/50);
            let x=i*50;
            let y=j*50;
            
            if(qizi[i][j]){
                alert('当前位置已经有棋子了')
                return;
            }
            //绘制颜色
            if(flag){
                context.fillStyle='#000';
                qizi[i][j]='hei';
            }else{
                context.fillStyle='#fff';
                qizi[i][j]='bai';
            }
            
           


            //画圆 360弧度就是一个圆 弧度=度*π/180
            //防止连线 开始路径
            context.beginPath();
            context.arc(x,y,20,0,2*Math.PI)

      
            //绘制连线 填满 背景黑色
            context.fill();
            //防止连线 关闭路径
            context.closePath();


            //校验横线
            let hengXian=checkHengXian(i,j,qizi[i][j]);
            //校验垂直线
            let chuiZhiXian=checkChuiZhiXian(i,j,qizi[i][j]);
            //校验左斜线
            let zuoXieXian=checkZuo(i,j,qizi[i][j]);
            //校验右斜线
            let youXieXian=checkYou(i,j,qizi[i][j]);

            if(hengXian || chuiZhiXian || zuoXieXian || youXieXian){
                alert('胜利了,请重新开始')
                window.location.reload();
                return;
            }

            //点击完毕后 状态切换
            flag=!flag;
            //获取class
            var tip=document.querySelector(".tip");
            //更改html的内容
            if(flag){
                tip.innerText='请黑子落子'
            }else{
                tip.innerText='请白子落子'
            }
        })
       

        //校验横线是否连城5子
        function checkHengXian(x,y,name){
            //y轴不动,x轴 左右移动 当前落子为1个
            let zuo=0;
            let you=0;
            //查询左边能连几颗棋子
            for (let i = 1; i < 5; i++) {
                if(x>0 && qizi[x-i][y] && qizi[x-i][y]==name){
                    zuo++;    
                }else{
                    break;
                }
            }
            //查询右边能连几颗棋子
            for (let i = 1; i < 5; i++) {
               
                if(x<11 && qizi[x+i][y] && qizi[x+i][y]==name){
                    you++;    
                }else{
                    break;
                }
            }
            return zuo+you+1>=5;
        }

        
        //校验垂直线是否连城5子
        function checkChuiZhiXian(x,y,name){
                
                //x轴不动,y轴 上下移动 当前落子为1个
                let shang=0;
                let xia=0;
                //查询上边能连几颗棋子
                for (let i = 1; i < 5; i++) {
                    if(y>0 && qizi[x][y-i] && qizi[x][y-i]==name){
                        shang++;    
                    }else{
                        break;
                    }
                }
                //查询下边能连几颗棋子
                for (let i = 1; i < 5; i++) {
                   
                    if(y<11 && qizi[x][y+i] && qizi[x][y+i]==name){
                        xia++;    
                    }else{
                        break;
                    }
                }
                return shang+xia+1>=5;
            }


            
        //校验左斜线是否连城5子
        function checkZuo(x,y,name){
                //x轴向左 右,y轴  上下移动 当前落子为1个
                let a=0;
                let b=0;
                //查询上边能连几颗棋子
                for (let i = 1; i < 5; i++) {
                    if(x >0 && y>0 && qizi[x-i][y-i] && qizi[x-i][y-i]==name){
                        a++;    
                    }else{
                        break;
                    }
                }
                //查询下边能连几颗棋子
                for (let i = 1; i < 5; i++) {
                   
                    if(x >0 && y>0 && x +i <=11 && y +i <=11 && qizi[x+i][y+i] && qizi[x+i][y+i]==name){
                        b++;    
                    }else{
                        break;
                    }
                }
                return a+b+1>=5;
            }

            //校验右斜线是否连城5子
        function checkYou(x,y,name){
            
                //x轴向左 右,y轴  上下移动 当前落子为1个
                let a=0;
                let b=0;
                //查询上边能连几颗棋子
                for (let i = 1; i < 5; i++) {
                    if(x >0 && y>0 && x+i<=11 && y<11 && qizi[x+i][y-i] && qizi[x+i][y-i]==name){
                        a++;    
                    }else{
                        break;
                    }
                }
                //查询下边能连几颗棋子
                for (let i = 1; i < 5; i++) {
                   
                    if(x >0 && y>0 && x<11 && y+i<=11 && qizi[x-i][y+i] && qizi[x-i][y+i]==name){
                        b++;    
                    }else{
                        break;
                    }
                }
                return a+b+1>=5;
            }
    </script>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值