Implemented normal game mod with winning and losing

This commit is contained in:
Andrew 2023-03-04 03:44:51 +07:00
parent 79d439e10a
commit 943af813e6
3 changed files with 357 additions and 10 deletions

View file

@ -6,7 +6,9 @@
"scripts": { "scripts": {
"build": "npx tsc", "build": "npx tsc",
"start": "node dist/index.js", "start": "node dist/index.js",
"dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"" "dev": "concurrently \"npx tsc --watch\" \"nodemon -q dist/index.js\"",
"buildDocker": "docker build -t nuark/huacu_server:latest .",
"pushDocker": "docker push nuark/huacu_server:latest"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",

View file

@ -5,6 +5,8 @@ import { v4 as uuidv4 } from "uuid";
import { Server, Socket } from "socket.io"; import { Server, Socket } from "socket.io";
import { instrument } from "@socket.io/admin-ui"; import { instrument } from "@socket.io/admin-ui";
import { pallette, availableColors } from "./pallette";
const app = express(); const app = express();
const server = http.createServer(app); const server = http.createServer(app);
@ -53,20 +55,36 @@ class Game {
private player1: Client; private player1: Client;
private player2: Client; private player2: Client;
private guesses: Set<String>;
private colors: Set<String>;
public get Id() { public get Id() {
return this.id; return this.id;
} }
public get Player1() { public get Guesser() {
return this.player1; return this.player1;
} }
public get Player2() { public get Suggester() {
return this.player2; return this.player2;
} }
public get Guesses() {
return this.guesses;
}
public get Colors() {
return this.colors;
}
constructor(id: String, player1: Client, player2: Client) { constructor(id: String, player1: Client, player2: Client) {
this.id = id; this.id = id;
this.player1 = player1; this.player1 = player1;
this.player2 = player2; this.player2 = player2;
this.guesses = new Set<String>();
this.colors = new Set<String>();
while (this.colors.size < 6) {
const key = availableColors[Math.floor(Math.random() * availableColors.length)];
this.colors.add(key);
}
} }
public Opponent(player: Client): Client { public Opponent(player: Client): Client {
@ -76,6 +94,35 @@ class Game {
return this.player1; return this.player1;
} }
public Guess(player: Client, guess: String) {
if (this.guesses.has(guess)) {
return true;
}
this.guesses.add(guess);
const opponent = this.Opponent(player);
const opponentSocket = Array.from(onlineClients.keys()).find((socket) => onlineClients.get(socket) === opponent);
if (opponentSocket) {
opponentSocket.emit("guess", guess);
} else {
console.log("opponent socket not found");
return false;
}
return true;
}
public GameWon() {
for (const color of this.colors) {
if (!this.guesses.has(color)) {
return false;
}
}
return true;
}
public GameLost() {
return this.guesses.size >= 10;
}
public simplify() { public simplify() {
return { return {
id: this.id, id: this.id,
@ -115,6 +162,10 @@ app.get("/", (req, res) => {
res.send("<h1>Hello world</h1>"); res.send("<h1>Hello world</h1>");
}); });
app.get("/pallette", (req, res) => {
res.json(pallette);
});
io.on("connection", (socket) => { io.on("connection", (socket) => {
console.log("someone connected"); console.log("someone connected");
@ -269,14 +320,22 @@ io.on("connection", (socket) => {
socket.emit("requestResponseResult", false, 404); socket.emit("requestResponseResult", false, 404);
return; return;
} }
const otherClient = onlineClients.get(otherClientSocket)!;
if (response) { if (response) {
const game = new Game(uuidv4(), client, onlineClients.get(otherClientSocket)!); const isClientInGuessers = guessersRoom.availablePlayers.has(client.login);
guessersRoom.removePlayer(client);
suggestersRoom.removePlayer(client);
guessersRoom.removePlayer(otherClient);
suggestersRoom.removePlayer(otherClient);
io.emit("updateNeeded");
const game = new Game(uuidv4(), isClientInGuessers ? client : otherClient, isClientInGuessers ? otherClient : client);
runningGames.set(game.Id, game); runningGames.set(game.Id, game);
client.setInGame(true); client.setInGame(true);
onlineClients.get(otherClientSocket)!.setInGame(true); otherClient.setInGame(true);
socket.emit("requestResponseResult", true, game.simplify()); socket.emit("requestResponseResult", true, game.simplify(), Array.from(game.Guesses));
otherClientSocket.emit("requestResponseResult", true, game.simplify()); otherClientSocket.emit("requestResponseResult", true, game.simplify(), Array.from(game.Colors));
} else { } else {
socket.emit("requestResponseResult", false, `You declined ${client.login} request`); socket.emit("requestResponseResult", false, `You declined ${client.login} request`);
otherClientSocket.emit("requestResponseResult", false, `${client.login} declined your request`); otherClientSocket.emit("requestResponseResult", false, `${client.login} declined your request`);
@ -317,6 +376,87 @@ io.on("connection", (socket) => {
}); });
}); });
socket.on("guess", (gameId, guess) => {
const client = onlineClients.get(socket);
if (client === undefined) {
socket.emit("guessResponse", false, 403);
return;
}
const game = runningGames.get(gameId);
if (game === undefined || !client.inGame) {
socket.emit("guessResponse", false, 400);
console.log("user " + client.login + " tried to guess in non existing game");
return;
}
if (game.Guesser.login !== client.login) {
socket.emit("guessResponse", false, 400);
console.log("user " + client.login + " tried to guess in game he is not guessing in");
return;
}
if (!game.Guess(client, guess)) {
socket.emit("guessResponse", false, 400);
console.log("user " + client.login + " tried to guess but something gone terribly wrong");
return;
}
const opponentPlayer = game.Opponent(client);
const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === opponentPlayer.login)!;
if (game.GameWon()) {
console.log(`game ${gameId} won by ${client.login} and ${opponentPlayer.login}`);
socket.emit("gameStatus", [true]);
otherClientSocket.emit("gameStatus", [true]);
client.setInGame(false);
opponentPlayer.setInGame(false);
runningGames.delete(gameId);
return;
}
if (game.GameLost()) {
console.log(`game ${gameId} lost by ${client.login} and ${opponentPlayer.login}`);
socket.emit("gameStatus", [false]);
otherClientSocket.emit("gameStatus", [false]);
client.setInGame(false);
opponentPlayer.setInGame(false);
runningGames.delete(gameId);
}
});
socket.on("leaveGame", (gameId) => {
const client = onlineClients.get(socket);
if (client === undefined) {
socket.emit("guessResponse", false, 403);
return;
}
const game = runningGames.get(gameId);
if (game === undefined || !client.inGame) {
socket.emit("guessResponse", false, 400);
console.log("user " + client.login + " tried to guess in non existing game");
return;
}
socket.emit("leaveGameResponse", true, 200);
const opponentPlayer = game.Opponent(client);
const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === opponentPlayer.login);
if (otherClientSocket !== undefined) {
otherClientSocket.emit("leaveGameResponse", true, 410);
}
client.setInGame(false);
opponentPlayer.setInGame(false);
runningGames.delete(game.Id);
});
socket.on("disconnect", () => { socket.on("disconnect", () => {
const client = onlineClients.get(socket); const client = onlineClients.get(socket);
if (client !== undefined) { if (client !== undefined) {
@ -324,14 +464,15 @@ io.on("connection", (socket) => {
guessersRoom.removePlayer(client); guessersRoom.removePlayer(client);
suggestersRoom.removePlayer(client); suggestersRoom.removePlayer(client);
if (client.inGame) { if (client.inGame) {
const game = Array.from(runningGames.values()).find((game) => game.Player1 === client || game.Player2 === client); const game = Array.from(runningGames.values()).find((game) => game.Guesser === client || game.Suggester === client);
if (game !== undefined) { if (game !== undefined) {
const opponentPlayer = game.Opponent(client); const opponentPlayer = game.Opponent(client);
const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === opponentPlayer.login); const otherClientSocket = Array.from(onlineClients.keys()).find((key) => onlineClients.get(key)?.login === opponentPlayer.login);
if (otherClientSocket !== undefined) { if (otherClientSocket !== undefined) {
// TODO: For now chatResponse used otherClientSocket.emit("leaveGameResponse", true, 410);
otherClientSocket.emit("chatResponse", false, 410);
} }
client.setInGame(false);
opponentPlayer.setInGame(false);
runningGames.delete(game.Id); runningGames.delete(game.Id);
} }

204
src/pallette.ts Normal file
View file

@ -0,0 +1,204 @@
export const pallette = {
A0: [0, 0, 186],
A1: [0, 26, 186],
A2: [0, 51, 186],
A3: [0, 77, 186],
A4: [0, 102, 186],
A5: [0, 128, 186],
A6: [0, 153, 186],
A7: [0, 179, 186],
A8: [0, 204, 186],
A9: [0, 230, 186],
B0: [13, 0, 186],
B1: [13, 26, 186],
B2: [13, 51, 186],
B3: [13, 77, 186],
B4: [13, 102, 186],
B5: [13, 128, 186],
B6: [13, 153, 186],
B7: [13, 179, 186],
B8: [13, 204, 186],
B9: [13, 230, 186],
C0: [26, 0, 186],
C1: [26, 26, 186],
C2: [26, 51, 186],
C3: [26, 77, 186],
C4: [26, 102, 186],
C5: [26, 128, 186],
C6: [26, 153, 186],
C7: [26, 179, 186],
C8: [26, 204, 186],
C9: [26, 230, 186],
D0: [38, 0, 186],
D1: [38, 26, 186],
D2: [38, 51, 186],
D3: [38, 77, 186],
D4: [38, 102, 186],
D5: [38, 128, 186],
D6: [38, 153, 186],
D7: [38, 179, 186],
D8: [38, 204, 186],
D9: [38, 230, 186],
E0: [51, 0, 186],
E1: [51, 26, 186],
E2: [51, 51, 186],
E3: [51, 77, 186],
E4: [51, 102, 186],
E5: [51, 128, 186],
E6: [51, 153, 186],
E7: [51, 179, 186],
E8: [51, 204, 186],
E9: [51, 230, 186],
F0: [64, 0, 186],
F1: [64, 26, 186],
F2: [64, 51, 186],
F3: [64, 77, 186],
F4: [64, 102, 186],
F5: [64, 128, 186],
F6: [64, 153, 186],
F7: [64, 179, 186],
F8: [64, 204, 186],
F9: [64, 230, 186],
G0: [77, 0, 186],
G1: [77, 26, 186],
G2: [77, 51, 186],
G3: [77, 77, 186],
G4: [77, 102, 186],
G5: [77, 128, 186],
G6: [77, 153, 186],
G7: [77, 179, 186],
G8: [77, 204, 186],
G9: [77, 230, 186],
H0: [89, 0, 186],
H1: [89, 26, 186],
H2: [89, 51, 186],
H3: [89, 77, 186],
H4: [89, 102, 186],
H5: [89, 128, 186],
H6: [89, 153, 186],
H7: [89, 179, 186],
H8: [89, 204, 186],
H9: [89, 230, 186],
I0: [102, 0, 186],
I1: [102, 26, 186],
I2: [102, 51, 186],
I3: [102, 77, 186],
I4: [102, 102, 186],
I5: [102, 128, 186],
I6: [102, 153, 186],
I7: [102, 179, 186],
I8: [102, 204, 186],
I9: [102, 230, 186],
J0: [115, 0, 186],
J1: [115, 26, 186],
J2: [115, 51, 186],
J3: [115, 77, 186],
J4: [115, 102, 186],
J5: [115, 128, 186],
J6: [115, 153, 186],
J7: [115, 179, 186],
J8: [115, 204, 186],
J9: [115, 230, 186],
K0: [128, 0, 186],
K1: [128, 26, 186],
K2: [128, 51, 186],
K3: [128, 77, 186],
K4: [128, 102, 186],
K5: [128, 128, 186],
K6: [128, 153, 186],
K7: [128, 179, 186],
K8: [128, 204, 186],
K9: [128, 230, 186],
L0: [140, 0, 186],
L1: [140, 26, 186],
L2: [140, 51, 186],
L3: [140, 77, 186],
L4: [140, 102, 186],
L5: [140, 128, 186],
L6: [140, 153, 186],
L7: [140, 179, 186],
L8: [140, 204, 186],
L9: [140, 230, 186],
M0: [153, 0, 186],
M1: [153, 26, 186],
M2: [153, 51, 186],
M3: [153, 77, 186],
M4: [153, 102, 186],
M5: [153, 128, 186],
M6: [153, 153, 186],
M7: [153, 179, 186],
M8: [153, 204, 186],
M9: [153, 230, 186],
N0: [166, 0, 186],
N1: [166, 26, 186],
N2: [166, 51, 186],
N3: [166, 77, 186],
N4: [166, 102, 186],
N5: [166, 128, 186],
N6: [166, 153, 186],
N7: [166, 179, 186],
N8: [166, 204, 186],
N9: [166, 230, 186],
O0: [179, 0, 186],
O1: [179, 26, 186],
O2: [179, 51, 186],
O3: [179, 77, 186],
O4: [179, 102, 186],
O5: [179, 128, 186],
O6: [179, 153, 186],
O7: [179, 179, 186],
O8: [179, 204, 186],
O9: [179, 230, 186],
P0: [191, 0, 186],
P1: [191, 26, 186],
P2: [191, 51, 186],
P3: [191, 77, 186],
P4: [191, 102, 186],
P5: [191, 128, 186],
P6: [191, 153, 186],
P7: [191, 179, 186],
P8: [191, 204, 186],
P9: [191, 230, 186],
Q0: [204, 0, 186],
Q1: [204, 26, 186],
Q2: [204, 51, 186],
Q3: [204, 77, 186],
Q4: [204, 102, 186],
Q5: [204, 128, 186],
Q6: [204, 153, 186],
Q7: [204, 179, 186],
Q8: [204, 204, 186],
Q9: [204, 230, 186],
R0: [217, 0, 186],
R1: [217, 26, 186],
R2: [217, 51, 186],
R3: [217, 77, 186],
R4: [217, 102, 186],
R5: [217, 128, 186],
R6: [217, 153, 186],
R7: [217, 179, 186],
R8: [217, 204, 186],
R9: [217, 230, 186],
S0: [230, 0, 186],
S1: [230, 26, 186],
S2: [230, 51, 186],
S3: [230, 77, 186],
S4: [230, 102, 186],
S5: [230, 128, 186],
S6: [230, 153, 186],
S7: [230, 179, 186],
S8: [230, 204, 186],
S9: [230, 230, 186],
T0: [242, 0, 186],
T1: [242, 26, 186],
T2: [242, 51, 186],
T3: [242, 77, 186],
T4: [242, 102, 186],
T5: [242, 128, 186],
T6: [242, 153, 186],
T7: [242, 179, 186],
T8: [242, 204, 186],
T9: [242, 230, 186],
};
export const availableColors = Object.keys(pallette);