Skip to content

Commit

Permalink
Merge pull request #20 from yuru-baku/feature/game-connection
Browse files Browse the repository at this point in the history
Feature/game connection
  • Loading branch information
some-random-int authored Feb 21, 2024
2 parents b19eefa + d58bf7c commit 31234d1
Show file tree
Hide file tree
Showing 72 changed files with 698 additions and 497 deletions.
9 changes: 5 additions & 4 deletions backend/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { MongoClient } from 'mongodb';
import { Db, MongoClient } from 'mongodb';
import { WebSocket, WebSocketServer } from 'ws';
import { Room } from './models/room.js';
import { User } from './models/user.js';
Expand All @@ -8,9 +8,10 @@ const dbName = 'InfinityDeck';

async function main() {
// Use connect method to connect to the server
await client.connect();
console.log('Connected successfully to database...');
const db = client.db(dbName);
// await client.connect();
// console.log('Connected successfully to database...');
// const db = client.db(dbName);
const db = undefined;

const rooms = new Map();
const wss = new WebSocketServer({ port: 8080 });
Expand Down
44 changes: 23 additions & 21 deletions backend/src/models/MauMau.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Room } from "./room";
import { Room, WsMessage } from "./room";
import { User } from "./user";

export class MauMau {
Expand All @@ -17,10 +17,10 @@ export class MauMau {
constructor (room: Room) {
this.room = room;
this.deck = [
'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'cj', 'cq', 'ck', 'ca',
'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'dj', 'dq', 'dk', 'da',
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'h9', 'hj', 'hq', 'hk', 'ha',
's1', 's2', 's3', 's4', 's5', 's6', 's7', 's8', 's9', 'sj', 'sq', 'sk', 'sa',
'clubs-1', 'clubs-2', 'clubs-3', 'clubs-4', 'clubs-5', 'clubs-6', 'clubs-7', 'clubs-8', 'clubs-9', 'clubs-jack', 'clubs-queen', 'clubs-king', 'clubs-ace',
'diamonds-1', 'diamonds-2', 'diamonds-3', 'diamonds-4', 'diamonds-5', 'diamonds-6', 'diamonds-7', 'diamonds-8', 'diamonds-9', 'diamonds-jack', 'diamonds-queen', 'diamonds-king', 'diamonds-ace',
'hearts-1', 'hearts-2', 'hearts-3', 'hearts-4', 'hearts-5', 'hearts-6', 'hearts-7', 'hearts-8', 'hearts-9', 'hearts-jack', 'hearts-queen', 'hearts-king', 'hearts-ace',
'spades-1', 'spades-2', 'spades-3', 'spades-4', 'spades-5', 'spades-6', 'spades-7', 'spades-8', 'spades-9', 'spades-jack', 'spades-queen', 'spades-king', 'spades-ace',
]; // All cards of this deck
this.playedCards = [ ];
this.drawPile = [ ]; // "Nachziehstapel"
Expand All @@ -37,6 +37,7 @@ export class MauMau {
return;
}
this.startTime = new Date();
this.room.state = 'inGame';
this.drawPile = [...this.deck]; // copy array
this.shuffleArray(this.drawPile);
// give users some handcards
Expand Down Expand Up @@ -69,16 +70,16 @@ export class MauMau {
leaderboard: leaderboard
});
// finally persist and close
this.room.db.collection('MauMau-Games').insertOne({
leaderboard: leaderboard,
history: this.history,
startTiem: this.startTime,
endTime: this.endTime,
users: this.room.users.map(user => { return { name: user.name, id: user.id, handcards: user.handcards }})
});
// this.room.db.collection('MauMau-Games').insertOne({
// leaderboard: leaderboard,
// history: this.history,
// startTiem: this.startTime,
// endTime: this.endTime,
// users: this.room.users.map(user => { return { name: user.name, id: user.id, handcards: user.handcards }})
// });
}

drawCard(user: User, _: any) {
drawCard(user: User, message: WsMessage) {
// check if it is the users turn
if (this.room.users[this.turn] !== user) {
user.ws.send(JSON.stringify({ error: 'It is not your turn!' }));
Expand All @@ -88,28 +89,29 @@ export class MauMau {
if (this.drawPile.length <= 0) {
this.shuffleDrawPile();
}
const newCard = this.drawPile.pop()!;
user.handcards.unshift(newCard);
const card = this.drawPile.pop()!;
user.handcards.unshift(card);
user.ws.send(JSON.stringify({
action: 'drawCard',
data: {
newCard: newCard,
card: card,
markerId: message.data.markerId,
handcards: user.handcards,
nextActions: [ 'endTurn', 'playCard' ]
}
}));
this.history.unshift(`+${user.id}:${newCard}`);
this.history.unshift(`+${user.id}:${card}`);
// do not hand to next user now, wait if he can play now
}

playCard(user: User, data: any) {
playCard(user: User, message: WsMessage) {
// check if it is the users turn
if (this.room.users[this.turn] !== user) {
user.ws.send(JSON.stringify({ error: 'It is not your turn!' }));
return;
}
// check if user has this card in his hand
const cardIndex = user.handcards.findIndex(card => card === data.card);
const cardIndex = user.handcards.findIndex(card => card === message.data.card);
if (cardIndex < 0) {
user.ws.send(JSON.stringify({ error: 'The Server did not know you own this card. Please play another one' }));
return;
Expand All @@ -126,10 +128,10 @@ export class MauMau {
this.history.unshift(`${user.id}:finished`)
}
// hand to next user
this.endTurn(user, data);
this.endTurn(user, message);
}

endTurn(user: User, _: any) {
endTurn(user: User, _: WsMessage) {
// check if it is the users turn
if (this.room.users[this.turn] !== user) {
user.ws.send(JSON.stringify({ error: 'It is not your turn!' }));
Expand Down
63 changes: 46 additions & 17 deletions backend/src/models/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@ import { Db } from "mongodb";
import { MauMau } from "./MauMau";
import { User } from "./user";

export type WsMessage = {
action: string,
data: any
}

export class Room {

id: string;
users: User[];
state: 'initialising'|'inGame';
selectedGame: 'MauMau';
game: MauMau;
db: Db;
db: Db|undefined;
isLocal: boolean;

constructor(db: Db, id?: string) {
constructor(db?: Db, id?: string) {
this.id = id || 'room_' + (Math.random() + 1).toString(36).substring(7);
this.users = []; // Users taking part in this game
this.state = 'initialising';
this.selectedGame = 'MauMau';
this.game = new MauMau(this);
this.db = db;
this.isLocal = true;
}

join(user: User) {
Expand Down Expand Up @@ -66,13 +73,13 @@ export class Room {
'getRoomInfo',
];
user.ws.on('message', (msg: string) => {
const data: any = JSON.parse(msg);
if (availableActions.includes(data.action)) {
const message: any = JSON.parse(msg);
if (availableActions.includes(message.action)) {
// @ts-ignore
this.game[data.action](user, data);
} else if (availableRoomActions.includes(data.action)){
this.game[message.action](user, message);
} else if (availableRoomActions.includes(message.action)){
// @ts-ignore
this[data.action](user, data);
this[message.action](user, message);
}
});
}
Expand All @@ -87,15 +94,16 @@ export class Room {
];
const availableRoomActions = [
'selectGame',
'changeSettings'
];
user.ws.on('message', (msg: string) => {
const data: any = JSON.parse(msg);
if (availableGameActions.includes(data.action)) {
const message: any = JSON.parse(msg);
if (availableGameActions.includes(message.action)) {
// @ts-ignore
this.game[data.action](user, data);
} else if (availableRoomActions.includes(data.action)){
this.game[message.action](user, message);
} else if (availableRoomActions.includes(message.action)){
// @ts-ignore
this[data.action](user, data);
this[message.action](user, message);
}
});
}
Expand Down Expand Up @@ -134,11 +142,15 @@ export class Room {
user.ws.send(JSON.stringify({
action: 'gotRoomInfo',
data: {
you: { name: user.name, isOwner: user.isOwner, id: user.id },
isLocal: false,
selectedGame: this.selectedGame,
state: this.state,
users: this.getUserInformations()
you: { name: user.name, isOwner: user.isOwner, id: user.id, handcards: user.handcards },
room: {
isLocal: false,
selectedGame: this.selectedGame,
state: this.state,
users: this.getUserInformations(),
id: this.id,
},
game: { ...this.game, room: undefined }
}
}))
}
Expand All @@ -147,6 +159,23 @@ export class Room {
// ToDo add multiple games
}

changeSettings(user: User, message: { action: 'changeSettings', data: { isLocal: boolean }}) {
if (!user.isOwner) {
user.ws.send(JSON.stringify({ error: 'Only the owner of this room might perform this action!' }));
return;
}
this.isLocal = message.data.isLocal || false;
this.users
.forEach(u => {
u.ws.send(JSON.stringify({
action: 'settingsChanged',
data: {
isLocal: this.isLocal
}
}));
});
}

getUserInformations(): { name: string, isOwner: boolean, id: string, disconnected: boolean }[] {
return this.users.map(user => { return { name: user.name, isOwner: user.isOwner, id: user.id, disconnected: user.timeout !== undefined }})
}
Expand Down
4 changes: 1 addition & 3 deletions backend/src/models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ export class User {
id: string;
name: string;
handcards: string[];
isLocal: boolean;
isOwner: boolean;
timeout: NodeJS.Timeout|undefined;

constructor(ws: WebSocket, id: string|undefined, name: string|undefined, isLocal: boolean = false) {
constructor(ws: WebSocket, id: string|undefined, name: string|undefined) {
this.ws = ws;
if (id) {
this.id = id;
Expand All @@ -23,7 +22,6 @@ export class User {
this.name = 'name_' + (Math.random() + 1).toString(36).substring(7);
}
this.handcards = [];
this.isLocal = isLocal;
this.isOwner = false;
}
}
Loading

0 comments on commit 31234d1

Please sign in to comment.