From d8d0c95779dcdc2052e8cf09d61791fb46d2ffb4 Mon Sep 17 00:00:00 2001 From: Moon Patel Date: Tue, 4 Jul 2023 03:11:46 +0530 Subject: [PATCH] New feature added: While in the match the user can go back it time to analyse previous moves. --- frontend/src/App.jsx | 12 +- frontend/src/components/GameHistory.jsx | 32 ++ frontend/src/constants.js | 1 + frontend/src/context/chess-game-context.jsx | 58 +++- frontend/src/pages/Chess/ChessBoard.jsx | 5 +- frontend/src/pages/Chess/ChessGame.jsx | 20 +- frontend/utils/chess.js | 306 -------------------- 7 files changed, 101 insertions(+), 333 deletions(-) create mode 100644 frontend/src/components/GameHistory.jsx diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index cf7fa0b..50ffa52 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -21,6 +21,7 @@ import ChallengeFriend, { playFriendAction } from './pages/Play/ChallengeFriend' import ChessGame from './pages/Chess/ChessGame' import JoinChallenge from './components/JoinChallenge' import ErrorBoundary from './components/ErrorBoundary' +import ChessGameContextProvider, { ChessGameContext } from './context/chess-game-context' const router = createBrowserRouter([{ path: '/', @@ -38,7 +39,14 @@ const router = createBrowserRouter([{ { path: 'online', element:
Online
} ] }, - { path: "game/friend/:roomID", element: }, + { + path: "game/friend/:roomID", element: +
+ + + +
+ }, { path: 'settings', element: , children: [ { index: true, element: }, @@ -52,7 +60,7 @@ const router = createBrowserRouter([{ }, { path: "/game/challenges/:challenger/:roomID", element: }, { - path: '/login', element: ,action: loginAction, loader: () => { if (getAuthToken()) return redirect('/home'); else return null; } + path: '/login', element: , action: loginAction, loader: () => { if (getAuthToken()) return redirect('/home'); else return null; } }, { path: '/signup', element: , action: signupAction, loader: () => { if (getAuthToken()) return redirect('/signup'); else return null; } }, { diff --git a/frontend/src/components/GameHistory.jsx b/frontend/src/components/GameHistory.jsx new file mode 100644 index 0000000..7378026 --- /dev/null +++ b/frontend/src/components/GameHistory.jsx @@ -0,0 +1,32 @@ +import React, { useContext } from 'react' +import { ChessGameContext } from '../context/chess-game-context' +import { Button, Flex, Text } from '@mantine/core'; + +const GameHistory = () => { + const { gameHistory, jumpTo } = useContext(ChessGameContext) + + let gameHistoryJSX = []; + for (let i = 0; i < gameHistory.length;) { + let move1 = null, move2 = null; + let index = i; + move1 = + if (i < gameHistory.length) { + let index = i; + move2 = + } + gameHistoryJSX.push( + + {move1} + {move2} + + ) + } + + return ( +
+ {gameHistoryJSX} +
+ ) +} + +export default GameHistory \ No newline at end of file diff --git a/frontend/src/constants.js b/frontend/src/constants.js index 56dd762..c85cdaf 100644 --- a/frontend/src/constants.js +++ b/frontend/src/constants.js @@ -13,4 +13,5 @@ export const DISPATCH_EVENTS = { SELECT_PIECE: "SELECT_PIECE", MOVE_PIECE: "MOVE_PIECE", CAPTURE_PIECE: "CAPTURE_PIECE", + JUMP_TO: "JUMP_TO", }; diff --git a/frontend/src/context/chess-game-context.jsx b/frontend/src/context/chess-game-context.jsx index d369957..a42522d 100644 --- a/frontend/src/context/chess-game-context.jsx +++ b/frontend/src/context/chess-game-context.jsx @@ -1,7 +1,8 @@ import React, { createContext, useReducer, useRef } from 'react' import { ChessModified, chessInit } from '../../utils/chess'; import { DISPATCH_EVENTS } from '../constants'; -const { CAPTURE_PIECE, MOVE_PIECE, SELECT_PIECE } = DISPATCH_EVENTS +import ChessBoard from '../pages/Chess/ChessBoard'; +const { CAPTURE_PIECE, MOVE_PIECE, SELECT_PIECE, JUMP_TO } = DISPATCH_EVENTS export const ChessGameContext = createContext(); // myColor: null, chess: null, chessBoard: null, moveHints: null, selected: null, dispatch: null, handleOpponentMove: null, handleSquareClick: null, getSquareColor: null, isSquareMarked: null, selectPiece: null, handleDrop: null @@ -11,22 +12,31 @@ const reducer = (state, action) => { switch (action.type) { case SELECT_PIECE: { - console.log('SELECTING...', action.val) + console.log('SELECTING...', action.val); return { ...state, moveHints: state.chess.getMoves(action.val), selected: action.val }; } 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: [], selected: null }; + let newChessObj = new ChessModified({ prop: state.chess.fen(), color: state.chess.myColor }); + let updatedGameHistory = state.gameHistory; + let move = newChessObj.move(action.val); + updatedGameHistory.push({ move: move.san, fen: newChessObj.fen() }); + return { ...state, chess: newChessObj, chessBoard: newChessObj.getBoard(localStorage.getItem('myColor')), moveHints: [], selected: null, gameHistory: updatedGameHistory, currentIndex: -1 }; } case CAPTURE_PIECE: { - console.log('Capture', action.val, state.chess.turn()) - let newChessObj = new ChessModified({ prop: state.chess.fen(), color: state.chess.myColor, selected: null }); - newChessObj.move(action.val); - return { ...state, chess: newChessObj, chessBoard: newChessObj.getBoard(localStorage.getItem('myColor')), moveHints: [] }; + console.log('Capture', action.val, state.chess.turn()); + let newChessObj = new ChessModified({ prop: state.chess.fen(), color: state.chess.myColor }); + let updatedGameHistory = state.gameHistory; + let move = newChessObj.move(action.val); + updatedGameHistory.push({ move: move.san, fen: newChessObj.fen() }); + return { ...state, chess: newChessObj, chessBoard: newChessObj.getBoard(localStorage.getItem('myColor')), moveHints: [], selected: null, gameHistory: updatedGameHistory, currentIndex: -1 }; + } + case JUMP_TO: + { + let index = action.val; + return { ...state, currentIndex: index } } default: return state; @@ -37,17 +47,23 @@ function chessGameStateInit(myColor) { let chess = chessInit(myColor); let chessBoard = chess.getBoard(myColor); let moveHints = []; + let gameHistory = []; let selected = null; + let currentIndex = -1; - return { chess, chessBoard, moveHints, selected } + return { chess, chessBoard, moveHints, selected, gameHistory, currentIndex }; } // the ChessGameContextProvider seperates the game logic from the ChessBoard component and exposes // some functions to update game state. const ChessGameContextProvider = ({ children }) => { let myColor = localStorage.getItem('myColor'); - const [{ chess, chessBoard, moveHints, selected }, dispatch] = useReducer(reducer, myColor, chessGameStateInit); + console.log('INSIDE CONTEXT PROVIDER'); + const [{ chess, chessBoard, moveHints, selected, gameHistory, currentIndex }, dispatch] = useReducer(reducer, myColor, chessGameStateInit); + console.log(gameHistory) + + console.log(gameHistory); const moveAudioRef = useRef(null); const captureAudioRef = useRef(null); const gameEndAudioRef = useRef(null); @@ -56,9 +72,9 @@ const ChessGameContextProvider = ({ children }) => { // data received through socket function handleOpponentMove(data) { let { from, to } = data; - console.log(from + to) + console.log(from + to); if (!chess.get(to)) { - console.log('Moving piece: ', data) + console.log('Moving piece: ', data); dispatch({ type: MOVE_PIECE, val: { from, to } }); moveAudioRef.current.play(); return; @@ -123,9 +139,23 @@ const ChessGameContextProvider = ({ children }) => { return moveHints.includes(square); } + function jumpTo(index) { + dispatch({ type: JUMP_TO, val: index }) + } + + function getChessBoard() { + console.log(gameHistory, currentIndex); + if (currentIndex === -1 || gameHistory.length === 0) { + return chessBoard; + } else { + let currentChessBoard = new ChessModified({ prop: gameHistory[currentIndex].fen, color: myColor }).getBoard(myColor); + return currentChessBoard; + } + } + return ( {children}