基于React 实现井字棋

一、简介

这篇文章会基于React 实现井字棋小游戏功能。

二、效果演示

三、技术实现

javascript 复制代码
import {useEffect, useState} from "react";

export default (props) => {
  return <Board/>
}


const Board = () => {
  let initialState = [['', '', ''], ['', '', ''], ['', '', '']];
  const [squares, setSquares] = useState(initialState);
  const [times, setTimes] = useState(0);
  useEffect(()=>{
      // 判断每行是否相同
      for (let i = 0; i < 3; i++) {
        if (squares[i][0] === squares[i][1] && squares[i][1] === squares[i][2] && squares[i][0] !== '') {
          alert(squares[i][0] + ' win');
          setTimes(0)
          setSquares(initialState)
          return;
        }
      }
      // 判断每列是否相同
      for (let i = 0; i < 3; i++) {
        if (squares[0][i] === squares[1][i] && squares[1][i] === squares[2][i] && squares[0][i] !== '') {
          alert(squares[0][i] + ' win')
          setTimes(0)
          setSquares(initialState)
          return;
        }
      }
      // 判断对角线是否相同
      if (squares[0][0] === squares[1][1] && squares[1][1] === squares[2][2] && squares[0][0] !== '') {
        alert(squares[0][0] + ' win');
        setTimes(0)
        setSquares(initialState)
        return;
      }
      if (squares[0][2] === squares[1][1] && squares[1][1] === squares[2][0] && squares[0][2] !== ''){
        alert(squares[0][2] + ' win');
        setTimes(0)
        setSquares(initialState)
        return;
      }


  },[times])
  return <div style={{width:'130px', margin: '0 auto'}}>
    <table style={{borderCollapse: 'collapse'}}>
      {squares.map((row, rowIdx) => {
        return <tr key={rowIdx}>
          {
            row.map((col, colIdx) => {
                return <td key={rowIdx + '-' + colIdx} style={{border: '1px solid #000', width: '40px', height: '40px'}}>
                  <div style={{width: '40px', height: '40px', textAlign: 'center', lineHeight:'40px'}} onClick={
                    () => {
                      const newSquares = [...squares];
                      if (newSquares[rowIdx][colIdx] !== '') {
                          return;
                      }
                      newSquares[rowIdx][colIdx] = times % 2 === 0 ? 'X' : 'O';
                      setSquares(newSquares);
                      setTimes(times + 1);

                    }
                  }>{col}</div>
                </td>
              }
            )
          }
        </tr>
      })}

    </table>
  </div>
}

1.布局

基于table实现,3行,3列。

2.表格元素点击

更新cell内容,更新次数。

javascript 复制代码
     const newSquares = [...squares];
     if (newSquares[rowIdx][colIdx] !== '') {
         return;
     }
     newSquares[rowIdx][colIdx] = times % 2 === 0 ? 'X' : 'O';
     setSquares(newSquares);
     setTimes(times + 1);

3.判断游戏是否结束

判断每行,每列,斜线是否相等。

javascript 复制代码
 useEffect(()=>{
      // 判断每行是否相同
      for (let i = 0; i < 3; i++) {
        if (squares[i][0] === squares[i][1] && squares[i][1] === squares[i][2] && squares[i][0] !== '') {
          alert(squares[i][0] + ' win');
          setTimes(0)
          setSquares(initialState)
          return;
        }
      }
      // 判断每列是否相同
      for (let i = 0; i < 3; i++) {
        if (squares[0][i] === squares[1][i] && squares[1][i] === squares[2][i] && squares[0][i] !== '') {
          alert(squares[0][i] + ' win')
          setTimes(0)
          setSquares(initialState)
          return;
        }
      }
      // 判断对角线是否相同
      if (squares[0][0] === squares[1][1] && squares[1][1] === squares[2][2] && squares[0][0] !== '') {
        alert(squares[0][0] + ' win');
        setTimes(0)
        setSquares(initialState)
        return;
      }
      if (squares[0][2] === squares[1][1] && squares[1][1] === squares[2][0] && squares[0][2] !== ''){
        alert(squares[0][2] + ' win');
        setTimes(0)
        setSquares(initialState)
        return;
      }


  },[times])
相关推荐
haogexiaole2 小时前
vue知识点总结
前端·javascript·vue.js
哆啦A梦15884 小时前
[前台小程序] 01 项目初始化
前端·vue.js·uni-app
小周同学@6 小时前
谈谈对this的理解
开发语言·前端·javascript
Wiktok6 小时前
Pyside6加载本地html文件并实现与Javascript进行通信
前端·javascript·html·pyside6
一只小风华~6 小时前
Vue:条件渲染 (Conditional Rendering)
前端·javascript·vue.js·typescript·前端框架
柯南二号6 小时前
【大前端】前端生成二维码
前端·二维码
程序员码歌7 小时前
明年35岁了,如何破局?说说心里话
android·前端·后端
博客zhu虎康7 小时前
React Hooks 报错?一招解决useState问题
前端·javascript·react.js
灰海8 小时前
vue中通过heatmap.js实现热力图(多个热力点)热区展示(带鼠标移入弹窗)
前端·javascript·vue.js·heatmap·heatmapjs
王源骏8 小时前
LayaAir鼠标(手指)控制相机旋转,限制角度
前端