Finished implementing everything except prepare
This commit is contained in:
parent
3ae7abec05
commit
7269261439
1 changed files with 69 additions and 22 deletions
|
@ -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();
|
||||
};
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue