简易版五子棋游戏--canvas、前端三件套

目录

简介 

棋盘介绍

一、棋盘介绍

二、下棋过程

三、功能设计

canvas获取画布

画棋盘

设计棋子、并进行美化

判断棋子是否有五个相同的棋子连成一条直线

运行效果图

完整代码


简介 

  根据自身学习使用前端三件套以及canvas做一个简易版五子棋,该实现了简单的判断五个颜色相同的棋子是否连成一条直线的功能,唯一不足的是未实现人机交互只实现了人人交互,因为不想使用随机算法进行,等后期会继续完善

棋盘介绍

一、棋盘介绍

棋盘采用了15 * 15,共有225个交叉点

棋子采用了黑白两棋

二、下棋过程

绘制棋盘,棋子

执黑子先落子,然后双方轮流落子

判断胜负

三、功能设计
canvas获取画布
  <canvas id = 'c1' width = '800' height='800'></canvas>
  /** @type {HTMLCanvasElement} */
    //1.找到画布
    var c1 = document.getElementById('c1')
    //位置:x,y,宽度,高度

    //获取tip元素
    let tip = document.querySelector('.tip')
    
    //2.获取画笔,上下文对象
    var ctx = c1.getContext("2d")
   
画棋盘
 //画棋盘
    for(let i=1;i<16;i++)
  {
    //横线
    ctx.moveTo(50,50*i)
    ctx.lineTo(750,50*i)
    ctx.stroke()
    //纵线
    ctx.moveTo(50*i,50)
    ctx.lineTo(50*i,750) 
    ctx.stroke()
  }
设计棋子、并进行美化
 //根据当前是那种棋子,给不同的颜色
   // ctx.fillStyle = isblack ? '#000' : '#fff'
    remb[m][n]  = isblack ? 'black' : 'white'

   let tx = isblack ? x - 10 : x + 10
   let ty = isblack ? y - 10 : y + 10
   const g = ctx.createRadialGradient(tx,ty,0,tx,ty,30)
   g.addColorStop(0,isblack ? '#ccc' : '#666')
   g.addColorStop(1,isblack ? '#000' : '#fff')
   ctx.fillStyle = g


   //美化棋子  增加其中的立体感
    ctx.shadowBlur = 4
    ctx.shadowColor = '#000'
    ctx.shadowOffsetX = 4
    ctx.shadowOffsetY = 4

    ctx.fill()
    ctx.closePath()

美化主要是给棋子增加立体感

判断棋子是否有五个相同的棋子连成一条直线
//纵向
  function check(row,col){
    //定义一个变量,记录向上的次数
    let up = 0

    //定义一个变量,记录向下的次数
    let down = 0
    let counts = 1  //记录目标棋子出现的次数
    let times  = 0
    while(times < 10000){  //防止出现死循环
      let target  = isblack ? 'black' : 'white'
      times++
      up++
     //判断纵向
      if(remb[row][col-up]&&remb[row][col-up] == target){
        counts++
      }
      down++
      if(remb[row][col+down]&&remb[row][col+down] == target){
        counts++
      }

      // 判断棋子是否有五个成一条直线或者有断的不同色
       if(counts >= 5 || remb[row][col-up] !== target && remb[row][col+down] !== target)
       {
        break
       }
    }
     return (counts >= 5)
  }
  //检查横向是否有五个连成一条直线
  function checkH(row,col){
    let count = 1
    let times1 = 0
    let left = 0
    let right = 0
    while(times1 < 10000){
      times1++
      let target1 = isblack ? 'black' : 'white'
      left++
      if(remb[row - left][col]&&remb[row - left][col] == target1){
        count++
      }
      right++
      if(remb[row + right][col]&&remb[row + right][col] == target1){
        count++
      }
        
       if(count >= 5 || remb[row-left][col] !== target1 && remb[row + right][col] !== target1){
      break
    }
    }
   return (count >= 5)
  }


  //检查从左上到右下是否有五个成一条直线
  function checkZsYx(row,col){
    let count = 1
    let times = 0
    let zs = 0
    let yx = 0
    while(times < 10000){
      times++
      let target = isblack ? 'black' : 'white'
      zs++
      if(remb[row - zs][col - zs]&& remb[row - zs][col - zs] == target){
        count++
      }
      yx++
      if(remb[row + yx][col + yx]&& remb[row + yx][col + yx]){
        count++
      }
      if(count >= 5 || remb[row - zs][col - zs] !== target && remb[row + yx][col + yx] !== target){
        break
      }
    }
    return (count >= 5)
  }


  //检查从右上到左下是否有五个连成一条直线
  function checkYsZx(row,col){
    let count = 1
    let times = 1
    let ys = 0
    let zx = 0
    while(times < 10000){
      times ++
      let target = isblack ? 'black' : 'white'
      ys++
      if(remb[row + ys][col - ys]&&remb[row + ys][col - ys] == target){
        count++
      }
      zx++
      if(remb[row - zx][col + zx]&&remb[row-zx][row + zx] == target){
        count++
      }
      if(count >= 5 || remb[row + ys][col - ys] !== target && remb[row - zx][col + zx] !== target){
        break
      }
    }
    return (count >= 5)
  }
运行效果图

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    canvas{
      background-color: darkgoldenrod;
      display: block;
      margin:0 auto;
    }
    .tip{
      text-align: center;
      padding:20px;
    }
  </style>
