|
|
|
|
|
|
|
|
|
|
|
|
|
import React, { useState, useEffect } from "react"; |
|
|
|
import { useDispatch, useSelector } from 'react-redux'; |
|
|
|
import { movePiece, tempMove } from '../store/gameSlice'; |
|
|
|
import './board.css'; |
|
|
|
import bg from '../assets/bg.jpg'; |
|
|
|
import { board_size } from '../config'; |
|
|
|
import { STATUS } from '../status'; |
|
|
|
import axios from 'axios'; |
|
|
|
|
|
const Board = () => { |
|
|
|
const dispatch = useDispatch(); |
|
|
|
const { board, currentPlayer, history, status, size, loading, winner, depth, index } = useSelector((state) => state.game); |
|
|
|
|
|
const handleClick = async (i, j) => { |
|
|
|
if (loading || status !== STATUS.GAMING) { |
|
console.log(loading, status); |
|
console.log(' loading || status !== STATUS.GAMING '); |
|
return; |
|
} |
|
|
|
if (board[i][j] === 0) { |
|
|
|
if (depth <= 0) { |
|
try { |
|
|
|
dispatch(tempMove([i, j])) |
|
|
|
const response = await axios.post('https://zjowowen-gomoku.hf.space/gomoku_server_ui/', { |
|
command: 'step', |
|
argument: [i, j, depth], |
|
uid: ':1' |
|
}); |
|
|
|
const agentAction = response.data.result.action; |
|
|
|
dispatch(movePiece({ position: [i, j, agentAction.i, agentAction.j], depth: depth })); |
|
} catch (error) { |
|
|
|
console.error('Error communicating with the server: ', error.response || error); |
|
} |
|
} else { |
|
|
|
dispatch(tempMove([i, j])) |
|
dispatch(movePiece({ position: [i, j], depth })); |
|
console.log('depth > 0 '); |
|
} |
|
} |
|
}; |
|
|
|
|
|
useEffect(() => { |
|
|
|
if (winner === 1 || winner === -1) { |
|
window.alert(winner === 1 ? '黑棋获胜' : '白棋获胜') |
|
} |
|
}, [winner]); |
|
|
|
|
|
const cellStyle = { |
|
width: `${375 / board_size}px`, |
|
height: `${375 / board_size}px`, |
|
}; |
|
|
|
|
|
return ( |
|
<div className="board" style={{ backgroundImage: `url(${bg})` }}> |
|
{/* 遍历棋盘数组,渲染每一行 */} |
|
{board.map((row, i) => ( |
|
<div key={i} className="board-row"> |
|
{/* 遍历棋盘的每一列,渲染每一个格子 */} |
|
{row.map((cell, j) => { |
|
// 根据格子位置给格子添加不同的边界样式 |
|
let cellClassName = 'cell'; |
|
if (i === 0) { |
|
cellClassName += ' top'; |
|
} |
|
if (i === board_size - 1) { |
|
cellClassName += ' bottom'; |
|
} |
|
if (j === 0) { |
|
cellClassName += ' left'; |
|
} |
|
if (j === board_size - 1) { |
|
cellClassName += ' right'; |
|
} |
|
// 根据格子内棋子的状态给棋子添加不同的样式 |
|
let pieceClassname = 'piece'; |
|
if (cell === 1) { |
|
pieceClassname += ' black'; |
|
} else if (cell === -1) { |
|
pieceClassname += ' white'; |
|
} |
|
// 判断当前格子是否为最后落子的格子 |
|
let isLastCell = false; |
|
const lastMove = history[history.length - 1]; |
|
if (lastMove && (lastMove.i === i && lastMove.j === j)) { |
|
isLastCell = true; |
|
} |
|
// 如果显示历史记录索引,则计算当前棋子的序号 |
|
let number = 0; |
|
if (index) { |
|
for(let x = 0; x < history.length; x++) { |
|
if (history[x].i === i && history[x].j === j) { |
|
number = x + 1; |
|
break; |
|
} |
|
} |
|
} |
|
// 渲染每一个格子,包括棋子和最后落子的标记 |
|
return ( |
|
<div key={j} className={cellClassName} style={cellStyle} onClick={() => handleClick(i, j)}> |
|
{cell == 0 ? '' : <div className={pieceClassname}>{ number === 0 ? '' : number}</div>} |
|
{isLastCell && <div className="last" />} |
|
</div> |
|
) |
|
})} |
|
</div> |
|
))} |
|
</div> |
|
); |
|
}; |
|
|
|
|
|
export default Board; |
|
|