Files
DADProject/frontend/src/stores/bisca.js
T

321 lines
8.1 KiB
JavaScript

import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useBiscaStore = defineStore('bisca', () => {
const isDealing = ref(false)
const isGameRunning = ref(false)
const isGameOver = ref(false)
const gameType = ref(3)
const isLoggingOut = ref(false)
const deck = ref([])
const playerHand = ref([])
const opponentHand = ref([])
const trumpCard = ref(null)
const trumpSuit = ref('')
const playerScore = ref(0)
const opponentScore = ref(0)
const currentTurn = ref('player')
const playerTricks = ref(0)
const opponentTricks = ref(0)
const winner = ref(null)
const table = ref({
playerCard: null,
opponentCard: null,
firstToPlay: null,
})
const startGame = async (type = 3) => {
if (isDealing.value) return
isDealing.value = true
isGameRunning.value = true
gameType.value = type
isGameOver.value = false
isLoggingOut.value = false
playerScore.value = 0
opponentScore.value = 0
playerTricks.value = 0
opponentTricks.value = 0
deck.value = []
playerHand.value = []
opponentHand.value = []
trumpCard.value = null
trumpSuit.value = ''
currentTurn.value = 'player'
table.value = { playerCard: null, opponentCard: null, firstToPlay: null }
deck.value = createDeck()
const lastCard = deck.value.pop()
trumpCard.value = lastCard
trumpSuit.value = lastCard.suit
await wait(500)
await dealInitialCards()
isDealing.value = false
if (currentTurn.value === 'opponent') {
setTimeout(botPlayCard, 1000)
}
}
const playerPlayCard = (card) => {
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
if (!table.value.firstToPlay) table.value.firstToPlay = 'player'
checkEndOfTrick()
}
const botPlayCard = () => {
if (!isGameRunning.value) return
if (opponentHand.value.length === 0) return
let cardToPlay = null
if (table.value.playerCard) {
const pCard = table.value.playerCard
const winningCards = opponentHand.value.filter((botCard) => doesCardWin(botCard, pCard))
if (winningCards.length > 0) {
winningCards.sort((a, b) => a.strength - b.strength)
cardToPlay = winningCards[0]
} else {
const sortedHand = [...opponentHand.value].sort((a, b) => {
if (a.points === b.points) return a.strength - b.strength
return a.points - b.points
})
cardToPlay = sortedHand[0]
}
} else {
const sortedHand = [...opponentHand.value].sort((a, b) => {
if (a.suit === trumpSuit.value && b.suit !== trumpSuit.value) return 1
if (a.suit !== trumpSuit.value && b.suit === trumpSuit.value) return -1
return a.strength - b.strength
})
cardToPlay = sortedHand[0]
table.value.firstToPlay = 'opponent'
}
opponentHand.value = opponentHand.value.filter((c) => c.id !== cardToPlay.id)
table.value.opponentCard = cardToPlay
checkEndOfTrick()
}
const checkEndOfTrick = () => {
if (table.value.playerCard && table.value.opponentCard) {
currentTurn.value = 'resolving'
setTimeout(resolveTrick, 1500)
} else {
if (table.value.playerCard) {
currentTurn.value = 'opponent'
setTimeout(botPlayCard, 1000)
} else {
currentTurn.value = 'player'
}
}
}
const resolveTrick = async () => {
const pCard = table.value.playerCard
const oCard = table.value.opponentCard
let weWon = false
if (table.value.firstToPlay === 'player') {
if (doesCardWin(oCard, pCard)) weWon = false
else weWon = true
} else {
if (doesCardWin(pCard, oCard)) weWon = true
else weWon = false
}
const points = pCard.points + oCard.points
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 || trumpCard.value !== null) {
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 (currentTurn.value === 'opponent') {
setTimeout(botPlayCard, 1000)
}
}
const drawOneCard = async (who) => {
let cardToDraw = null
if (deck.value.length > 0) {
cardToDraw = deck.value.pop()
} else if (trumpCard.value !== null) {
cardToDraw = trumpCard.value
trumpCard.value = null
} else {
return
}
if (who === 'player') {
playerHand.value.push(cardToDraw)
} else {
opponentHand.value.push(cardToDraw)
}
}
const doesCardWin = (attacker, defender) => {
const suit = trumpSuit.value
if (attacker.suit === suit && defender.suit !== suit) return true
if (defender.suit === suit && attacker.suit !== suit) return false
if (attacker.suit === defender.suit) {
return attacker.strength > defender.strength
}
return false
}
const endGame = () => {
isGameRunning.value = false
isGameOver.value = true
if (playerScore.value > opponentScore.value) winner.value = 'player'
else if (opponentScore.value > playerScore.value) winner.value = 'opponent'
else winner.value = 'draw'
}
const dealInitialCards = async () => {
const cardsToDeal = gameType.value === 9 ? 9 : 3
const dealSpeed = gameType.value === 9 ? 200 : 500
for (let i = 0; i < cardsToDeal; i++) {
if (deck.value.length > 0) {
playerHand.value.push(deck.value.pop())
await wait(dealSpeed)
}
if (deck.value.length > 0) {
opponentHand.value.push(deck.value.pop())
await wait(dealSpeed)
}
}
}
const createDeck = () => {
const suits = ['c', 'e', 'o', 'p']
const ranks = [1, 2, 3, 4, 5, 6, 7, 11, 12, 13]
let newDeck = []
for (const suit of suits) {
for (const rank of ranks) {
newDeck.push({
id: `${suit}-${rank}`,
suit,
rank,
points: getPoints(rank),
strength: getStrength(rank),
})
}
}
return newDeck.sort(() => Math.random() - 0.5)
}
const getPoints = (rank) => {
if (rank === 1) return 11
if (rank === 7) return 10
if (rank === 13) return 4
if (rank === 11) return 3
if (rank === 12) return 2
return 0
}
const getStrength = (rank) => {
const strengthMap = { 1: 10, 7: 9, 13: 8, 11: 7, 12: 6, 6: 5, 5: 4, 4: 3, 3: 2, 2: 1 }
return strengthMap[rank] || 0
}
const quitGame = () => {
if (!isGameRunning.value) return
opponentScore.value = 120
playerScore.value = 0
winner.value = 'opponent'
isGameRunning.value = false
isGameOver.value = true
}
const canPlayCard = (card) => {
if (currentTurn.value !== 'player') return false
if (!table.value.opponentCard) return true
const hasCardsToDraw = deck.value.length > 0 || trumpCard.value !== null
if (hasCardsToDraw) 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 {
isDealing,
isGameRunning,
gameType,
deck,
playerHand,
opponentHand,
isLoggingOut,
trumpCard,
trumpSuit,
playerScore,
opponentScore,
currentTurn,
table,
playerTricks,
opponentTricks,
isGameOver,
winner,
startGame,
quitGame,
resolveTrick,
playerPlayCard,
canPlayCard,
}
})