Game over et Victory + Affichage texte, timer et choix des variables

This commit is contained in:
2024-10-27 15:14:07 +01:00
parent 2c32d2ae49
commit a16742f55f
2 changed files with 94 additions and 51 deletions

View File

@@ -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'] const checkDrop = ['/sEmpty.png', '/sUnknown.png', '/sFlag.png', '/sQuestion.png']
if (checkDrop.includes(cellGrid[y][x])) return if (checkDrop.includes(cellGrid[y][x])) return 1
else if (cellGrid[y][x] === '/sClick.png') checkCell(gameStatus, cellGrid, mineGrid, x, y) else if (cellGrid[y][x] === '/sClick.png') {
else revealCell(gameStatus, cellGrid, mineGrid, x, y) 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
} }
function cliqueDroit(cellGrid: string[][], x: number, y: number) { // fonction cliqueDroit (flag d'une case) // modification de l'image de la case // Continuer le jeu
return 1
}
function cliqueDroit(cellGrid: string[][], x: number, y: number) { // fonction cliqueDroit (flag d'une case)
switch (cellGrid[y][x]) { switch (cellGrid[y][x]) {
case '/sUnknown.png': case '/sUnknown.png':
cellGrid[y][x] = "/sFlag.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) { function checkCell(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number {
if (mineGrid.some(m => m[0] === x && m[1] === y)) return gameOver(gameStatus, cellGrid, mineGrid, x, y) 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 let minesAdjacentes = 0
const directions = getDirections(x, y) const directions = getDirections(x, y)
for (const [dx, dy] of directions) { 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++ 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` if (minesAdjacentes > 0) cellGrid[y][x] = `/s${minesAdjacentes}.png`
else { else {
cellGrid[y][x] = '/sEmpty.png' cellGrid[y][x] = '/sEmpty.png'
for (const [dx, dy] of directions) { for (const [dx, dy] of directions) {
if (dx >= 0 && dx < cellGrid[0].length && dy >= 0 && dy < cellGrid.length && cellGrid[dy][dx] === '/sUnknown.png') { 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
} }
} }
} }
function revealCell(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number) { // 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(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number {
const directions = getDirections(x, y) const directions = getDirections(x, y)
let flagCount = 0 let flagCount = 0
for (const [dx, dy] of directions) { for (const [dx, dy] of directions) {
@@ -80,16 +102,22 @@ function revealCell(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid,
for (const [dx, dy] of directions) { for (const [dx, dy] of directions) {
if (dx >= 0 && dx < cellGrid[0].length && dy >= 0 && dy < cellGrid.length && cellGrid[dy][dx] === '/sHighlight.png') { if (dx >= 0 && dx < cellGrid[0].length && dy >= 0 && dy < cellGrid.length && cellGrid[dy][dx] === '/sHighlight.png') {
cellGrid[dy][dx] = '/sUnknown.png' cellGrid[dy][dx] = '/sUnknown.png'
checkCell(gameStatus, cellGrid, mineGrid, dx, dy)
} const result = checkCell(cellGrid, mineGrid, dx, dy)
if (result !== 0) return result
} }
} }
} }
function gameOver(gameStatus: number, cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number) { // Continuer le jeu
return 0
}
function gameOver(cellGrid: CellGrid, mineGrid: MineGrid, x: number, y: number): number {
for (const [mx, my] of mineGrid) { for (const [mx, my] of mineGrid) {
if (cellGrid[my][mx] === '/sUnknown.png') cellGrid[my][mx] = '/sMine.png' 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 // 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 y = 0; y < cellGrid.length; y++) {
for (let x = 0; x < cellGrid[y].length; x++) { 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' cellGrid[y][x] = '/sExploded.png'
gameStatus = 3 return 3
} }
export { getDirections, genCellGrid, genMineGrid, cliqueGauche, cliqueDroit } // export des fonctions export { getDirections, genCellGrid, genMineGrid, cliqueGauche, cliqueDroit } // export des fonctions
export type { Directions, CellGrid, MineGrid } // export des types export type { Directions, CellGrid, MineGrid } // export des types
//test

View File

@@ -4,13 +4,13 @@ import { getDirections, genCellGrid, genMineGrid, cliqueGauche, cliqueDroit } fr
import type { CellGrid, MineGrid } from '@/utils/game' import type { CellGrid, MineGrid } from '@/utils/game'
// Variables du jeu // Variables du jeu
const width = 10 const width = ref(10)
const length = 15 const length = ref(15)
const nbMines = 25 const nbMines = ref(25)
// Création grille des cases // Création grille des cases
const cellGrid = ref<CellGrid>([]) const cellGrid = ref<CellGrid>([])
cellGrid.value = genCellGrid(width, length) cellGrid.value = genCellGrid(width.value, length.value)
// Création grille des mines // Création grille des mines
let mineGrid: MineGrid = [] let mineGrid: MineGrid = []
@@ -21,13 +21,8 @@ const timer = ref(0)
let timerInterval: number | undefined = undefined let timerInterval: number | undefined = undefined
watch(gameStatus, async (status) => { watch(gameStatus, async (status) => {
if (status === 1) { if (status === 1) timerInterval = setInterval(() => timer.value++, 1000)
timerInterval = setInterval(() => timer.value++, 1000) else clearInterval(timerInterval)
} else {
if (timerInterval !== null) clearInterval(timerInterval)
if (status === 2) alert('Vous avez gagné !')
if (status === 3) alert('Vous avez perdu !')
}
}) })
// État pour gérer le clic et la position de la cellule // É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) => { const handleMouseUp = async (rowIndex: number, cellIndex: number) => {
isMouseDown.value = false isMouseDown.value = false
if (!mineGrid.length) { if (!mineGrid.length) {
mineGrid = genMineGrid(width, length, nbMines, cellIndex, rowIndex) mineGrid = genMineGrid(width.value, length.value, nbMines.value, cellIndex, rowIndex)
gameStatus.value = 1 gameStatus.value = 1
} }
cliqueGauche(gameStatus.value, cellGrid.value, mineGrid, cellIndex, rowIndex) gameStatus.value = cliqueGauche(cellGrid.value, mineGrid, cellIndex, rowIndex)
currentCell.value = null currentCell.value = null
// Réinitialiser les cases surlignées // Réinitialiser les cases surlignées
@@ -125,37 +120,59 @@ onUnmounted(() => document.removeEventListener('mousemove', handleGlobalMouseMov
<template> <template>
<div class="main"> <div class="main">
<div class="space">
<h1>Solo</h1> <h1>Solo</h1>
<div class="timer" :gameStatus>{{ timer }}</div> <div class="timer" :gameStatus>Timer : {{ timer }}</div>
<div class="menu">
<input type="number" v-model="width" min="10" max="50" />Lignes (10-50)
<input type="number" v-model="length" min="10" max="50" />Colonnes (10-50)
<input type="number" v-model="nbMines" min="10" max="250" />Mines (10-250)
<button @click="gameStatus = 0">Nouvelle partie</button>
</div>
</div>
<div class="grid"> <div class="grid">
<div v-for="(row, rowIndex) in cellGrid" :key="rowIndex" class="row"> <div v-for="(row, rowIndex) in cellGrid" :key="rowIndex" class="row">
<div v-for="(cell, cellIndex) in row" :key="cellIndex"> <img v-for="(cell, cellIndex) in row" :key="cellIndex" class="cell" :src="cell"
<img class="cell" :src="cell" @mousedown.right="gameStatus == 1 ? cliqueDroit(cellGrid, cellIndex, rowIndex) : null"
@mousedown.right="cliqueDroit(cellGrid, cellIndex, rowIndex)" @mousedown.left="gameStatus == 0 || gameStatus == 1 ? handleMouseDown(rowIndex, cellIndex) : null"
@mousedown.left="handleMouseDown(rowIndex, cellIndex)" @mouseup.left="gameStatus == 0 || gameStatus == 1 ? handleMouseUp(rowIndex, cellIndex) : null"
@mouseup.left="handleMouseUp(rowIndex, cellIndex)" @mousemove="gameStatus == 0 || gameStatus == 1 ? handleMouseMove(rowIndex, cellIndex) : null"
@mousemove="handleMouseMove(rowIndex, cellIndex)"
@contextmenu.prevent @contextmenu.prevent
@select.prevent @select.prevent
draggable="false" draggable="false"
/> />
</div> </div>
</div> </div>
</div> <transition name="fade">
<div class="grid"> <div v-if="gameStatus === 2" class="message">Vous avez gagné !</div>
<div v-for="(row, rowIndex) in cellGrid" :key="rowIndex" class="row"> <div v-else-if="gameStatus === 3" class="message">Vous avez perdu !</div>
<div v-for="(cell, cellIndex) in row" :key="cellIndex"> </transition>
<img class="cell" :src="mineGrid.some(mine => mine[0] === cellIndex && mine[1] === rowIndex) ? '/sMine.png' : '/sEmpty.png'" />
</div>
</div>
</div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.space {
display: flex;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
margin: 30px 60px;
h1 {
flex: 2;
}
}
.menu {
flex: 2;
display: flex;
input {
margin-left: 20px;
}
}
.grid { .grid {
display: grid; display: grid;
border: 10px solid black; border: 4px solid rgb(65, 65, 65);
} }
.row { .row {
display: flex; display: flex;