Skip to content

Commit

Permalink
feat: insert game moves into database
Browse files Browse the repository at this point in the history
  • Loading branch information
sownfam committed Dec 29, 2023
1 parent d402251 commit 5914aa0
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 22 deletions.
7 changes: 7 additions & 0 deletions api/app/dto/core/insert_moves.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from api.app.dto.base import CamelBaseModel
from typing import List

class InsertMoveRequest(CamelBaseModel):
game_id: int
user_id: int
move_details: List[str]
1 change: 1 addition & 0 deletions api/app/dto/core/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class RatingInGetProfileResponse(CamelBaseModel):
variant_id: int

class GetProfileResponse(CamelBaseModel):
user_id: int
name: str
date_of_birth: date
gender: UserGender
Expand Down
1 change: 1 addition & 0 deletions api/app/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from .variants import Variants
from .puzzle import Puzzle
from .profile import Profile
from .move import Move
22 changes: 22 additions & 0 deletions api/app/service/insert_moves.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from sqlalchemy.orm import Session
from sqlalchemy import select
from api.app.model import Move
from datetime import datetime
from api.app.dto.core.insert_moves import InsertMoveRequest
from fastapi import Depends
from api.app.helper.db import db_session
from api.app.model import Game


async def insert_game_move(db: Session, request: InsertMoveRequest):
for move_detail in request.move_details:
move = Move(game_id=request.game_id, user_id=request.user_id, move_detail=move_detail,
time_stamp=datetime.now())
db.add(move)
db.commit()
pass

async def get_game_id_from_slug(db: Session, slug: str):
statement = select(Game.id).where(Game.slug == slug)
row = db.scalars(statement).one();
return row;
2 changes: 1 addition & 1 deletion api/app/service/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def get_current_user_profile(cls, db: Session, user: User) -> GetProfileResponse
ratings = []
for res in q.all():
ratings.append(RatingInGetProfileResponse(rating=res.rating, variant_id=res.variant_id))
return GetProfileResponse(name=user_profile.name, date_of_birth=user_profile.date_of_birth,
return GetProfileResponse(user_id=user_profile.id, name=user_profile.name, date_of_birth=user_profile.date_of_birth,
gender=user_profile.gender, email=user_profile.email, ratings=ratings)

@classmethod
Expand Down
36 changes: 34 additions & 2 deletions api/index.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from fastapi import FastAPI, Request, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from api.app import create_app
from api.app.service.insert_moves import insert_game_move, get_game_id_from_slug
from api.app.helper.db import db_session
from sqlalchemy.orm import Session
from api.app.dto.core.insert_moves import InsertMoveRequest
from .config import STOCKFISH_PATH
from .socket import manager
from fastapi.staticfiles import StaticFiles
Expand Down Expand Up @@ -116,7 +120,16 @@ async def play_chess(sid, msg):
}
game_states[gameID]['status'] = True
game_states[gameID]['result'] = winner
# TODO: Insert moves into database
all_uci_moves = list(map(lambda move: move.uci(), game_states[gameID]['board'].move_stack))
with next(db_session()) as db:
game_id_num = await get_game_id_from_slug(db, slug=gameID)
insert_move_request = InsertMoveRequest(
game_id = game_id_num,
user_id = game_states[gameID]['userID'], #FIXME, or not...
move_details = all_uci_moves
)
await insert_game_move(db, request=insert_move_request)

await sio.emit("play-chess", json.dumps(message), room=sid)
return

Expand All @@ -136,7 +149,15 @@ async def play_chess(sid, msg):
winner = 0 if winner_color is None else 1 if winner_color is True else 2
game_states[gameID]['status'] = True
game_states[gameID]['result'] = winner
# TODO: Insert moves into database
all_uci_moves = list(map(lambda move: move.uci(), game_states[gameID]['board'].move_stack))
with next(db_session()) as db:
game_id_num = await get_game_id_from_slug(db, slug=gameID)
insert_move_request = InsertMoveRequest(
game_id = game_id_num,
user_id = game_states[gameID]['userID'], #FIXME, or not...
move_details = all_uci_moves
)
await insert_game_move(db, request=insert_move_request)

message = {
"ok": True,
Expand Down Expand Up @@ -176,6 +197,15 @@ async def user_forfeit(sid, msg):
if (gameID in game_states):
game_states[gameID]['status'] = True
game_states[gameID]['result'] = 2 # Black win
all_uci_moves = list(map(lambda move: move.uci(), game_states[gameID]['board'].move_stack))
with next(db_session()) as db:
game_id_num = await get_game_id_from_slug(db, slug=gameID)
insert_move_request = InsertMoveRequest(
game_id = game_id_num,
user_id = game_states[gameID]['userID'], #FIXME, or not...
move_details = all_uci_moves
)
await insert_game_move(db, request=insert_move_request)

message = "White forfeited" # TODO: Return match info for modal rendering?
await sio.emit("user-forfeit", message, room=sid)
Expand All @@ -185,6 +215,7 @@ async def start_game(sid, msg):
try:
data = json.loads(msg)
gameID = data["id"]
userID = data["userId"]
all_game_ids.discard(gameID) # safe removal
all_game_ids.add(gameID)
engine = chess.engine.SimpleEngine.popen_uci(STOCKFISH_PATH)
Expand All @@ -201,6 +232,7 @@ async def start_game(sid, msg):
current_state['limit'] = limit
current_state['status'] = False # Unfinished game
current_state['result'] = 3 # Unknown result
current_state['userID'] = userID

timer_dict = dict()
timer_dict['wPlayer'] = wTimer
Expand Down
9 changes: 1 addition & 8 deletions src/app/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,14 +187,7 @@ const Analyst = () => {
}

const ProfilePage = () => {
const {name } = useContext(UserContext);
const router = useRouter();
useEffect(() => {
const token = localStorage.getItem('accessToken');
if (!token) {
router.push('/login');
}
},[])
const { name } = useContext(UserContext);
return (
<div className="flex flex-col">
<div className="rw-full sm:w-full md:w-full p-4">
Expand Down
6 changes: 4 additions & 2 deletions src/components/ChessGame/ChessGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import MoveList from "../MoveList/MoveList";
import useChessSocket, { ChessType } from "@/hooks/useChessSocket";
import PlayerCard from "@/components/Card/PlayerCard";
import PrepareCard from "@/components/Card/PrepareCard";
import { useEffect, useState } from "react";
import { useContext, useEffect, useState } from "react";
import { BotProps } from "@/types";

import PlayerTimer from "@/components/PlayerTimer/PlayerTimer";
import ModalEndGame from "../Modal/ModalEndGame";

import { CaretLeftFilled, CaretRightFilled } from "@ant-design/icons";
import { UserContext } from "@/context/UserContext";

type ChessGameType = {
id: string;
type: ChessType;
};

const ChessGame = ({ id, type }: ChessGameType) => {
const { userId } = useContext(UserContext);
const {
game,
// moves,
Expand All @@ -44,7 +46,7 @@ const ChessGame = ({ id, type }: ChessGameType) => {
prevMove,
nextMove

} = useChessSocket({ type, id });
} = useChessSocket({ type, id, userId });

const [botList, setBotList] = useState<BotProps[]>([]);
const [bot, setBot] = useState<BotProps>({ id: "0", name: "shark" });
Expand Down
22 changes: 16 additions & 6 deletions src/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const items: MenuProps["items"] = [
const Navbar : React.FC = () => {
const [isModalPlayBotOpen, setIsModalPlayBotOpen] = React.useState(false);
const router = useRouter();
const {name, rate} = useContext(UserContext);
const {name, rate, accessToken} = useContext(UserContext);

const showModal = () => {
setIsModalPlayBotOpen(true);
Expand All @@ -78,6 +78,12 @@ const Navbar : React.FC = () => {
}
};

const onClickAvatar = () => {
const savedToken = localStorage.getItem('accessToken');
if(!accessToken || !savedToken) router.push("/login");
else router.push("/profile");
}

return (
<>
<div
Expand All @@ -88,23 +94,27 @@ const Navbar : React.FC = () => {
<StockChess />
</Link>
<div className="object-cover p-6 w-full flex items-center justify-center">
<Link href="/profile">
<img src={avatar} alt="image description" className="shadow rounded-full max-w-full h-auto border-4 border-[#518538]"/>
</Link>
<div>
<button onClick={onClickAvatar}>
<img src={avatar} alt="image description" className="shadow rounded-full max-w-full h-auto border-4 border-[#518538]"/>
</button>
</div>
<Link href={"/settings"}>
<SettingOutlined style={{ fontSize: "40px", color:'#f1f1f1' }} className='pl-5'/>
</Link>
</div>
<div className="pb-6">
<div className="object-cover max-w-full flex items-center justify-center bg-[#518538] rounded-3xl shadow-md h-auto m-1">
<Link href="/profile">
<div>
<button onClick={onClickAvatar}>
<div className="text-3xl text-slate-100 font-mono font-bold flex items-center pt-3">
{name ? name : "Guest"}
</div>
<div className="text-l text-slate-100 font-mono flex items-center pb-3 pt-0.5">
Rate: {rate ? rate : "xxx"}
</div>
</Link>
</button>
</div>
</div>
</div>
<div>
Expand Down
4 changes: 4 additions & 0 deletions src/context/UserContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import React, {ComponentType, useState, useEffect} from "react";

type UserContextType = {
userId?: number,
name?: string,
dateOfBirth?: string,
gender?: string,
Expand All @@ -14,6 +15,7 @@ type UserContextType = {
}

const defaultValue = {
userId: 0,
dateOfBirth: "",
email: "",
gender: "",
Expand Down Expand Up @@ -55,6 +57,7 @@ const UserProvider: React.FC<Props> = (props) => {
})
const data = await response.json();
if (data?.code === 200) {
console.log("DATA PROF: ", data.data);
setDataUser(data.data)
}
} else {
Expand All @@ -72,6 +75,7 @@ const UserProvider: React.FC<Props> = (props) => {

return (
<UserContext.Provider value={{
userId: dataUser?.userId,
dateOfBirth: dataUser?.dateOfBirth,
email: dataUser?.email,
gender: dataUser?.gender,
Expand Down
9 changes: 6 additions & 3 deletions src/hooks/useChessSocket.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { useReducer, useState } from "react";
import { useContext, useReducer, useState } from "react";
import React from "react";
import { Chess, Move, Square } from "chess.js";
import { io, Socket } from "socket.io-client";
import { CustomSquares, ShortMove } from "@/types";
import { useLocalStorage } from "./useLocalStorage";
import { httpGetPlayerTimeLeft } from "@/modules/backend-client/httpGetPlayerTimeLeft";
import { WINNER } from "@/helpers/types";
import { UserContext } from "@/context/UserContext";

export type ChessType = "random" | "computer" | "minimax";

type Props = {
id: string;
type: ChessType;
userId?: number;
};

enum ConnectionStatus {
Expand All @@ -29,7 +31,7 @@ function squareReducer(squares: CustomSquares, action: Partial<CustomSquares>) {
return { ...squares, ...action };
}

const useChessSocket = ({ type, id }: Props) => {
const useChessSocket = ({ type, id, userId }: Props) => {
// Start of socket
const [socket, setSocket] = React.useState<Socket | null>(null);
const [connectionStatus, setConnectionStatus] =
Expand Down Expand Up @@ -168,6 +170,7 @@ const useChessSocket = ({ type, id }: Props) => {
}
}
getTime();
console.log("??: ", userId);
}, []);

// Send latest move over socket
Expand All @@ -185,7 +188,7 @@ const useChessSocket = ({ type, id }: Props) => {

const onInitGame = () => {
console.log("Running init...");
const initNewGame = { id: id }; // TODO: Add preferences (difficulty, timer, ...)
const initNewGame = { id: id, userId: userId ?? 0 }; // TODO: Add preferences (difficulty, timer, ...)
socket?.emit("start-game", JSON.stringify(initNewGame));
};

Expand Down

0 comments on commit 5914aa0

Please sign in to comment.