+
+
Bisca Game
+
+
+
+
+
+
+
Escolhe o Modo
+
+
+
+
+
+
+
+
+
+
-`
\ No newline at end of file
+
diff --git a/frontend/src/router/index.js b/frontend/src/router/index.js
index b75364d..983f8fd 100644
--- a/frontend/src/router/index.js
+++ b/frontend/src/router/index.js
@@ -6,7 +6,9 @@ import TestAnimations from '@/pages/TestAnimations.vue'
import TestDealing from '@/pages/TestDealing.vue'
import TestAllAnimations from '@/pages/TestAllAnimations.vue'
import TestGameBoard from '@/pages/TestGameBoard.vue'
+import SinglePlayerGamePage from '@/pages/game/SinglePlayerGamePage.vue'
import { createRouter, createWebHistory } from 'vue-router'
+import { toast } from 'vue-sonner'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
@@ -19,6 +21,20 @@ const router = createRouter({
path: '/login',
component: LoginPage,
},
+ {
+ path: '/game/3',
+ name: 'bisca3',
+ component: SinglePlayerGamePage,
+ props: { gameType: 3 },
+ meta: { requiresAuth: true },
+ },
+ {
+ path: '/game/9',
+ name: 'bisca9',
+ component: SinglePlayerGamePage,
+ props: { gameType: 9 },
+ meta: { requiresAuth: true },
+ },
{
path: '/testing',
children: [
@@ -51,4 +67,19 @@ const router = createRouter({
],
})
+router.beforeEach((to, from, next) => {
+ if (to.meta.requiresAuth) {
+ const token = localStorage.getItem('token') // Ou useAuthStore().token
+
+ if (!token) {
+ toast.error('Acesso Negado', {
+ description: 'Precisas de fazer login para aceder ao jogo.',
+ duration: 4000,
+ })
+ return next({ name: 'home' })
+ }
+ }
+ next()
+})
+
export default router
diff --git a/frontend/src/stores/bisca.js b/frontend/src/stores/bisca.js
new file mode 100644
index 0000000..49a7c79
--- /dev/null
+++ b/frontend/src/stores/bisca.js
@@ -0,0 +1,127 @@
+import { defineStore } from 'pinia'
+import { ref } from 'vue'
+
+export const useBiscaStore = defineStore('bisca', () => {
+ const isDealing = ref(false)
+ const isGameRunning = ref(false)
+ const gameType = ref(3)
+
+ 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 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
+
+ playerScore.value = 0
+ opponentScore.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()
+
+ isDealing.value = false
+ }
+
+ 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 wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
+
+ return {
+ isDealing,
+ isGameRunning,
+ gameType,
+ deck,
+ playerHand,
+ opponentHand,
+ trumpCard,
+ playerScore,
+ opponentScore,
+ currentTurn,
+ table,
+ startGame,
+ }
+})
diff --git a/frontend/src/stores/game.js b/frontend/src/stores/game.js
deleted file mode 100644
index f979538..0000000
--- a/frontend/src/stores/game.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { defineStore } from 'pinia'
-import { ref, computed } from 'vue'
-import { toast } from 'vue-sonner'
-import { useApiStore } from './api'
-
-export const useGameStore = defineStore('game', () => {
-
-})