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

300 lines
7.4 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 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
currentTurn.value = 'player'
table.value = {
playerCard: null,
opponentCard: null,
firstToPlay: null,
}
deck.value = createDeck()
trumpCard.value = deck.value[0]
await wait(500)
await dealInitialCards()
if (currentTurn.value === 'opponent') {
setTimeout(botPlayCard, 1000)
}
isDealing.value = false
}
const playerPlayCard = (card) => {
if (!isGameRunning.value || currentTurn.value !== 'player') return
if (table.value.playerCard) 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 trump = trumpCard.value.suit
const winningCards = opponentHand.value.filter((botCard) =>
doesCardWin(botCard, pCard, trump),
)
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 === trumpCard.value.suit && b.suit !== trumpCard.value.suit) return 1
if (a.suit !== trumpCard.value.suit && b.suit === trumpCard.value.suit) 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 = () => {
const pCard = table.value.playerCard
const oCard = table.value.opponentCard
const trumpSuit = trumpCard.value.suit
let trickWinner = ''
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'
} else {
trickWinner = table.value.firstToPlay
}
const points = pCard.points + oCard.points
if (trickWinner === 'player') {
playerScore.value += points
playerTricks.value++
} else {
opponentScore.value += points
opponentTricks.value++
}
table.value = { playerCard: null, opponentCard: null, firstToPlay: null }
if (
deck.value.length === 0 &&
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') {
setTimeout(botPlayCard, 1000)
}
}
const doesCardWin = (attacker, defender, trumpSuit) => {
if (attacker.suit === trumpSuit && defender.suit !== trumpSuit) return true
if (defender.suit === trumpSuit && attacker.suit !== trumpSuit) 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) {
const card = deck.value.pop()
playerHand.value.push(card)
await wait(dealSpeed)
}
if (deck.value.length > 0) {
const card = deck.value.pop()
opponentHand.value.push(card)
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 wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
return {
isDealing,
isGameRunning,
gameType,
deck,
playerHand,
opponentHand,
isLoggingOut,
trumpCard,
playerScore,
opponentScore,
currentTurn,
table,
playerTricks,
opponentTricks,
isGameOver,
winner,
startGame,
quitGame,
resolveTrick,
playerPlayCard,
}
})