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}
diff --git a/frontend/src/pages/Chess/ChessBoard.jsx b/frontend/src/pages/Chess/ChessBoard.jsx
index 7d8c76a..2a27f0b 100644
--- a/frontend/src/pages/Chess/ChessBoard.jsx
+++ b/frontend/src/pages/Chess/ChessBoard.jsx
@@ -5,7 +5,7 @@ import { Flex, createStyles } from '@mantine/core';
import { DndContext } from '@dnd-kit/core'
import { ChessGameContext } from '../../context/chess-game-context';
import { SOCKET_EVENTS } from '../../constants';
-const {CHESS_OPPONENT_MOVE,CHESS_MOVE} = SOCKET_EVENTS
+const { CHESS_OPPONENT_MOVE, CHESS_MOVE } = SOCKET_EVENTS
const useStyles = createStyles((theme) => ({
chessboard: {
[theme.fn.largerThan('md')]: {
@@ -34,8 +34,9 @@ const useStyles = createStyles((theme) => ({
const ChessBoard = () => {
const { classes } = useStyles();
- const { chessBoard, handleOpponentMove, handleDrop } = useContext(ChessGameContext)
+ const { getChessBoard, handleOpponentMove, handleDrop } = useContext(ChessGameContext)
let roomID = localStorage.getItem('roomID');
+ const chessBoard = getChessBoard();
useEffect(() => {
socket.on(CHESS_OPPONENT_MOVE, handleOpponentMove)
diff --git a/frontend/src/pages/Chess/ChessGame.jsx b/frontend/src/pages/Chess/ChessGame.jsx
index 20ba860..9127505 100644
--- a/frontend/src/pages/Chess/ChessGame.jsx
+++ b/frontend/src/pages/Chess/ChessGame.jsx
@@ -1,12 +1,14 @@
import { Avatar, Button, Flex, Image, Loader, MediaQuery, NavLink, Text, Title } from '@mantine/core'
-import React, { useEffect, useState } from 'react'
+import React, { useContext, useEffect, useState } from 'react'
import ChessBoard from '../Chess/ChessBoard'
import { useNavigate, useParams } from 'react-router-dom'
import { socket } from '../../socket'
import { getUserData } from '../../../utils/auth'
-import ChessGameContextProvider from '../../context/chess-game-context'
+import { ChessGameContext } from '../../context/chess-game-context'
+import GameHistory from '../../components/GameHistory'
const ChessGame = () => {
+ const { gameHistory } = useContext(ChessGameContext);
const user = getUserData();
let username = user.username;
let color = localStorage.getItem('myColor')
@@ -59,9 +61,9 @@ const ChessGame = () => {
}, []);
- // if (!hasJoinedRoom) return (
- //
- // )
+ if (!hasJoinedRoom) return (
+
+ )
return (
@@ -72,9 +74,7 @@ const ChessGame = () => {
icon={}
description={"description"}
/>
-
-
-
+
{
/>
-
{
borderRadius: '10px'
}} bg='gray' p="10px" justify='start' align='center' direction='column' h="600px">
Game Data
+
+
+
diff --git a/frontend/utils/chess.js b/frontend/utils/chess.js
index d25eda5..5770f0e 100644
--- a/frontend/utils/chess.js
+++ b/frontend/utils/chess.js
@@ -1,309 +1,3 @@
-// const pawn = "P",
-// rook = "R",
-// knight = "N",
-// bishop = "B",
-// queen = "Q",
-// king = "K";
-
-// export const pieces = {
-// pawn,
-// rook,
-// knight,
-// bishop,
-// queen,
-// king,
-// };
-
-// export const whiteColor = "W",
-// blackColor = "B";
-
-// export function chessBoardInit(myColor) {
-// let opColor = myColor === whiteColor ? blackColor : whiteColor;
-// const chessBoardMatrix = [
-// [
-// { color: opColor, type: rook },
-// { color: opColor, type: knight },
-// { color: opColor, type: bishop },
-// { color: opColor, type: myColor === whiteColor ? queen : king },
-// { color: opColor, type: myColor === whiteColor ? king : queen },
-// { color: opColor, type: bishop },
-// { color: opColor, type: knight },
-// { color: opColor, type: rook },
-// ],
-// Array(8).fill({ color: opColor, type: pawn }),
-// [null, null, null, null, null, null, null, null],
-// [null, null, null, null, null, null, null, null],
-// [null, null, null, null, null, null, null, null],
-// [null, null, null, null, null, null, null, null],
-// Array(8).fill({ color: myColor, type: pawn }),
-// [
-// { color: myColor, type: rook },
-// { color: myColor, type: knight },
-// { color: myColor, type: bishop },
-// { color: myColor, type: myColor === whiteColor ? queen : king },
-// { color: myColor, type: myColor === whiteColor ? king : queen },
-// { color: myColor, type: bishop },
-// { color: myColor, type: knight },
-// { color: myColor, type: rook },
-// ],
-// ];
-// return chessBoardMatrix;
-// }
-
-// function inBoard(i, j) {
-// if (i >= 0 && i < 8 && j >= 0 && j < 8) return true;
-// else return false;
-// }
-
-// function isBlocked(chessBoard, chessPiece, i, j) {
-// if (chessBoard[i][j] === null) return false;
-// else if (chessBoard[i][j].color === chessPiece.color) return true;
-// else return false;
-// }
-
-// function isAttacking(chessBoard, chessPiece, i, j) {
-// if (chessBoard[i][j] === null) return false;
-// else if (chessBoard[i][j].color !== chessPiece.color) return true;
-// else return false;
-// }
-
-// function getPawnHint(chessBoard, chessPiece, myColor) {
-// const { row, col } = chessPiece;
-// let movePos = [];
-// if (chessPiece.color === myColor) {
-// // for moving forward
-// if (inBoard(row - 1, col) && chessBoard[row - 1][col] === null && movePos.push({ row: row - 1, col })) {
-// chessPiece.row === 6 &&
-// chessBoard[row - 2][col] === null &&
-// inBoard(row - 2, col) &&
-// !isBlocked(chessBoard, chessPiece, row - 1, col) &&
-// movePos.push({ row: row - 2, col });
-// }
-// // for killing opponent piece
-// if (
-// inBoard(row - 1, col + 1) &&
-// chessBoard[row - 1][col + 1]?.type &&
-// chessBoard[row - 1][col + 1]?.color !== myColor
-// )
-// inBoard(row - 1, col + 1) && movePos.push({ row: row - 1, col: col + 1 });
-// if (
-// inBoard(row - 1, col - 1) &&
-// chessBoard[row - 1][col - 1]?.type &&
-// chessBoard[row - 1][col - 1]?.color !== myColor
-// )
-// inBoard(row - 1, col - 1) && movePos.push({ row: row - 1, col: col - 1 });
-// } else {
-// // for moving forward
-// if (inBoard(row + 1, col) && chessBoard[row + 1][col] === null && movePos.push({ row: row + 1, col })) {
-// chessPiece.row === 1 &&
-// chessBoard[row + 2][col] === null &&
-// inBoard(row + 2, col) &&
-// movePos.push({ row: row + 2, col });
-// }
-// // for killing opponent piece
-// if (
-// inBoard(row + 1, col + 1) &&
-// chessBoard[row + 1][col + 1]?.type &&
-// chessBoard[row + 1][col + 1]?.color === myColor
-// )
-// inBoard(row + 1, col + 1) && movePos.push({ row: row + 1, col: col + 1 });
-// if (
-// inBoard(row + 1, col - 1) &&
-// chessBoard[row + 1][col - 1]?.type &&
-// chessBoard[row + 1][col - 1]?.color === myColor
-// )
-// inBoard(row + 1, col - 1) && movePos.push({ row: row + 1, col: col - 1 });
-// }
-
-// return { movePos };
-// }
-
-// function getRookHint(chessBoard, chessPiece, myColor) {
-// const { row, col, color } = chessPiece;
-// let movePos = [];
-// let i = row,
-// j = col;
-// while (inBoard(++i, j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(--i, j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(i, ++j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(i, --j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// console.log(movePos);
-
-// return { movePos };
-// }
-
-// function getKnightHint(chessBoard, chessPiece, myColor) {
-// const { row, col, color } = chessPiece;
-// let movePos = [];
-
-// if (inBoard(row + 2, col + 1) && !isBlocked(chessBoard, chessPiece, row + 2, col + 1))
-// movePos.push({ row: row + 2, col: col + 1 });
-// if (inBoard(row + 2, col - 1) && !isBlocked(chessBoard, chessPiece, row + 2, col - 1))
-// movePos.push({ row: row + 2, col: col - 1 });
-// if (inBoard(row - 2, col + 1) && !isBlocked(chessBoard, chessPiece, row - 2, col + 1))
-// movePos.push({ row: row - 2, col: col + 1 });
-// if (inBoard(row - 2, col - 1) && !isBlocked(chessBoard, chessPiece, row - 2, col - 1))
-// movePos.push({ row: row - 2, col: col - 1 });
-// if (inBoard(row + 1, col + 2) && !isBlocked(chessBoard, chessPiece, row + 1, col + 2))
-// movePos.push({ row: row + 1, col: col + 2 });
-// if (inBoard(row - 1, col + 2) && !isBlocked(chessBoard, chessPiece, row - 1, col + 2))
-// movePos.push({ row: row - 1, col: col + 2 });
-// if (inBoard(row + 1, col - 2) && !isBlocked(chessBoard, chessPiece, row + 1, col - 2))
-// movePos.push({ row: row + 1, col: col - 2 });
-// if (inBoard(row - 1, col - 2) && !isBlocked(chessBoard, chessPiece, row - 1, col - 2))
-// movePos.push({ row: row - 1, col: col - 2 });
-
-// return { movePos };
-// }
-
-// function getBishopHint(chessBoard, chessPiece, myColor) {
-// const { row, col, color } = chessPiece;
-// let movePos = [];
-
-// let i = row,
-// j = col;
-// while (inBoard(++i, ++j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(++i, --j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(--i, ++j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(--i, --j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-
-// return { movePos };
-// }
-
-// function getQueenHint(chessBoard, chessPiece, myColor) {
-// const { row, col, color } = chessPiece;
-// let movePos = [];
-// let i = row,
-// j = col;
-// while (inBoard(++i, j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(--i, j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(i, ++j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(i, --j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(++i, ++j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(++i, --j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(--i, ++j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-// i = row;
-// j = col;
-// while (inBoard(--i, --j) && !isBlocked(chessBoard, chessPiece, i, j)) {
-// movePos.push({ row: i, col: j });
-// if (isAttacking(chessBoard, chessPiece, i, j)) break;
-// }
-
-// return { movePos };
-// }
-
-// function getKingHint(chessBoard, chessPiece, myColor) {
-// const { row, col } = chessPiece;
-// let movePos = [];
-
-// if (inBoard(row, col + 1) && !isBlocked(chessBoard, chessPiece, row, col + 1))
-// movePos.push({ row: row, col: col + 1 });
-// if (inBoard(row, col - 1) && !isBlocked(chessBoard, chessPiece, row, col - 1))
-// movePos.push({ row: row, col: col - 1 });
-// if (inBoard(row + 1, col + 1) && !isBlocked(chessBoard, chessPiece, row + 1, col + 1))
-// movePos.push({ row: row + 1, col: col + 1 });
-// if (inBoard(row + 1, col) && !isBlocked(chessBoard, chessPiece, row + 1, col))
-// movePos.push({ row: row + 1, col: col });
-// if (inBoard(row + 1, col - 1) && !isBlocked(chessBoard, chessPiece, row + 1, col - 1))
-// movePos.push({ row: row + 1, col: col - 1 });
-// if (inBoard(row - 1, col + 1) && !isBlocked(chessBoard, chessPiece, row - 1, col + 1))
-// movePos.push({ row: row - 1, col: col + 1 });
-// if (inBoard(row - 1, col) && !isBlocked(chessBoard, chessPiece, row - 1, col))
-// movePos.push({ row: row - 1, col: col });
-// if (inBoard(row - 1, col - 1) && !isBlocked(chessBoard, chessPiece, row - 1, col - 1))
-// movePos.push({ row: row - 1, col: col - 1 });
-
-// return { movePos };
-// }
-
-// export function getPieceHint(chessBoard, chessPiece, myColor) {
-// switch (chessPiece.type) {
-// case pawn:
-// return getPawnHint(chessBoard, chessPiece, myColor);
-// case rook:
-// return getRookHint(chessBoard, chessPiece, myColor);
-// case knight:
-// return getKnightHint(chessBoard, chessPiece, myColor);
-// case bishop:
-// return getBishopHint(chessBoard, chessPiece, myColor);
-// case queen:
-// return getQueenHint(chessBoard, chessPiece, myColor);
-// case king:
-// return getKingHint(chessBoard, chessPiece, myColor);
-// }
-
-// return [];
-// }
-
import { Chess } from "chess.js";
export class ChessModified extends Chess {