From a16742f55fd3f4a1e188a54d1cc1dd32fcff8e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zachary=20Gu=C3=A9not?= Date: Sun, 27 Oct 2024 15:14:07 +0100 Subject: [PATCH] Game over et Victory + Affichage texte, timer et choix des variables --- src/utils/game.ts | 64 ++++++++++++++++++++--------- src/views/Game/SoloView.vue | 81 ++++++++++++++++++++++--------------- 2 files changed, 94 insertions(+), 51 deletions(-) diff --git a/src/utils/game.ts b/src/utils/game.ts index 0cc8cc4..1afab9d 100644 --- a/src/utils/game.ts +++ b/src/utils/game.ts @@ -1,6 +1,6 @@ -type CellGrid = string[][] // type CellGrid (grille de jeu) -type MineGrid = number[][] // type MineGrid (grille de bombes) -type Directions = number[][] // type Directions (directions possibles) +type CellGrid = string[][] // type CellGrid (grille de jeu) +type MineGrid = number[][] // type MineGrid (grille de bombes) +type Directions = number[][] // type Directions (directions possibles) function getDirections(x: number, y: number): Directions { return [[x-1, y-1], [x-1, y], [x-1, y+1], [x, y-1], [x, y+1], [x+1, y-1], [x+1, y], [x+1, y+1]] @@ -27,14 +27,23 @@ function genMineGrid(width: number, length: number, nbMines: number, fx: number, } -function cliqueGauche(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number) { +function cliqueGauche(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number { const checkDrop = ['/sEmpty.png', '/sUnknown.png', '/sFlag.png', '/sQuestion.png'] - if (checkDrop.includes(cellGrid[y][x])) return - else if (cellGrid[y][x] === '/sClick.png') checkCell(gameStatus, cellGrid, mineGrid, x, y) - else revealCell(gameStatus, cellGrid, mineGrid, x, y) + if (checkDrop.includes(cellGrid[y][x])) return 1 + else if (cellGrid[y][x] === '/sClick.png') { + const result = checkCell(cellGrid, mineGrid, x, y) + if (result !== 0) return result + } + else { + const result = revealCell(cellGrid, mineGrid, x, y) + if (result !== 0) return result + } + + // Continuer le jeu + return 1 } -function cliqueDroit(cellGrid: string[][], x: number, y: number) { // fonction cliqueDroit (flag d'une case) // modification de l'image de la case +function cliqueDroit(cellGrid: string[][], x: number, y: number) { // fonction cliqueDroit (flag d'une case) switch (cellGrid[y][x]) { case '/sUnknown.png': cellGrid[y][x] = "/sFlag.png" @@ -48,9 +57,10 @@ function cliqueDroit(cellGrid: string[][], x: number, y: number) { } } -function checkCell(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number) { - if (mineGrid.some(m => m[0] === x && m[1] === y)) return gameOver(gameStatus, cellGrid, mineGrid, x, y) +function checkCell(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number { + if (mineGrid.some(m => m[0] === x && m[1] === y)) return gameOver(cellGrid, mineGrid, x, y) + // Compter le nombre de mines adjacentes let minesAdjacentes = 0 const directions = getDirections(x, y) for (const [dx, dy] of directions) { @@ -58,18 +68,30 @@ function checkCell(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x if (mineGrid.some(m => m[0] === dx && m[1] === dy)) minesAdjacentes++ } + // Si la cellule a des mines adjacentes, afficher le nombre de mines if (minesAdjacentes > 0) cellGrid[y][x] = `/s${minesAdjacentes}.png` else { cellGrid[y][x] = '/sEmpty.png' for (const [dx, dy] of directions) { if (dx >= 0 && dx < cellGrid[0].length && dy >= 0 && dy < cellGrid.length && cellGrid[dy][dx] === '/sUnknown.png') { - checkCell(gameStatus, cellGrid, mineGrid, dx, dy) + const result = checkCell(cellGrid, mineGrid, dx, dy) + if (result !== 0) return result } } } + + // Vérifier si toutes les cellules non-mines sont révélées pour déterminer la victoire + if (cellGrid.flat().every((cell, index) => { + const x = index % cellGrid[0].length + const y = Math.floor(index / cellGrid[0].length) + return cell !== '/sUnknown.png' || mineGrid.some(m => m[0] === x && m[1] === y) + })) return 2 + + // Continuer le jeu + return 0 } -function revealCell(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number) { +function revealCell(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number { const directions = getDirections(x, y) let flagCount = 0 for (const [dx, dy] of directions) { @@ -80,16 +102,22 @@ function revealCell(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, for (const [dx, dy] of directions) { if (dx >= 0 && dx < cellGrid[0].length && dy >= 0 && dy < cellGrid.length && cellGrid[dy][dx] === '/sHighlight.png') { cellGrid[dy][dx] = '/sUnknown.png' - checkCell(gameStatus, cellGrid, mineGrid, dx, dy) + + const result = checkCell(cellGrid, mineGrid, dx, dy) + if (result !== 0) return result } } } + + // Continuer le jeu + return 0 } -function gameOver(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number) { +function gameOver(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number { for (const [mx, my] of mineGrid) { if (cellGrid[my][mx] === '/sUnknown.png') cellGrid[my][mx] = '/sMine.png' } + // Vérifier l'emplacement de tous les flags dans toute la grille et les remplacer par '/sFlagWrong.png' s'il y en a un qui n'est pas sur une bombe for (let y = 0; y < cellGrid.length; y++) { for (let x = 0; x < cellGrid[y].length; x++) { @@ -98,10 +126,8 @@ function gameOver(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: } cellGrid[y][x] = '/sExploded.png' - gameStatus = 3 + return 3 } -export { getDirections, genCellGrid, genMineGrid, cliqueGauche, cliqueDroit } // export des fonctions -export type { Directions, CellGrid, MineGrid } // export des types - -//test \ No newline at end of file +export { getDirections, genCellGrid, genMineGrid, cliqueGauche, cliqueDroit } // export des fonctions +export type { Directions, CellGrid, MineGrid } // export des types \ No newline at end of file diff --git a/src/views/Game/SoloView.vue b/src/views/Game/SoloView.vue index 0f3f4d0..190d2a9 100644 --- a/src/views/Game/SoloView.vue +++ b/src/views/Game/SoloView.vue @@ -4,13 +4,13 @@ import { getDirections, genCellGrid, genMineGrid, cliqueGauche, cliqueDroit } fr import type { CellGrid, MineGrid } from '@/utils/game' // Variables du jeu -const width = 10 -const length = 15 -const nbMines = 25 +const width = ref(10) +const length = ref(15) +const nbMines = ref(25) // Création grille des cases const cellGrid = ref([]) -cellGrid.value = genCellGrid(width, length) +cellGrid.value = genCellGrid(width.value, length.value) // Création grille des mines let mineGrid: MineGrid = [] @@ -21,13 +21,8 @@ const timer = ref(0) let timerInterval: number | undefined = undefined watch(gameStatus, async (status) => { - if (status === 1) { - timerInterval = setInterval(() => timer.value++, 1000) - } else { - if (timerInterval !== null) clearInterval(timerInterval) - if (status === 2) alert('Vous avez gagné !') - if (status === 3) alert('Vous avez perdu !') - } + if (status === 1) timerInterval = setInterval(() => timer.value++, 1000) + else clearInterval(timerInterval) }) // État pour gérer le clic et la position de la cellule @@ -52,11 +47,11 @@ const handleMouseDown = (rowIndex: number, cellIndex: number) => { const handleMouseUp = async (rowIndex: number, cellIndex: number) => { isMouseDown.value = false if (!mineGrid.length) { - mineGrid = genMineGrid(width, length, nbMines, cellIndex, rowIndex) + mineGrid = genMineGrid(width.value, length.value, nbMines.value, cellIndex, rowIndex) gameStatus.value = 1 } - cliqueGauche(gameStatus.value, cellGrid.value, mineGrid, cellIndex, rowIndex) + gameStatus.value = cliqueGauche(cellGrid.value, mineGrid, cellIndex, rowIndex) currentCell.value = null // Réinitialiser les cases surlignées @@ -125,37 +120,59 @@ onUnmounted(() => document.removeEventListener('mousemove', handleGlobalMouseMov