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,
}
})