337 lines
8.8 KiB
Vue
337 lines
8.8 KiB
Vue
<!-- eslint-disable -->
|
|
<template>
|
|
<div id="app">
|
|
<div
|
|
v-for="(row, rowIndex) in localNumberOfRows"
|
|
:key="`row-${rowIndex}`"
|
|
class="row"
|
|
>
|
|
<div
|
|
v-for="(col, colIndex) in localNumberOfCols"
|
|
:key="`col-${colIndex}`"
|
|
class="cell no-cursor"
|
|
@click="cellOpener(rowIndex, colIndex)"
|
|
@contextmenu.prevent="isCellFlagged(rowIndex, colIndex)"
|
|
:data-value="getCellSymbol(rowIndex, colIndex)"
|
|
:class="{ revealed: isCellRevealed(rowIndex, colIndex) }"
|
|
>
|
|
{{ getCellSymbol(rowIndex, colIndex) }}
|
|
</div>
|
|
</div>
|
|
<v-btn @click="saver()">save</v-btn>
|
|
</div>
|
|
</template>
|
|
<!-- eslint-disable -->
|
|
<script>
|
|
import Swal from "sweetalert2";
|
|
import { Minesweeper, EndGame, Play } from "./Game";
|
|
|
|
export default {
|
|
data: function () {
|
|
return {
|
|
localNumberOfRows: 0,
|
|
localNumberOfCols: 0,
|
|
minesweeperGrid: null,
|
|
numberOfMines: 0,
|
|
item: null,
|
|
undoStack: [],
|
|
redoStack: [],
|
|
};
|
|
},
|
|
name: "Board",
|
|
methods: {
|
|
isCellRevealed(row, col) {
|
|
let cell;
|
|
if (
|
|
this.minesweeperGrid &&
|
|
this.minesweeperGrid.board &&
|
|
this.minesweeperGrid.board.board &&
|
|
this.minesweeperGrid.board.board[row] &&
|
|
row < this.localNumberOfRows &&
|
|
col < this.localNumberOfCols
|
|
) {
|
|
cell = this.minesweeperGrid.board.board[row][col];
|
|
if (cell) {
|
|
return cell.isRevealed;
|
|
}
|
|
}
|
|
return false; // return false when minesweeperGrid is null or the cell doesn't exist
|
|
},
|
|
isCellFlagged(row, col) {
|
|
this.undoStack.push({
|
|
minesweeperGrid: JSON.parse(JSON.stringify(this.minesweeperGrid)),
|
|
numberToWin: this.minesweeperGrid.board.numberToWin
|
|
});
|
|
this.play = new Play();
|
|
this.play.doFlagged(row, col);
|
|
store.commit("UPDATE_MINESWEEPER_GRID", this.minesweeperGrid);
|
|
this.getCellSymbol(row, col);
|
|
},
|
|
|
|
cellOpener(row, col) {
|
|
if (
|
|
this.minesweeperGrid &&
|
|
this.minesweeperGrid.board &&
|
|
this.minesweeperGrid.board.board &&
|
|
this.minesweeperGrid.board.board[row] &&
|
|
this.minesweeperGrid.board.board[row][col] &&
|
|
!this.minesweeperGrid.board.board[row][col].isFlagged
|
|
) {
|
|
this.play = new Play();
|
|
if (!this.minesweeperGrid.board.board[row][col].isMine) {
|
|
this.minesweeperGrid.board.numberToWin = this.$store.state.numberToWin
|
|
this.undoStack.push({
|
|
minesweeperGrid: JSON.parse(JSON.stringify(this.minesweeperGrid)),
|
|
numberToWin: this.minesweeperGrid.board.numberToWin
|
|
});
|
|
if (this.minesweeperGrid.board.numberToWin > 0) {
|
|
console.log(this.minesweeperGrid.board.numberToWin);
|
|
this.play.onClick(row, col);
|
|
} else if (!this.minesweeperGrid.board.board[row][col].isRevealed) {
|
|
Swal.fire({
|
|
title: "you win",
|
|
text: "Do you want to continue",
|
|
icon: "success",
|
|
showCancelButton: true,
|
|
confirmButtonText: "replay",
|
|
cancelButtonText: "Do nothing",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
this.$router.push("/").then(() => window.location.reload());
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
Swal.fire({
|
|
title: "you lose",
|
|
text: "Do you want to continue",
|
|
icon: "error",
|
|
showCancelButton: true,
|
|
confirmButtonText: "replay",
|
|
cancelButtonText: "Do nothing",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
this.$router.push("/").then(() => window.location.reload());
|
|
}
|
|
});
|
|
}
|
|
|
|
this.$store.commit("UPDATE_MINESWEEPER_GRID", this.minesweeperGrid);
|
|
|
|
this.getCellSymbol(row, col);
|
|
this.redoStack = [];
|
|
}
|
|
},
|
|
|
|
saver() {
|
|
this.$store.dispatch("writeOnFile", {
|
|
name: "yazan",
|
|
board: this.minesweeperGrid,
|
|
rows: this.localNumberOfRows,
|
|
cols: this.localNumberOfCols,
|
|
mines: this.numberOfMines,
|
|
numberToWin: this.minesweeperGrid.board.numberToWin,
|
|
undoStack: this.undoStack,
|
|
redoStack: this.redoStack
|
|
});
|
|
},
|
|
|
|
getCellSymbol(row, col) {
|
|
if (
|
|
this.minesweeperGrid &&
|
|
this.minesweeperGrid.board &&
|
|
this.minesweeperGrid.board.board &&
|
|
this.minesweeperGrid.board.board[row] &&
|
|
row < this.localNumberOfRows &&
|
|
col < this.localNumberOfCols
|
|
) {
|
|
let cell = this.minesweeperGrid.board.board[row][col];
|
|
if (cell) {
|
|
if (cell.isFlagged) {
|
|
return "F";
|
|
} else if (cell.isRevealed === true) {
|
|
return String(cell.nearbyMines);
|
|
} else if (!cell.isRevealed) {
|
|
return "#";
|
|
}
|
|
}
|
|
}
|
|
return "#";
|
|
},
|
|
|
|
undo() {
|
|
if (this.undoStack.length > 0) {
|
|
let localNumberToWin = this.$store.state.numberToWin
|
|
this.redoStack.push({
|
|
minesweeperGrid: JSON.parse(JSON.stringify(this.minesweeperGrid)),
|
|
numberToWin: localNumberToWin
|
|
});
|
|
let undoState = this.undoStack.pop();
|
|
this.minesweeperGrid = undoState.minesweeperGrid;
|
|
this.$store.commit("UPDATE_NUMBER_TO_WIN", undoState.numberToWin);
|
|
this.$store.commit("UPDATE_MINESWEEPER_GRID", this.minesweeperGrid);
|
|
}
|
|
},
|
|
|
|
redo() {
|
|
if (this.redoStack.length > 0) {
|
|
this.undoStack.push({
|
|
minesweeperGrid: JSON.parse(JSON.stringify(this.minesweeperGrid)),
|
|
numberToWin: this.minesweeperGrid.board.numberToWin
|
|
});
|
|
let redoState = this.redoStack.pop();
|
|
this.minesweeperGrid = redoState.minesweeperGrid;
|
|
this.$store.commit("UPDATE_NUMBER_TO_WIN", redoState.numberToWin);
|
|
this.$store.commit("UPDATE_MINESWEEPER_GRID", this.minesweeperGrid);
|
|
}
|
|
},
|
|
keydownHandler(event) {
|
|
if (event.ctrlKey && event.key === "z") {
|
|
this.undo();
|
|
}
|
|
if (event.ctrlKey && event.key === "y") {
|
|
this.redo();
|
|
}
|
|
},
|
|
},
|
|
computed: {
|
|
numberToWin() {
|
|
return this.$store.state.numberToWin;
|
|
}
|
|
},
|
|
watch: {
|
|
numberToWin(newVal) {
|
|
if (newVal === 0) {
|
|
Swal.fire({
|
|
title: "you win",
|
|
text: "Do you want to continue",
|
|
icon: "success",
|
|
showCancelButton: true,
|
|
confirmButtonText: "replay",
|
|
cancelButtonText: "Do nothing",
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
this.$router.push("/").then(() => window.location.reload());
|
|
}
|
|
});
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
this.$nextTick(() => {
|
|
window.addEventListener("keydown", this.keydownHandler);
|
|
this.undoStack = this.$store.state.undo;
|
|
this.redoStack = this.$store.state.redo;
|
|
this.localNumberOfRows = this.$store.state.numberOfRows;
|
|
this.localNumberOfCols = this.$store.state.numberOfCols;
|
|
this.numberOfMines = this.$store.state.numberOfMines;
|
|
this.localNumberOfRows = parseInt(this.localNumberOfRows);
|
|
this.localNumberOfCols = parseInt(this.localNumberOfCols);
|
|
this.numberOfMines = parseInt(this.numberOfMines);
|
|
|
|
let minesweeperGrid = this.$store.state.minesweeperGrid;
|
|
// let minesweeperGrid = JSON.parse(localStorage.getItem("minesweeperGrid"));
|
|
this.minesweeperGrid = minesweeperGrid;
|
|
this.numberToWin = this.$store.state.numberToWin;
|
|
// this.numberToWin = parseInt(localStorage.getItem("numberToWin"));
|
|
});
|
|
},
|
|
beforeDestroy() {
|
|
window.removeEventListener("keydown", this.keydownHandler);
|
|
},
|
|
|
|
// created() {
|
|
// window.addEventListener('keydown', this.keydownHandler);
|
|
// },
|
|
// beforeDestroy() {
|
|
// window.removeEventListener('keydown', this.keydownHandler);
|
|
// },
|
|
|
|
};
|
|
</script>
|
|
<!-- eslint-disable -->
|
|
<style>
|
|
.no-cursor {
|
|
caret-color: transparent;
|
|
}
|
|
#app {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 20px;
|
|
/* background-color: #f5f5f5; */
|
|
}
|
|
|
|
.row {
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.cell {
|
|
width: 30px;
|
|
height: 30px;
|
|
border: 1px solid #333;
|
|
margin: 2px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
text-align: center;
|
|
background-color: #ccc;
|
|
cursor: pointer;
|
|
transition: background-color 0.3s ease;
|
|
}
|
|
|
|
.cell:hover {
|
|
background-color: #aaa;
|
|
}
|
|
|
|
.v-btn {
|
|
margin-top: 20px;
|
|
align-self: center;
|
|
}
|
|
|
|
/* Unique colors for each number */
|
|
.cell[data-value="0"] {
|
|
background-color: blue;
|
|
}
|
|
.cell[data-value="1"] {
|
|
background-color: pink;
|
|
}
|
|
.cell[data-value="2"] {
|
|
background-color: green;
|
|
}
|
|
.cell[data-value="3"] {
|
|
background-color: red;
|
|
}
|
|
.cell[data-value="4"] {
|
|
background-color: purple;
|
|
}
|
|
.cell[data-value="5"] {
|
|
background-color: maroon;
|
|
}
|
|
.cell[data-value="6"] {
|
|
background-color: turquoise;
|
|
}
|
|
.cell[data-value="7"] {
|
|
background-color: black;
|
|
}
|
|
.cell[data-value="8"] {
|
|
background-color: gray;
|
|
}
|
|
|
|
/* Animation when a cell is revealed */
|
|
@keyframes reveal {
|
|
0% {
|
|
background-color: #ccc;
|
|
}
|
|
100% {
|
|
background-color: #eee;
|
|
}
|
|
}
|
|
|
|
.cell.revealed {
|
|
animation: reveal 0.3s ease;
|
|
}
|
|
</style>
|