aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Wang2021-05-06 20:22:30 -0500
committerAnthony Wang2021-05-06 20:22:30 -0500
commit72692614391a0eb116bf19886693a638a40971c7 (patch)
tree36cae87401a70d32b6afd9b222168a0e7303cc5b
parent3ae7abec050a18d54aa1e1f78a03a714b4ee4308 (diff)
Finished implementing everything except prepare
-rw-r--r--back/src/Game.ts91
1 files changed, 69 insertions, 22 deletions
diff --git a/back/src/Game.ts b/back/src/Game.ts
index 028dd21..4643da6 100644
--- a/back/src/Game.ts
+++ b/back/src/Game.ts
@@ -1,4 +1,4 @@
-import {canPlay, Card, cmpCard, Suit} from 'bsx-core';
+import {Card, Suit} from 'bsx-core';
import Client from './Client';
import logSocket from './logSocket';
@@ -9,6 +9,7 @@ class Player {
game: Game;
client: Client;
cards: Card[] = [];
+ stack: Card[] = [];
disconnected = false;
disconnectListener?: () => void;
rank = 0;
@@ -17,7 +18,6 @@ class Player {
this.client = client;
}
sendGameState() {
- this.cards.sort(cmpCard);
const i = this.game.players.indexOf(this);
const otherPlayers = [];
for (let j = 1; j < this.game.players.length; ++j)
@@ -30,6 +30,7 @@ class Player {
numCards: p.cards.length,
rank: p.rank,
})),
+ phase: this.game.phase,
lastPlayed: this.game.lastPlayed,
lastPlayedPlayer: this.game.lastPlayedPlayer < 0 ? null : this.game.players[this.game.lastPlayedPlayer].client.username,
playerTurn: this.game.players[this.game.playerTurn].client.username
@@ -76,7 +77,7 @@ export default class Game {
});
if (playersLeft.length < 2) {
if (playersLeft.length === 1)
- playersLeft[0].rank = ++this.playersFinished;
+ playersLeft[0].rank = ++this.playersFinished; // rank is reversed, fix later
break;
}
await this.round();
@@ -93,33 +94,56 @@ export default class Game {
}
async round() {
this.phase = 0;
- await this.prepare();
+ await this.prepare(); // Phase 0
this.phase = 1;
- while (true) {
+ this.lastPlayed = 0;
+ while (true) { // Phase 1
const p = this.players[this.playerTurn];
if (p.rank || p.disconnected) {
this.playerTurn = (this.playerTurn + 1) % this.players.length;
continue;
}
- let result = await this.turn();
- if (result === false) break; // Called BS!
+ await this.turn();
+ if (this.phase === 2) break; // Called BS!
this.lastPlayedPlayer = this.playerTurn;
this.playerTurn = (this.playerTurn + 1) % this.players.length;
}
- this.phase = 2;
- while (this.lastPlayed > 0) {
- let result = await this.flip();
- if (result === false) { // Oops, flipped over a red card
-
+ while (this.lastPlayed > 0) { // Phase 2
+ await this.flip();
+ if (this.phase === 3) { // Oops, flipped over a red card!
+ await this.giveup(); // The player who called BS won and now the challenged player must give up a card!
+ return;
}
}
- this.lastPlayed = 0;
+ await this.giveup(); // The player who called BS won and now they must give up a card!
}
- async prepare() {
+ async prepare() { // Players prepare their hand for this round
this.broadcastGameState();
+ const playerPromises = [];
+ for (let i = 0; i < this.room.clients.length; ++i) {
+ const p = this.players[i];
+ if (p.rank || p.disconnected) continue;
+ playerPromises.push(new Promise<void>(resolve => {
+ p.client.once('prepare', order => {
+ delete p.disconnectListener;
+ (() => {
+
+ p.client.socket.disconnect();
+ logSocket(p.client.socket, 'Bad cards argument on turn');
+ })();
+ resolve();
+ });
+ p.disconnectListener = () => {
+ delete p.disconnectListener;
+ p.client.removeAllListeners('prepare');
+ resolve();
+ };
+ }));
+ }
+ await Promise.all(playerPromises);
}
- async turn() {
+ async turn() { // Do a turn
const p = this.players[this.playerTurn];
this.broadcastGameState();
await new Promise<void>(resolve => {
@@ -127,11 +151,12 @@ export default class Game {
delete p.disconnectListener;
(() => {
if (num === -1) {
- return false; // Called BS!
+ this.phase = 2; // Called BS, move on to the next phase!
+ return;
}
if (num > this.lastPlayed) {
this.lastPlayed = num;
- return true;
+ return;
}
p.client.socket.disconnect();
logSocket(p.client.socket, 'Bad cards argument on turn');
@@ -145,17 +170,19 @@ export default class Game {
};
});
}
- async flip() {
+ async flip() { // Someone called BS and now the challenged player must flip over a card
const p = this.players[this.lastPlayedPlayer];
this.broadcastGameState();
await new Promise<void>(resolve => {
p.client.once('turn', selectedPlayer => {
delete p.disconnectListener;
(() => {
- if (this.players[selectedPlayer].cards === -1) {
- return false;
+ if (this.players[selectedPlayer].stack.length > 0) {
+ if (this.players[selectedPlayer].stack[0].suit === Suit.Diamonds ||
+ this.players[selectedPlayer].stack[0].suit === Suit.Hearts) this.phase = 3; // Red card
+ this.players[selectedPlayer].stack.splice(0);
+ return;
}
-
p.client.socket.disconnect();
logSocket(p.client.socket, 'Bad cards argument on turn');
})();
@@ -163,7 +190,27 @@ export default class Game {
});
p.disconnectListener = () => {
delete p.disconnectListener;
- p.client.removeAllListeners('turn');
+ p.client.removeAllListeners('flip');
+ resolve();
+ };
+ });
+ }
+ async giveup() { // Give up a card
+ const p = this.players[this.lastPlayed ? this.lastPlayedPlayer : this.playerTurn];
+ this.broadcastGameState();
+ await new Promise<void>(resolve => {
+ p.client.once('giveup', card => {
+ delete p.disconnectListener;
+ (() => {
+ p.cards.splice(card); // Remove card, may want to check if it is valid
+ p.client.socket.disconnect();
+ logSocket(p.client.socket, 'Bad cards argument on turn');
+ })();
+ resolve();
+ });
+ p.disconnectListener = () => {
+ delete p.disconnectListener;
+ p.client.removeAllListeners('giveup');
resolve();
};
});