Basic bot support and option to change opening text
This commit is contained in:
1 parent
7bc9d67544
commit
499a5954f5
7 files changed
+264
-13
No files matched your search
@@ -5,6 +5,7 @@ const path = require('path');
|
||||
const cookieParser = require('cookie-parser');
|
||||
//const { v4: uuidv4 } = require('uuid');
|
||||
const { randomUUID } = require('node:crypto');
|
||||
const BotFactory = require('./bots/BotFactory');
|
||||
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
@@ -25,8 +26,10 @@ class YarnGame {
|
||||
this.gameSettings = {
|
||||
scoreLimit: 50,
|
||||
timeLimit: 60,
|
||||
botCount: 0
|
||||
botCount: 0,
|
||||
startText: "It was a dark and stormy night..."
|
||||
};
|
||||
this.bots = [];
|
||||
this.players = []; // { player_id, name, score, socketId }
|
||||
this.disconnectedPlayers = []; // So people can keep their score when they reconnect
|
||||
this.yarnStory = []; // { player: "", str: "" }
|
||||
@@ -78,20 +81,23 @@ class YarnGame {
|
||||
removePlayer(playerId) {
|
||||
const index = this.players.findIndex(p => p.player_id === playerId);
|
||||
if (index !== -1) {
|
||||
console.log(`Player ${this.players[index].name} dropped.`)
|
||||
const removed = this.players.splice(index, 1);
|
||||
this.disconnectedPlayers.push(removed[0]);
|
||||
|
||||
// Assign new host if host left
|
||||
if (this.gameHost === playerId && this.players.length > 0) {
|
||||
this.gameHost = this.players[0].player_id;
|
||||
if (this.gameHost === playerId && this.getHumanPlayers().length > 0) {
|
||||
const human_players = this.getHumanPlayers();
|
||||
this.gameHost = human_players[0].player_id;
|
||||
}
|
||||
}
|
||||
if (this.players.length > 0) {
|
||||
console.log(`Player ${this.players[index].name} dropped.`)
|
||||
}
|
||||
return this.players.length;
|
||||
}
|
||||
|
||||
getHumanPlayers() {
|
||||
return this.players.filter(p => !this.bots.some(b => b.bot_id === p.player_id));
|
||||
}
|
||||
|
||||
getPlayer(playerId) {
|
||||
return this.players.find(p => p.player_id === playerId);
|
||||
}
|
||||
@@ -107,19 +113,49 @@ class YarnGame {
|
||||
}
|
||||
}
|
||||
|
||||
startBots(botCount) {
|
||||
console.log("Creating bots...")
|
||||
for (let i = 0; i < botCount; i++) {
|
||||
const bot_id = randomUUID()
|
||||
const bot = BotFactory.createBot("random");
|
||||
this.bots.push({ bot_id, bot });
|
||||
const bot_player = {
|
||||
player_id: bot_id,
|
||||
name: BotFactory.generateBotName(),
|
||||
score: 0,
|
||||
socketId: null
|
||||
};
|
||||
this.players.push(bot_player);
|
||||
console.log(`Created bot with UUID ${bot_id}`)
|
||||
}
|
||||
}
|
||||
|
||||
startGame(settings) {
|
||||
this.gameSettings = { ...this.gameSettings, ...settings };
|
||||
this.startBots(this.gameSettings.botCount);
|
||||
this.inProgress = true;
|
||||
this.yarnStory = [{ player: "Narrator", str: "It was a dark and stormy night..." }];
|
||||
this.yarnStory = [{ player: "Narrator", str: this.gameSettings.startText }];
|
||||
this.players.forEach(p => p.score = 0);
|
||||
this.startWritingPhase();
|
||||
}
|
||||
|
||||
processBotWriting() {
|
||||
for (const botObj of this.bots) {
|
||||
const botText = botObj.bot.Write(this.getStoryText());
|
||||
this.submitEntry(botObj.bot_id, botText)
|
||||
}
|
||||
}
|
||||
|
||||
startWritingPhase() {
|
||||
this.currentPhase = 'writing';
|
||||
this.round_data = [];
|
||||
this.submittedPlayers = new Set();
|
||||
this.timeRemaining = this.gameSettings.timeLimit;
|
||||
this.processBotWriting()
|
||||
}
|
||||
|
||||
getStoryText() {
|
||||
return this.yarnStory.map(entry => entry.str).join('');
|
||||
}
|
||||
|
||||
submitEntry(playerId, entryText) {
|
||||
@@ -140,10 +176,18 @@ class YarnGame {
|
||||
return this.submittedPlayers.size >= this.players.length;
|
||||
}
|
||||
|
||||
processBotVoting() {
|
||||
for (const botObj of this.bots) {
|
||||
const botVote = botObj.bot.Vote(this.getStoryText(), this.round_data);
|
||||
this.submitVote(botObj.bot_id, botVote)
|
||||
}
|
||||
}
|
||||
|
||||
startVotingPhase() {
|
||||
this.currentPhase = 'voting';
|
||||
this.votedPlayers = new Set();
|
||||
this.timeRemaining = 30; // 30 seconds for voting
|
||||
this.processBotVoting()
|
||||
}
|
||||
|
||||
submitVote(playerId, entryIndex) {
|
||||
@@ -203,9 +247,17 @@ class YarnGame {
|
||||
return null;
|
||||
}
|
||||
|
||||
purgeBots() {
|
||||
for (const botObj of this.bots) {
|
||||
this.removePlayer(botObj.bot_id)
|
||||
}
|
||||
this.bots = [];
|
||||
}
|
||||
|
||||
resetGame() {
|
||||
this.inProgress = false;
|
||||
this.currentPhase = 'lobby';
|
||||
this.purgeBots();
|
||||
this.round_data = [];
|
||||
this.yarnStory = [];
|
||||
this.submittedPlayers = new Set();
|
||||
@@ -216,6 +268,18 @@ class YarnGame {
|
||||
}
|
||||
}
|
||||
|
||||
botBanter() {
|
||||
for (const botObj of this.bots) {
|
||||
if (Math.random() > 0.8) {
|
||||
console.log("Bot bantering")
|
||||
const botBanter = botObj.bot.Banter(this.getStoryText());
|
||||
console.log(botBanter)
|
||||
const chatMsg = this.addChatMessage(botObj.bot_id, botBanter)
|
||||
io.to(this.roomName).emit('newChatMessage', chatMsg); //I don't like using io calls here but chat is weird
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addChatMessage(playerId, msg) {
|
||||
const player = this.getPlayer(playerId);
|
||||
const chatMsg = {
|
||||
@@ -331,7 +395,7 @@ io.on('connection', (socket) => {
|
||||
|
||||
const game = games[currentRoom];
|
||||
if (!game || game.gameHost !== playerId) return;
|
||||
if (game.players.length < 2) {
|
||||
if (game.players.length < 2 && settings.botCount == 0) {
|
||||
socket.emit('error', { message: 'Need at least 2 players to start' });
|
||||
return;
|
||||
}
|
||||
@@ -422,9 +486,9 @@ io.on('connection', (socket) => {
|
||||
io.to(currentRoom).emit('playersUpdate', game.getState().players);
|
||||
io.to(currentRoom).emit('gameState', game.getState());
|
||||
|
||||
// Clean up empty rooms
|
||||
console.log(`Removing empty room ${currentRoom}`)
|
||||
if (remaining === 0) {
|
||||
if (remaining === 0 || game.bots.length === game.players.length) {
|
||||
// Clean up empty rooms
|
||||
console.log(`Removing empty room ${currentRoom}`)
|
||||
if (game.timer) clearInterval(game.timer);
|
||||
delete games[currentRoom];
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user