Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Oceankoh committed Jan 20, 2024
2 parents fed514f + c1c27ab commit 76afc49
Show file tree
Hide file tree
Showing 11 changed files with 338 additions and 65 deletions.
26 changes: 23 additions & 3 deletions backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import { Server } from "socket.io";
const ENVIRONMENT = process.env.ENV || "dev";

let httpServer = createServer();
const io = new Server(httpServer, { serveClient: false });
const io = new Server(httpServer, {
serveClient: false,
cors:
ENVIRONMENT === "dev"
? { origin: "*", methods: ["GET", "POST"] }
: undefined,
});

let expressApp = express();
if (ENVIRONMENT === "dev") {
Expand Down Expand Up @@ -46,12 +52,26 @@ io.on("connection", (socket) => {
socket.join(roomId);

if (io.sockets.adapter.rooms.get(roomId).size === 2)
io.to(roomId).emit("start", global.rooms[roomId].players.size);
io.to(roomId).emit(
"start",
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR",
socket.id
);

callback(true);
});

socket.on("move", (move) => {});
socket.on("move", (move) => {
console.log(socket.id, move);
socket.rooms.forEach((roomId) =>
io.to(roomId).emit(
"update",
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
socket.id,
null //TODO winner
)
);
});

socket.on("disconnecting", () => {
console.log(`${socket.id} disconnecting`);
Expand Down
9 changes: 8 additions & 1 deletion backend/src/utils/calc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
// Generate a random 6-letter room code
export function generateRoomCode() {
return Math.random().toString(36).substring(2, 8).toUpperCase();
const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let roomCode = "";
for (let i = 0; i < 6; i++) {
roomCode += characters.charAt(
Math.floor(Math.random() * characters.length)
);
}
return roomCode;
}
13 changes: 12 additions & 1 deletion backend/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,16 @@ socket.on("connect", () => {
console.log(roomId);
});

socket.send("ping");
socket.on("start", (fen, whiteSocketId) => {
console.log(fen);

if (whiteSocketId === socket.id) socket.emit("move", "aSTART");
socket.on("update", (fen, lastMove) => {
console.log(fen);
const myTurn = lastMove !== socket.id;
setTimeout(() => {
if (myTurn) socket.emit("move", "a1");
}, 2000);
});
});
});
15 changes: 14 additions & 1 deletion backend/test/test2.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,22 @@ const socket = io("http://localhost:8000");

socket.on("connect", () => {
console.log(socket.id);
socket.emit("join", "TEST", (ack) => {
socket.emit("join", "Z001OQ", (ack) => {
console.log(ack);
});

socket.on("start", (fen, whiteSocketId) => {
console.log(fen);

if (whiteSocketId === socket.id) socket.emit("move", "bSTART");
socket.on("update", (fen, lastMove) => {
console.log(fen);
const myTurn = lastMove !== socket.id;
setTimeout(() => {
if (myTurn) socket.emit("move", "b1");
}, 2000);
});
});

socket.send("ping");
});
4 changes: 3 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
"preview": "vite preview"
},
"dependencies": {
"@types/socketcluster-client": "^19.1.0",
"react": "^18.2.0",
"react-chessboard": "^4.3.4",
"react-dom": "^18.2.0",
"semantic-ui-less": "^2.5.0",
"semantic-ui-react": "^2.1.5"
"semantic-ui-react": "^2.1.5",
"socket.io-client": "^4.7.4"
},
"devDependencies": {
"@rollup/plugin-alias": "^5.1.0",
Expand Down
19 changes: 16 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,30 @@ import { useState } from "react";
import "./App.css";
import Landing from "./Landing";
import Game from "./Game";
import { onGameStart, onUpdate } from "./utils/socket";

function App() {
const [roomCode, setRoomCode] = useState<string | undefined>("");
const [gameStarted, setGameStarted] = useState(false);
const [fen, setFen] = useState<string | undefined>();
const [isTurn, setIsTurn] = useState(false);
const [isWhite, setIsWhite] = useState(false);

//TODO socket IO
const [gameStarted, setGameStarted] = useState(true);
onGameStart((fen, isWhite) => {
setFen(fen);
setIsWhite(isWhite);
setIsTurn(isWhite);
setGameStarted(true);
});
onUpdate((fen, isTurn, lastMove) => {
setFen(fen);
setIsTurn(isTurn);
});

return (
<>
{gameStarted ? (
<Game />
<Game fen={fen} isWhite={isWhite} isTurn={isTurn} />
) : (
<Landing confirmedRoomCodeState={[roomCode, setRoomCode]} />
)}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/Game.css
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
}

div.message {
margin: 5px;
margin: 5px 0;
width: 100%;
height: fit-content;
background-color: transparent;
Expand Down
88 changes: 50 additions & 38 deletions frontend/src/Game.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,55 @@
import { Button, Container, Grid, Icon, Input } from "semantic-ui-react";
import { useEffect, useState } from "react";
import { Chessboard } from "react-chessboard";
import "./Game.css";
import { Message } from "./types/message";
import { useCallback, useState } from "react";

export default function Game() {
const [fen, setFen] = useState(
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
);

useEffect(() => {
setInterval(() => {
const a = Date.now() % 3;
export default function Game({
fen,
isWhite,
isTurn,
}: {
fen?: string;
isWhite: boolean;
isTurn: boolean;
}) {
const [text, setText] = useState("");
const [messages, setMessages] = useState<Message[]>([]);

if (a == 0)
setFen("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
else if (a == 1)
setFen("rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1");
else
setFen(
"rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2"
);
}, 2813);
}, []);
// const messages: Message[] = [
// { outgoing: true, text: "Knight to E5" },
// { outgoing: false, text: "Moving knight from A5 to E5" },
// {
// outgoing: true,
// text: "Knight to E5 and move all pawns forward. This is a very illegal move",
// },
// { outgoing: false, text: "Move not allowed! Try again!" },
// {
// outgoing: true,
// text: "Knight to E5 and move all pawns forward. This move is legal",
// },
// { outgoing: false, text: "Moving knight to E5 and move all pawns forward" },
// { outgoing: true, text: "Win the game" },
// { outgoing: false, text: "Move not allowed! Try again!" },
// ];

const messages: Message[] = [
{ outgoing: true, text: "Knight to E5" },
{ outgoing: false, text: "Moving knight from A5 to E5" },
{
outgoing: true,
text: "Knight to E5 and move all pawns forward. This is a very illegal move",
},
{ outgoing: false, text: "Move not allowed! Try again!" },
{
outgoing: true,
text: "Knight to E5 and move all pawns forward. This move is legal",
},
{ outgoing: false, text: "Moving knight to E5 and move all pawns forward" },
{ outgoing: true, text: "Win the game" },
{ outgoing: false, text: "Move not allowed! Try again!" },
];
const sendMessage = useCallback(() => {
if (text.trim().length === 0) return;
setMessages((msgs) => [...msgs, { outgoing: true, text }]);
setText("");
}, [text]);

return (
<Grid columns={2} style={{ height: "80vh", width: "80vw" }}>
<Grid.Column>
<Chessboard position={fen} />
<Chessboard
position={fen}
areArrowsAllowed={false}
arePiecesDraggable={false}
boardOrientation={isWhite ? "white" : "black"}
customLightSquareStyle={{ backgroundColor: "#CCC5B9" }}
customDarkSquareStyle={{ backgroundColor: "#4C4843" }}
/>
</Grid.Column>
<Grid.Column>
<div>
Expand All @@ -58,8 +63,9 @@ export default function Game() {
}}
>
<Container style={{ flex: 1 }} />
{messages.map((m) => (
{messages.map((m, idx) => (
<div
key={idx}
className={
"message " + (m.outgoing ? "outgoing" : "incoming")
}
Expand All @@ -69,11 +75,17 @@ export default function Game() {
))}
</Container>
<Input
onKeyDown={(event: KeyboardEvent) => {
if (event.key === "Enter") sendMessage();
}}
value={text}
onChange={(t) => setText(t.target.value)}
action={
<Button primary>
<Button primary onClick={sendMessage}>
<Icon name="send" />
</Button>
}
disabled={!isTurn}
/>
</Container>
</div>
Expand Down
32 changes: 18 additions & 14 deletions frontend/src/Landing.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { Button, Grid, Header, Icon, Input } from "semantic-ui-react";
import { createRoom, joinRoom } from "./utils/socket";

export default function Landing({
confirmedRoomCodeState,
Expand All @@ -17,6 +18,16 @@ export default function Landing({
if (isChoosingState) roomCodeRef.current?.focus();
}, [isChoosingState]);

const requestJoin = useCallback(async () => {
if (roomCode.length == 6) {
const joined = await joinRoom(roomCode);
if (joined) {
setIsChoosingState(false);
setConfirmedRoomCode(roomCode);
}
}
}, [roomCode, setConfirmedRoomCode]);

return (
<Grid columns={1} textAlign="center">
<Grid.Row>
Expand Down Expand Up @@ -48,9 +59,8 @@ export default function Landing({
<Grid.Row>
<Button
primary
onClick={() => {
//TODO: Socket IO
setConfirmedRoomCode("ABCDEF");
onClick={async () => {
setConfirmedRoomCode(await createRoom());
}}
>
Create Game
Expand All @@ -63,17 +73,11 @@ export default function Landing({
ref={roomCodeRef}
input={<input onBlur={() => setIsChoosingState(false)}></input>}
placeholder="Enter Room Code"
onKeyDown={(event: KeyboardEvent) => {
if (event.key === "Enter") requestJoin();
}}
action={
<Button
primary
onMouseDown={() => {
//TODO: Socket IO
if (roomCode.length == 6) {
setIsChoosingState(false);
setConfirmedRoomCode(roomCode);
}
}}
>
<Button primary onMouseDown={requestJoin}>
<Icon name="sign-in" />
</Button>
}
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/utils/socket.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { io } from "socket.io-client";

const socket = io("http://localhost:8000");

socket.on("connect", () => console.log("Connected to socket.io server"));

export async function createRoom() {
const response = await socket.emitWithAck("create");
console.log(response);
return response as string;
}

export async function joinRoom(roomId: string) {
const response = await socket.emitWithAck("join", roomId);
console.log(roomId, response);
return response as boolean;
}

export function move(move: string) {
socket.emit("move", move);
}

export function onGameStart(callback: (fen: string, isWhite: boolean) => void) {
socket.on("start", (fen, whiteSocketId) =>
callback(fen, socket.id === whiteSocketId)
);
}

export function onUpdate(callback: (fen: string, lastMove: string) => void) {
socket.on("update", callback);
}
Loading

0 comments on commit 76afc49

Please sign in to comment.