From 5ef8ea86bbd4b6be118c84e9c07a630dae67ee93 Mon Sep 17 00:00:00 2001 From: EisiBaer Date: Thu, 13 Jul 2023 20:22:46 +0200 Subject: [PATCH] Finished player choosing entry implementation; TODO: Award in non Buzzer Interaction --- .../controllers/PlayerControllerMongoose.js | 20 ---- src/server/models/GameModel.js | 1 + src/server/websocket/handler.js | 91 +++++++++++++++---- .../components/blocks/BoardEntryCard.vue | 19 ++-- .../components/blocks/PlayerListEntry.vue | 51 ++++++++--- src/webapp/components/pages/Game.vue | 30 +++++- src/webapp/components/pages/Lobby.vue | 4 + src/webapp/components/views/BoardView.vue | 18 ++-- .../components/views/HostInteractionView.vue | 16 +++- src/webapp/components/views/PlayersView.vue | 14 ++- src/webapp/main.js | 3 +- src/webapp/stores/GameStore.js | 7 ++ 12 files changed, 200 insertions(+), 74 deletions(-) diff --git a/src/server/controllers/PlayerControllerMongoose.js b/src/server/controllers/PlayerControllerMongoose.js index d039de4..b06cd64 100644 --- a/src/server/controllers/PlayerControllerMongoose.js +++ b/src/server/controllers/PlayerControllerMongoose.js @@ -63,26 +63,6 @@ exports.setAllPlayersAcceptAnswers = ( playerIds, acceptAnswersValue ) => { }); } -/** - * Sets one player as isChoosing and other players as isChoosing false - * @param {String} choosingPlayerId - * @param {Array} notChoosingPlayerIds - * @returns A promise which resolves with the choosing player - */ -exports.setAllPlayersAcceptAnswers = ( choosingPlayerId, notChoosingPlayerIds ) => { - return new Promise((resolve, reject) => { - let promiseSetChoosing = PlayerModel.updateOne( { _id: choosingPlayerId }, { isChoosing: true } ); - let promiseSetNotChoosing = PlayerModel.updateMany( { _id: { $in : notChoosingPlayerIds } }, { isChoosing: false } ); - Promise.all( [ promiseSetChoosing, promiseSetNotChoosing ] ) - .then( ( resArr ) => { - resolve( resArr[0] ); - }) - .catch( ( err ) => { - reject( err ); - }) - }); -} - /** * Checks if a player is allowed to currently answer a question * @param {String} playerId diff --git a/src/server/models/GameModel.js b/src/server/models/GameModel.js index 0b0437b..9bc46d2 100644 --- a/src/server/models/GameModel.js +++ b/src/server/models/GameModel.js @@ -8,6 +8,7 @@ const GameSchema = new Schema({ board: { type: Schema.Types.ObjectId, ref: "Board", required: false }, players: { type: [Schema.Types.ObjectId], ref: "Player", required: true }, acceptAnswers: { type: Boolean, required: true, default: false }, + playerChoosing: { type: Object }, answeredBoardEntries: { type: [Object], default: [] }, state: { type: String, required: true, default: "CREATED" }, createdTimestamp: { type: Date, required: true, default: new Date() }, diff --git a/src/server/websocket/handler.js b/src/server/websocket/handler.js index 37b5c61..c6d7d66 100644 --- a/src/server/websocket/handler.js +++ b/src/server/websocket/handler.js @@ -128,22 +128,27 @@ exports.handleMessage = ( gameSocketList, socket, dataRaw ) => { break; case "startGame": if( socket.locals.isHost ){ - let gameOuter; gameController.findGameByIdAndSetStateAndPopulateBoard( socket.locals.game, "IN_PROGRESS" ) .then( ( game ) => { - gameOuter = game; if( game.players.length > 0 ){ - let randomPlayerIndex = crypto.randomInt(0, game.players.length ); - let randomPlayer = game.players[randomPlayerIndex]; - let otherPlayers = game.players.splice(randomPlayerIndex, 1); - return playerController.setPlayerIsChoosingAndOthersNotChoosing( randomPlayer, otherPlayers ); + let randomPlayer = game.players[ crypto.randomInt(0, game.players.length ) ]; + game.playerChoosing = { + playerId: randomPlayer._id.toString(), + categoryIndex: null, + boardEntryIndex: null, + } + return game.save(); } else { - return -1; + return game; } }) - .then( ( choosingPlayer ) => { + .then( ( game ) => { + let choosingPlayer = undefined + if( game.playerChoosing ){ + choosingPlayer = game.playerChoosing.playerId; + } let message = "Game is starting"; - let sendingData = { gameId: gameOuter._id, board: gameOuter.board, choosingPlayer: choosingPlayer._id }; + let sendingData = { gameId: game._id, board: game.board, choosingPlayer: choosingPlayer }; sendAllPlayers( socket, gameSocketList, "gameStarted", message, sendingData); resolve(); }) @@ -164,19 +169,69 @@ exports.handleMessage = ( gameSocketList, socket, dataRaw ) => { reject( new Error("Message not sent by host") ); } break; + case "letPlayerChoose": + if( socket.locals.isHost ){ + gameController.findGameById( socket.locals.game ) + .then( ( game ) => { + if( data.payload.playerId ){ + game.playerChoosing = { + playerId: data.payload.playerId, + categoryIndex: null, + boardEntryIndex: null, + } + return game.save(); + } else { + let currentChoosingPlayer = game.players.findIndex( playerEntry => playerEntry._id.toString() === game.playerChoosing.playerId ); + if( currentChoosingPlayer !== -1 ){ + let newChoosingPlayerIndex = currentChoosingPlayer + 1; + if( newChoosingPlayerIndex === game.players.length ){ + newChoosingPlayerIndex = 0; + } + game.playerChoosing = { + playerId: game.players[newChoosingPlayerIndex]._id.toString(), + categoryIndex: null, + boardEntryIndex: null, + } + return game.save(); + } else { + return game; + } + } + }) + .then( ( game ) => { + let message = `Player ${game.playerChoosing.playerId} can choose a BoardEntry`; + let sendingData = { choosingPlayer: game.playerChoosing.playerId }; + sendAllPlayers( socket, gameSocketList, "playerCanChoose", message, sendingData ); + resolve(); + }) + .catch( ( err ) => { + reject( err ); + }); + } + break; case "playerChooseBoardEntry": - playerController.checkPlayerCanChoose( socket.locals.player ) - .then( ( player ) => { - if( player.isChoosing ){ - let message = `Category ${payload.categoryIndex} with BoardEntry ${payload.boardEntryIndex} selected`; - let sendingData = { categoryIndex: payload.categoryIndex, boardEntryIndex: payload.boardEntryIndex, choosingPlayer: player._id.toString() }; - sendToHost( socket, gameSocketList, "playerChoseBoardEntry", message, sendingData ); - resolve(); + gameController.findGameById( socket.locals.game ) + .then( ( game ) => { + if( socket.locals.player === game.playerChoosing.playerId ){ + game.playerChoosing.categoryIndex = payload.categoryIndex; + game.playerChoosing.boardEntryIndex = payload.boardEntryIndex; + return game.save(); } else { - resolve(); + throw new Error("Message not sent by choosing Player"); } }) - .catch(); + .then( ( game ) => { + let chosenCategoryIndex = game.playerChoosing.categoryIndex; + let chosenBoardEntryIndex = game.playerChoosing.boardEntryIndex; + let choosingPlayer = game.playerChoosing.playerId; + let message = `Category ${chosenCategoryIndex} with BoardEntry ${chosenBoardEntryIndex} selected`; + let sendingData = { categoryIndex: chosenCategoryIndex, boardEntryIndex: chosenBoardEntryIndex, choosingPlayer: choosingPlayer }; + sendAllPlayers( socket, gameSocketList, "playerChoseBoardEntry", message, sendingData ); + resolve(); + }) + .catch( ( err ) => { + reject( err ); + }); break; case "selectBoard": if( socket.locals.isHost ){ diff --git a/src/webapp/components/blocks/BoardEntryCard.vue b/src/webapp/components/blocks/BoardEntryCard.vue index 8cad40e..ae56ed2 100644 --- a/src/webapp/components/blocks/BoardEntryCard.vue +++ b/src/webapp/components/blocks/BoardEntryCard.vue @@ -4,6 +4,14 @@ import { computed } from 'vue'; const props = defineProps({ boardEntry: Object, + boardEntryIndex: { + type: Number, + default: -1, + }, + categoryIndex: { + type: Number, + default: -1, + }, isHost: { type: Boolean, default: false, @@ -16,10 +24,7 @@ const props = defineProps({ type: Boolean, default: false, }, - playerChose: { - type: [Boolean, String], - default: false, - }, + chosenEntry: Object, }); const emit = defineEmits(["boardEntryCardClicked", "boardEntryAnsweredClicked", "boardEntryAnsweredRevertClicked" ]); @@ -64,9 +69,9 @@ function boardEntryAnsweredRevertClicked(){ -
- - {{ props.playerChose.name }} chooses this +
+ + {{ props.chosenEntry.player.name }}
diff --git a/src/webapp/components/blocks/PlayerListEntry.vue b/src/webapp/components/blocks/PlayerListEntry.vue index 0b0f7e3..b8a31ed 100644 --- a/src/webapp/components/blocks/PlayerListEntry.vue +++ b/src/webapp/components/blocks/PlayerListEntry.vue @@ -9,29 +9,47 @@ const props = defineProps({ acceptAnswers: { type: Boolean, default: false, - } + }, + isEntryShown: { + type: Boolean, + default: false, + }, }); -const emit = defineEmits(["manualPointsAdjustment", "answerRuled", "revealPlayerAnswer"]); +const emit = defineEmits(["manualPointsAdjustment", "answerRuled", "revealPlayerAnswer", "letPlayerChoose"]); function revealAnswer(){ emit("revealPlayerAnswer", props.player._id); } +function letPlayerChoose(){ + emit("letPlayerChoose", props.player._id); +} +