用 React18 构建Tic-Tac-Toe(井字棋)游戏

下面是一个完整的 Tic-Tac-Toe(井字棋)游戏的实现,用 React 构建。包括核心逻辑和组件分离,支持两人对战。

1. 初始化 React 项目:

bash 复制代码
npx create-react-app tic-tac-toe
cd tic-tac-toe

2.文件结构

scss 复制代码
src/
├── App.js
├── Board.js
├── Square.js
└── index.js

Step 1: Square.js - 单个方块组件

jsx 复制代码
import React from 'react';

const Square = ({ value, onClick }) => {
  return (
    <button 
      className="square" 
      onClick={onClick} 
      style={{
        width: '60px',
        height: '60px',
        fontSize: '24px',
        cursor: 'pointer'
      }}
    >
      {value}
    </button>
  );
};

export default Square;

Step 2: Board.js - 棋盘组件

jsx 复制代码
import React from 'react';
import Square from './Square';

const Board = ({ squares, onClick }) => {
  const renderSquare = (i) => {
    return <Square value={squares[i]} onClick={() => onClick(i)} />;
  };

  return (
    <div style={{
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'center',
      alignItems: 'center',
    }}>
      <div style={{ display: 'flex' }}>
        {renderSquare(0)}{renderSquare(1)}{renderSquare(2)}
      </div>
      <div style={{ display: 'flex' }}>
        {renderSquare(3)}{renderSquare(4)}{renderSquare(5)}
      </div>
      <div style={{ display: 'flex' }}>
        {renderSquare(6)}{renderSquare(7)}{renderSquare(8)}
      </div>
    </div>
  );
};

export default Board;

Step 3: App.js - 游戏逻辑和主组件

jsx 复制代码
import React, { useState } from 'react';
import Board from './Board';


const App = () => {
  const [squares, setSquares] = useState(Array(9).fill(null));
  const [isXNext, setIsXNext] = useState(true);

  const calculateWinner = (squares) => {
    const lines = [
      [0, 1, 2], [3, 4, 5], [6, 7, 8], // Rows
      [0, 3, 6], [1, 4, 7], [2, 5, 8], // Columns
      [0, 4, 8], [2, 4, 6]            // Diagonals
    ];
    for (let [a, b, c] of lines) {
      if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
        return squares[a];
      }
    }
    return null;
  };

  const winner = calculateWinner(squares);
  const handleClick = (i) => {
    if (squares[i] || winner) return; // Ignore if square is already filled or game is won
    const nextSquares = squares.slice();
    nextSquares[i] = isXNext ? 'X' : 'O';
    setSquares(nextSquares);
    setIsXNext(!isXNext);
  };

  const restartGame = () => {
    setSquares(Array(9).fill(null));
    setIsXNext(true);
  };

  const status = winner ? `Winner: ${winner}` : `Next Player: ${isXNext ? 'X' : 'O'}`;

  return (
    <div style={{ textAlign: 'center', marginTop: '50px' }}>
      <h1>Tic-Tac-Toe</h1>
      <Board squares={squares} onClick={handleClick} />
      <h3>{status}</h3>
      <button onClick={restartGame} style={{ padding: '10px 20px', marginTop: '20px' }}>
        Restart
      </button>
    </div>
  );
};

export default App;

Step 4: index.js - 渲染应用

jsx 复制代码
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

3. 启动应用:

bash 复制代码
npm start

打开浏览器,访问 http://localhost:3000 即可运行。如图所示:

希望这些内容对你有所帮助!如果有任何问题,欢迎随时提问。

相关推荐
xcs194055 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
小宋102110 小时前
A2UI从零实战:Agent安全生成交互界面与事件回传
javascript·人工智能·安全·交互
大包子10 小时前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js
神仙别闹11 小时前
基于C++实现的贪吃蛇游戏平台
java·c++·游戏
lerhxx11 小时前
AI 应用中的上下文管理 —— 从"上下文窗口"到"分层压缩"的工程实践
前端·javascript
Mahut11 小时前
我在 Mac 上做了个本地剪辑器
javascript·架构·产品
汉堡大王952711 小时前
GPT-6 上线 48 小时,我扒开了 Intelligent UI 的运行机制:DIL、沙箱 Worker 和一个 React 式协调器
前端·javascript·后端
hai_android12 小时前
Chat 聊天模块功能总结
前端·javascript·vue.js
创世虚拟世界12 小时前
我做了一个 3D 虚拟世界基底,基于这个再做 3D 虚拟世界或者元宇宙,会事半功倍
javascript·人工智能·3d·gitee·虚拟现实
阿狗童鞋12 小时前
React实战指南
前端·react.js·前端框架