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 Client from './Client';
|
||||||
import logSocket from './logSocket';
|
import logSocket from './logSocket';
|
||||||
|
@ -9,6 +9,7 @@ class Player {
|
||||||
game: Game;
|
game: Game;
|
||||||
client: Client;
|
client: Client;
|
||||||
cards: Card[] = [];
|
cards: Card[] = [];
|
||||||
|
stack: Card[] = [];
|
||||||
disconnected = false;
|
disconnected = false;
|
||||||
disconnectListener?: () => void;
|
disconnectListener?: () => void;
|
||||||
rank = 0;
|
rank = 0;
|
||||||
|
@ -17,7 +18,6 @@ class Player {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
sendGameState() {
|
sendGameState() {
|
||||||
this.cards.sort(cmpCard);
|
|
||||||
const i = this.game.players.indexOf(this);
|
const i = this.game.players.indexOf(this);
|
||||||
const otherPlayers = [];
|
const otherPlayers = [];
|
||||||
for (let j = 1; j < this.game.players.length; ++j)
|
for (let j = 1; j < this.game.players.length; ++j)
|
||||||
|
@ -30,6 +30,7 @@ class Player {
|
||||||
numCards: p.cards.length,
|
numCards: p.cards.length,
|
||||||
rank: p.rank,
|
rank: p.rank,
|
||||||
})),
|
})),
|
||||||
|
phase: this.game.phase,
|
||||||
lastPlayed: this.game.lastPlayed,
|
lastPlayed: this.game.lastPlayed,
|
||||||
lastPlayedPlayer: this.game.lastPlayedPlayer < 0 ? null : this.game.players[this.game.lastPlayedPlayer].client.username,
|
lastPlayedPlayer: this.game.lastPlayedPlayer < 0 ? null : this.game.players[this.game.lastPlayedPlayer].client.username,
|
||||||
playerTurn: this.game.players[this.game.playerTurn].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 < 2) {
|
||||||
if (playersLeft.length === 1)
|
if (playersLeft.length === 1)
|
||||||
playersLeft[0].rank = ++this.playersFinished;
|
playersLeft[0].rank = ++this.playersFinished; // rank is reversed, fix later
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await this.round();
|
await this.round();
|
||||||
|
@ -93,33 +94,56 @@ export default class Game {
|
||||||
}
|
}
|
||||||
async round() {
|
async round() {
|
||||||
this.phase = 0;
|
this.phase = 0;
|
||||||
await this.prepare();
|
await this.prepare(); // Phase 0
|
||||||
this.phase = 1;
|
this.phase = 1;
|
||||||
while (true) {
|
this.lastPlayed = 0;
|
||||||
|
while (true) { // Phase 1
|
||||||
const p = this.players[this.playerTurn];
|
const p = this.players[this.playerTurn];
|
||||||
if (p.rank || p.disconnected) {
|
if (p.rank || p.disconnected) {
|
||||||
this.playerTurn = (this.playerTurn + 1) % this.players.length;
|
this.playerTurn = (this.playerTurn + 1) % this.players.length;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let result = await this.turn();
|
await this.turn();
|
||||||
if (result === false) break; // Called BS!
|
if (this.phase === 2) break; // Called BS!
|
||||||
this.lastPlayedPlayer = this.playerTurn;
|
this.lastPlayedPlayer = this.playerTurn;
|
||||||
this.playerTurn = (this.playerTurn + 1) % this.players.length;
|
this.playerTurn = (this.playerTurn + 1) % this.players.length;
|
||||||
}
|
}
|
||||||
this.phase = 2;
|
while (this.lastPlayed > 0) { // Phase 2
|
||||||
while (this.lastPlayed > 0) {
|
await this.flip();
|
||||||
let result = await this.flip();
|
if (this.phase === 3) { // Oops, flipped over a red card!
|
||||||
if (result === false) { // 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();
|
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];
|
const p = this.players[this.playerTurn];
|
||||||
this.broadcastGameState();
|
this.broadcastGameState();
|
||||||
await new Promise<void>(resolve => {
|
await new Promise<void>(resolve => {
|
||||||
|
@ -127,11 +151,12 @@ export default class Game {
|
||||||
delete p.disconnectListener;
|
delete p.disconnectListener;
|
||||||
(() => {
|
(() => {
|
||||||
if (num === -1) {
|
if (num === -1) {
|
||||||
return false; // Called BS!
|
this.phase = 2; // Called BS, move on to the next phase!
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (num > this.lastPlayed) {
|
if (num > this.lastPlayed) {
|
||||||
this.lastPlayed = num;
|
this.lastPlayed = num;
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
p.client.socket.disconnect();
|
p.client.socket.disconnect();
|
||||||
logSocket(p.client.socket, 'Bad cards argument on turn');
|
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];
|
const p = this.players[this.lastPlayedPlayer];
|
||||||
this.broadcastGameState();
|
this.broadcastGameState();
|
||||||
await new Promise<void>(resolve => {
|
await new Promise<void>(resolve => {
|
||||||
p.client.once('turn', selectedPlayer => {
|
p.client.once('turn', selectedPlayer => {
|
||||||
delete p.disconnectListener;
|
delete p.disconnectListener;
|
||||||
(() => {
|
(() => {
|
||||||
if (this.players[selectedPlayer].cards === -1) {
|
if (this.players[selectedPlayer].stack.length > 0) {
|
||||||
return false;
|
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();
|
p.client.socket.disconnect();
|
||||||
logSocket(p.client.socket, 'Bad cards argument on turn');
|
logSocket(p.client.socket, 'Bad cards argument on turn');
|
||||||
})();
|
})();
|
||||||
|
@ -163,7 +190,27 @@ export default class Game {
|
||||||
});
|
});
|
||||||
p.disconnectListener = () => {
|
p.disconnectListener = () => {
|
||||||
delete 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();
|
resolve();
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue