Files
ChessHub/frontend/src/pages/Chess/ChessBoard.jsx
T
2023-07-03 16:29:09 +05:30

152 lines
5.7 KiB
React

import React, { useEffect, useReducer, useRef } from 'react';
import { ChessModified, chess, chessInit } from '../../../utils/chess';
import Cell from '../../components/Cell';
import { socket } from '../../socket';
import { Flex, createStyles } from '@mantine/core';
import { DndContext } from '@dnd-kit/core'
import { useElementSize } from '@mantine/hooks';
const useStyles = createStyles((theme) => ({
chessboard: {
[theme.fn.largerThan('md')]: {
width: '600px'
},
[theme.fn.smallerThan('md')]: {
width: '560px'
},
[theme.fn.smallerThan('sm')]: {
width: '360px',
},
},
boardrow: {
[theme.fn.largerThan('md')]: {
height: '75px'
},
[theme.fn.smallerThan('md')]: {
height: '70px'
},
[theme.fn.smallerThan('sm')]: {
height: '45px'
},
}
}))
const reducer = (state, action) => {
console.log(state.chess.myColor)
switch (action.type) {
case 'SELECT_PIECE':
{
if (state.chess.turn() !== localStorage.getItem('myColor')) return state;
state.chess.select(action.val.square);
return { ...state, moveHints: state.chess.getMoves(state.chess.selected) };
}
case 'MOVE_PIECE':
{
console.log('Moving', action.val, state.chess.turn());
let newChessObj = new ChessModified({ prop: state.chess.fen(), color: state.chess.myColor })
newChessObj.move(action.val);
return { ...state, chess: newChessObj, chessBoard: newChessObj.getBoard(localStorage.getItem('myColor')), moveHints: [] };
}
case 'CAPTURE_PIECE':
{
console.log('Capture', action.val, state.chess.turn())
let newChessObj = new ChessModified({ prop: state.chess.fen(), color: state.chess.myColor });
newChessObj.move(action.val);
return { ...state, chess: newChessObj, chessBoard: newChessObj.getBoard(localStorage.getItem('myColor')), moveHints: [] };
}
default:
return state;
}
}
const ChessBoard = ({ color }) => {
const ref = useRef()
const { height, width } = useElementSize(ref)
const { classes } = useStyles();
const moveAudioRef = useRef(null);
const captureAudioRef = useRef(null);
const gameEndAudioRef = useRef(null);
const checkAudioRef = useRef(null);
let roomID = localStorage.getItem('roomID');
const [gameState, dispatch] = useReducer(reducer, {
chess: chessInit(color), chessBoard: chess.getBoard(color), moveHints: []
});
const chessBoardRef = useRef(gameState.chessBoard);
chessBoardRef.current = gameState.chessBoard;
useEffect(() => {
function handleOpponentMove(data) {
let { from, to } = data;
console.log(from + to)
if (!gameState.chess.get(to)) {
console.log('Moving piece: ', data)
dispatch({ type: 'MOVE_PIECE', val: { from, to } });
moveAudioRef.current.play();
return;
} else {
console.log('Capturing piece');
dispatch({ type: 'CAPTURE_PIECE', val: { from, to } });
captureAudioRef.current.play();
return;
}
}
socket.on('opponent-move', handleOpponentMove)
return () => {
socket.off('move', handleOpponentMove);
}
}, []);
return (
<DndContext onDragEnd={evt => {
let srcSquare = evt.active.id;
let destSquare = evt.over.id;
if (gameState.moveHints.includes(destSquare)) {
console.log(gameState.chess.get(srcSquare))
if (gameState.chess.get(destSquare)) {
captureAudioRef.current.play();
dispatch({ type: 'CAPTURE_PIECE', val: { from: srcSquare, to: destSquare } }); // capture piece
socket.emit('move', roomID, { from: srcSquare, to: destSquare })
} else {
moveAudioRef.current.play();
dispatch({ type: 'MOVE_PIECE', val: { from: srcSquare, to: destSquare } }); // move piece
socket.emit('move', roomID, { from: srcSquare, to: destSquare })
}
}
}}>
<Flex ref={ref} className={
classes.chessboard
}>
<div>
{gameState.chessBoard.map((row, rowIndex) => {
return (
<Flex className={classes.boardrow} key={rowIndex * 2}>
{row.map((cell) => {
return (
<Cell
key={cell.square}
cell={cell}
chess={chess}
marked={gameState.moveHints.includes(cell.square)}
dispatch={dispatch}
/>)
})}
</Flex>
)
})}
</div>
</Flex>
<audio src='/src/assets/move-self.mp3' ref={moveAudioRef} />
<audio src='/src/assets/capture.mp3' ref={captureAudioRef} />
<audio src='/src/assets/game-end.webm.mp3' ref={gameEndAudioRef} />
<audio src='/src/assets/move-check.mp3' ref={checkAudioRef} />
</DndContext >
)
}
export default ChessBoard