</head>
<body>
  <div class="tip">请黑棋落子</div>
  <canvas id = 'c1' width = '800' height='800'></canvas>
  <script>
     /** @type {HTMLCanvasElement} */
    //1.找到画布
    var c1 = document.getElementById('c1')
    //位置:x,y,宽度,高度

    //获取tip元素
    let tip = document.querySelector('.tip')
    
    //2.获取画笔,上下文对象
    var ctx = c1.getContext("2d")
   

    //画棋盘
    for(let i=1;i<16;i++)
  {
    //横线
    ctx.moveTo(50,50*i)
    ctx.lineTo(750,50*i)
    ctx.stroke()
    //纵线
    ctx.moveTo(50*i,50)
    ctx.lineTo(50*i,750) 
    ctx.stroke()
  }
  let isblack = true
  let remb = []
  for(let i = 1;i < 16; i++){
    remb[i] = []
  }

  let endGame = false
  c1.addEventListener('click',e=>{
    let {offsetX : x,offsetY : y} = e

    if(x < 25 || y < 25|| x > 775||y > 775){
      return
    }
    let m = Math.floor((x + 25) / 50)
    let n = Math.floor((y + 25) / 50)
    x = m * 50
    y = n * 50
    if(endGame){
      //当有五个相同的棋子连城一条线,则返回,click事件无效
      return
    }
    ctx.beginPath()
    ctx.arc(x,y,20,0,2 * Math.PI)
    //判断当前位置是否存在棋子
    if(remb[m][n]){
      tip.innerHTML = `不能重复落子,当前是${isblack ? '黑子' : '白子'}落棋`
      return 
    }

    //根据当前是那种棋子,给不同的颜色
   // ctx.fillStyle = isblack ? '#000' : '#fff'
    remb[m][n]  = isblack ? 'black' : 'white'

   let tx = isblack ? x - 10 : x + 10
   let ty = isblack ? y - 10 : y + 10
   const g = ctx.createRadialGradient(tx,ty,0,tx,ty,30)
   g.addColorStop(0,isblack ? '#ccc' : '#666')
   g.addColorStop(1,isblack ? '#000' : '#fff')
   ctx.fillStyle = g


   //美化棋子  增加其中的立体感
    ctx.shadowBlur = 4
    ctx.shadowColor = '#000'
    ctx.shadowOffsetX = 4
    ctx.shadowOffsetY = 4

    ctx.fill()
    ctx.closePath()

    //判断是否已经有5个棋子连成一条线
    endGame = check(m,n) || checkH(m,n) || checkZsYx(m,n) || checkYsZx(m,n)
    if(endGame){
      tip.innerText = `${isblack ? '黑' : '白'}子已获胜,请刷新重新开始`
      return
    }
    isblack = !isblack
    //提醒用户落棋
    tip.innerHTML = isblack ? '请黑棋落子' : '请白棋落子'
  })

  //纵向
  function check(row,col){
    //定义一个变量,记录向上的次数
    let up = 0

    //定义一个变量,记录向下的次数
    let down = 0
    let counts = 1  //记录目标棋子出现的次数
    let times  = 0
    while(times < 10000){  //防止出现死循环
      let target  = isblack ? 'black' : 'white'
      times++
      up++
     //判断纵向
      if(remb[row][col-up]&&remb[row][col-up] == target){
        counts++
      }
      down++
      if(remb[row][col+down]&&remb[row][col+down] == target){
        counts++
      }

      // 判断棋子是否有五个成一条直线或者有断的不同色
       if(counts >= 5 || remb[row][col-up] !== target && remb[row][col+down] !== target)
       {
        break
       }
    }
     return (counts >= 5)
  }
  //检查横向是否有五个连成一条直线
  function checkH(row,col){
    let count = 1
    let times1 = 0
    let left = 0
    let right = 0
    while(times1 < 10000){
      times1++
      let target1 = isblack ? 'black' : 'white'
      left++
      if(remb[row - left][col]&&remb[row - left][col] == target1){
        count++
      }
      right++
      if(remb[row + right][col]&&remb[row + right][col] == target1){
        count++
      }
        
       if(count >= 5 || remb[row-left][col] !== target1 && remb[row + right][col] !== target1){
      break
    }
    }
   return (count >= 5)
  }


  //检查从左上到右下是否有五个成一条直线
  function checkZsYx(row,col){
    let count = 1
    let times = 0
    let zs = 0
    let yx = 0
    while(times < 10000){
      times++
      let target = isblack ? 'black' : 'white'
      zs++
      if(remb[row - zs][col - zs]&& remb[row - zs][col - zs] == target){
        count++
      }
      yx++
      if(remb[row + yx][col + yx]&& remb[row + yx][col + yx]){
        count++
      }
      if(count >= 5 || remb[row - zs][col - zs] !== target && remb[row + yx][col + yx] !== target){
        break
      }
    }
    return (count >= 5)
  }


  //检查从右上到左下是否有五个连成一条直线
  function checkYsZx(row,col){
    let count = 1
    let times = 1
    let ys = 0
    let zx = 0
    while(times < 10000){
      times ++
      let target = isblack ? 'black' : 'white'
      ys++
      if(remb[row + ys][col - ys]&&remb[row + ys][col - ys] == target){
        count++
      }
      zx++
      if(remb[row - zx][col + zx]&&remb[row-zx][row + zx] == target){
        count++
      }
      if(count >= 5 || remb[row + ys][col - ys] !== target && remb[row - zx][col + zx] !== target){
        break
      }
    }
    return (count >= 5)
  }
  </script>
</body>
</html>

友友们直接可以将代码复制到VScode中直接编译运行
过几天我会将完善之后的代码发出来,希望友友们指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值