From ceb3d735ad3f97e955b8ed32f36ab64c0b6f6761 Mon Sep 17 00:00:00 2001 From: Tiago Ramos <2222055@my.ipleiria.pt> Date: Tue, 23 Dec 2025 21:52:09 +0000 Subject: [PATCH] SyntaxSquad/DADProject#14 Bot works and play works, still has some bugs --- frontend/src/components/game/GameBoard.vue | 69 +++------------- frontend/src/components/game/PlayerHand.vue | 64 ++++++++------- frontend/src/components/layout/NavBar.vue | 1 - frontend/src/stores/bisca.js | 89 ++++++++++++++------- 4 files changed, 112 insertions(+), 111 deletions(-) diff --git a/frontend/src/components/game/GameBoard.vue b/frontend/src/components/game/GameBoard.vue index 418f7fc..125c065 100644 --- a/frontend/src/components/game/GameBoard.vue +++ b/frontend/src/components/game/GameBoard.vue @@ -2,7 +2,6 @@
-
-
-
-
-
@@ -55,52 +48,20 @@ import PlayArea from './PlayArea.vue' import DeckArea from './DeckArea.vue' import ScoreDisplay from './ScoreDisplay.vue' -// Props for testing - in real implementation, these come from Pinia store const props = defineProps({ - playerHand: { - type: Array, - default: () => [], - }, - opponentHand: { - type: Array, - default: () => [], - }, + playerHand: { type: Array, default: () => [] }, + opponentHand: { type: Array, default: () => [] }, currentTrick: { type: Object, - default: () => ({ - playerCard: null, - opponentCard: null, - winner: null, - }), - }, - trumpCard: { - type: Object, - required: true, - }, - cardsRemaining: { - type: Number, - default: 0, - }, - deckIsEmpty: { - type: Boolean, - default: false, - }, - maxCards: { - type: Number, - default: 3, - }, - playableCardIndices: { - type: Array, - default: () => [], - }, - playerScore: { - type: Number, - default: 0, - }, - opponentScore: { - type: Number, - default: 0, + default: () => ({ playerCard: null, opponentCard: null, winner: null }), }, + trumpCard: { type: Object, required: true }, + cardsRemaining: { type: Number, default: 0 }, + deckIsEmpty: { type: Boolean, default: false }, + maxCards: { type: Number, default: 3 }, + // REMOVIDO: playableCardIndices (já não precisamos dele) + playerScore: { type: Number, default: 0 }, + opponentScore: { type: Number, default: 0 }, currentTurn: { type: String, default: 'player', @@ -108,13 +69,9 @@ const props = defineProps({ }, }) -const emit = defineEmits(['card-clicked']) +const emit = defineEmits(['play-card']) const handleCardClick = (payload) => { - emit('card-clicked', payload) + emit('play-card', payload.card) } - -const handlePlayCard = (card) => { - store.playerPlayCard(card) -} - + \ No newline at end of file diff --git a/frontend/src/components/game/PlayerHand.vue b/frontend/src/components/game/PlayerHand.vue index d19a7be..40ea923 100644 --- a/frontend/src/components/game/PlayerHand.vue +++ b/frontend/src/components/game/PlayerHand.vue @@ -12,13 +12,15 @@ :style="getCardStyle(index)" @mouseenter="hoveredIndex = index" @mouseleave="hoveredIndex = null" - @click="$emit('card-clicked', { card, index })" + @click="handleCardClick(card, index)" >
@@ -31,6 +33,8 @@ + \ No newline at end of file diff --git a/frontend/src/components/layout/NavBar.vue b/frontend/src/components/layout/NavBar.vue index 817c530..b605b46 100644 --- a/frontend/src/components/layout/NavBar.vue +++ b/frontend/src/components/layout/NavBar.vue @@ -51,7 +51,6 @@ import router from '@/router'; const emits = defineEmits(['logout']) const { userLoggedIn } = defineProps(['userLoggedIn']) -const router = useRouter() const biscaStore = useBiscaStore() const logoutClickHandler = () => { diff --git a/frontend/src/stores/bisca.js b/frontend/src/stores/bisca.js index d5c2040..2a69348 100644 --- a/frontend/src/stores/bisca.js +++ b/frontend/src/stores/bisca.js @@ -74,6 +74,10 @@ export const useBiscaStore = defineStore('bisca', () => { if (!isGameRunning.value || currentTurn.value !== 'player') return if (table.value.playerCard) return + if (!canPlayCard(card)) { + console.warn('Jogada Inválida! Tens de assistir ao naipe.') + return + } playerHand.value = playerHand.value.filter((c) => c.id !== card.id) table.value.playerCard = card @@ -137,57 +141,67 @@ export const useBiscaStore = defineStore('bisca', () => { } } - const resolveTrick = () => { + const resolveTrick = async () => { const pCard = table.value.playerCard const oCard = table.value.opponentCard - const trumpSuit = trumpCard.value.suit - let trickWinner = '' + const trump = trumpCard.value.suit - if (pCard.suit === trumpSuit && oCard.suit !== trumpSuit) trickWinner = 'player' - else if (oCard.suit === trumpSuit && pCard.suit !== trumpSuit) trickWinner = 'opponent' - else if (pCard.suit === oCard.suit) { - trickWinner = getStrength(pCard.rank) > getStrength(oCard.rank) ? 'player' : 'opponent' + let weWon = false + + if (table.value.firstToPlay === 'player') { + if (doesCardWin(oCard, pCard, trump)) weWon = false + else weWon = true } else { - trickWinner = table.value.firstToPlay + if (doesCardWin(pCard, oCard, trump)) weWon = true + else weWon = false } const points = pCard.points + oCard.points - - if (trickWinner === 'player') { + if (weWon) { playerScore.value += points playerTricks.value++ + currentTurn.value = 'player' } else { opponentScore.value += points opponentTricks.value++ + currentTurn.value = 'opponent' } table.value = { playerCard: null, opponentCard: null, firstToPlay: null } - if ( - deck.value.length === 0 && - playerHand.value.length === 0 && - opponentHand.value.length === 0 - ) { + if (deck.value.length > 0) { + if (weWon) { + await drawOneCard('player') + await drawOneCard('opponent') + } else { + await drawOneCard('opponent') + await drawOneCard('player') + } + } else if (playerHand.value.length === 0 && opponentHand.value.length === 0) { endGame() return } - if (deck.value.length > 0) { - if (trickWinner === 'player') { - playerHand.value.push(deck.value.pop()) - opponentHand.value.push(deck.value.pop()) - } else { - opponentHand.value.push(deck.value.pop()) - playerHand.value.push(deck.value.pop()) - } - } - - currentTurn.value = trickWinner - if (trickWinner === 'opponent') { + if (currentTurn.value === 'opponent') { setTimeout(botPlayCard, 1000) } } + const drawOneCard = async (who) => { + if (deck.value.length === 0) return + + let card + if (deck.value.length === 1) { + card = deck.value.pop() + trumpCard.value = null + } else { + card = deck.value.pop() + } + + if (who === 'player') playerHand.value.push(card) + else opponentHand.value.push(card) + } + const doesCardWin = (attacker, defender, trumpSuit) => { if (attacker.suit === trumpSuit && defender.suit !== trumpSuit) return true @@ -272,6 +286,26 @@ export const useBiscaStore = defineStore('bisca', () => { isGameOver.value = true } + const canPlayCard = (card) => { + // 1. Se não for a minha vez, não posso jogar nada + if (currentTurn.value !== 'player') return false + + if (!table.value.opponentCard) return true + + if (deck.value.length > 0) return true + + + const suitToFollow = table.value.opponentCard.suit + + const hasSuit = playerHand.value.some((c) => c.suit === suitToFollow) + + if (hasSuit && card.suit !== suitToFollow) { + return false + } + + return true + } + const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) return { @@ -295,5 +329,6 @@ export const useBiscaStore = defineStore('bisca', () => { quitGame, resolveTrick, playerPlayCard, + canPlayCard, } })