肖强的博客 肖强的博客
Home
Guide
Web Document
  • Plugins
  • Case
  • Animation
Components
  • Categories
  • Tags
  • Archives
Website Tools

xiaoQiang

因为爱所以爱
Home
Guide
Web Document
  • Plugins
  • Case
  • Animation
Components
  • Categories
  • Tags
  • Archives
Website Tools
  • 案例
    • Gluttonous Snake
    • Verification Code
    • Star sky
    • gobang
    • drawing
    • china map
  • views
xiaoQiang
2021-09-30

gobang

gobang

五子棋

<template>
  <div>
    <button @click="empty">重玩</button>
    <canvas
      ref="gobangCanvas"
      width="600"
      height="600"
      @click="render"
    ></canvas>
  </div>
</template>

<script>
export default {
  name: 'gobang',

  data() {
    return {
      arr: [],
      mrow: 15, //棋盘行数
      mcol: 15, //棋盘列数
      len: 40, //棋盘的每个小格的宽高
      chessXY: 36, //棋子的大小
      boo: true, // 控制黑白棋的切换
      // black: new Image(),
      // white: new Image(),
      black: null,
      white: null,
      canvas: null,
      ctx: null,
      left: 0, // 棋盘距离页面左侧的距离
      top: 0, // 棋盘距离页面顶部的距离
    }
  },

  mounted() {
    this.init()
    this.offset(this.canvas)
    window.addEventListener('resize', () => {
      if (this.canvas) {
        this.left = 0
        this.top = 0
        this.offset(this.canvas)
      }
    })
  },

  methods: {
    offset(ele) {
      if (ele) {
        if (ele.offsetParent === document.body) {
          this.left += ele.offsetLeft
          this.top += ele.offsetTop
        } else {
          this.left += ele.offsetLeft
          this.top += ele.offsetTop
          this.offset(ele.offsetParent)
        }
      }
    },
    init() {
      this.canvas = this.$refs.gobangCanvas
      this.ctx = this.canvas.getContext('2d')
      this.black = document.createElement('img')
      this.white = document.createElement('img')
      this.black.src = 'http://yaru.vip:8080/images/icon/black.png'
      this.white.src = 'http://yaru.vip:8080/images/icon/white.png'
      for (let i = 0; i <= this.mrow; i++) {
        this.arr[i] = new Array()
        for (let j = 0; j <= this.mcol; j++) {
          //让数组内所有的初始值都为零
          this.arr[i][j] = 0
        }
      }
      //构建棋盘
      this.ctx.strokeStyle = '#fff' //棋盘线的颜色
      for (let i = 0; i <= this.mrow; i++) {
        for (let j = 0; j <= this.mcol; j++) {
          this.ctx.strokeRect(i * this.len, j * this.len, this.len, this.len)
        }
      }
    },
    render(event) {
      let cliX = event.pageX - this.left
      let cliY = event.pageY - this.top
      // /*console.log(cliX,cliY);*/
      //转换成坐标
      let x = Math.round(cliX / this.len)
      let y = Math.round(cliY / this.len)
      // console.log(x, y)

      if (this.arr[x][y] != 0) {
        alert('你压到我了')
        return
      }

      if (this.boo) {
        // console.log(this.ctx)
        this.ctx.drawImage(
          this.black,
          x * this.len - this.len / 2,
          y * this.len - this.len / 2,
          this.chessXY,
          this.chessXY,
        ) //把黑子放到棋盘上
        this.arr[x][y] = 1 //代表黑子
        this.boo = false //切换白子
        this.estimate(1, x, y)
      } else {
        this.ctx.drawImage(
          this.white,
          x * this.len - this.len / 2,
          y * this.len - this.len / 2,
          this.chessXY,
          this.chessXY,
        ) //把白子放到棋盘上
        this.arr[x][y] = 2 //代表白子
        this.boo = true //切换黑子
        this.estimate(2, x, y)
      }
    },
    estimate(target, row, col) {
      //保存一份传进来的行列坐标
      let myRow = row
      let myCol = col
      let num = 1 //存储相同棋子的数量

      //水平方向判断
      while (row - 1 >= 0 && this.arr[row - 1][col] == target) {
        num++
        row--
      }
      row = myRow
      col = myCol
      while (row + 1 <= this.mrow && this.arr[row + 1][col] == target) {
        row++
        num++
      }
      this.ying(num, target, '水平方向五子连珠')

      //垂直方向判断
      row = myRow //回归初始值
      col = myCol
      num = 1

      while (col - 1 >= 0 && this.arr[row][col - 1] == target) {
        col--
        num++
      }
      row = myRow
      col = myCol
      while (col + 1 <= this.mcol && this.arr[row][col + 1] == target) {
        col++
        num++
      }
      this.ying(num, target, '垂直方向五子连珠')

      //左下,右上判断
      row = myRow //回归初始值
      col = myCol
      num = 1
      while (
        row - 1 >= 0 &&
        col + 1 <= this.mcol &&
        this.arr[row - 1][col + 1] == target
      ) {
        row--
        col++
        num++
      }
      row = myRow
      col = myCol
      while (
        row + 1 <= this.mrow &&
        col - 1 >= 0 &&
        this.arr[row + 1][col - 1] == target
      ) {
        row++
        col--
        num++
      }
      this.ying(num, target, '左下右上五子连珠')

      //左上,右下判断
      row = myRow //回归初始值
      col = myCol
      num = 1
      while (
        row - 1 >= 0 &&
        col - 1 >= 0 &&
        this.arr[row - 1][col - 1] == target
      ) {
        row--
        col--
        num++
      }
      row = myRow
      col = myCol
      while (
        row + 1 <= this.mrow &&
        col + 1 <= this.mcol &&
        this.arr[row + 1][col + 1] == target
      ) {
        row++
        col++
        num++
      }
      this.ying(num, target, '左上右下五子连珠')
    },
    ying(num, target, str) {
      if (num >= 5) {
        if (target == 1) {
          alert('恭喜黑方获得胜利' + ' ' + str)
          return
        } else {
          alert('恭喜白方获得胜利' + ' ' + str)
          return
        }
      }
    },
    empty() {
      this.ctx.clearRect(0, 0, 600, 600) //清空画布
      //清除数组
      for (let i = 0; i <= this.mrow; i++) {
        for (let j = 0; j <= this.mcol; j++) {
          //让数组内所有的初始值都为零
          this.arr[i][j] = 0
        }
      }
      //重新绘制棋盘
      this.ctx.strokeStyle = '#fff' //棋盘线的颜色
      for (let i = 0; i <= this.mrow; i++) {
        for (let j = 0; j <= this.mcol; j++) {
          this.ctx.strokeRect(i * this.len, j * this.len, this.len, this.len)
        }
      }
    },
  },
}
</script>

<style lang="less" scoped>
canvas {
  background-color: sandybrown;
  border: 1px solid #ccc;
}
button {
  width: 50px;
  height: 50px;
  outline: none;
  border: none;
  background-color: orange;
  color: white;
  font-size: 16px;
  border-radius: 50%;
  cursor: pointer;
  font-weight: 900;
  vertical-align: top;
}
</style>
#case
上次更新: 2021-10-10 23:28:19
Star sky
drawing

← Star sky drawing →

最近更新
01
drag
12-22
02
入场/出场05
10-16
03
入场/出场04
10-16
更多文章>
icon组件不能用
时间左侧 © 2021-2021 时间右侧
冀公网安备 13108202000744号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
欢迎来到我的家
Back