Add winning
This commit is contained in:
parent
bb475b74f9
commit
d863129361
3 changed files with 141 additions and 5 deletions
|
|
@ -233,3 +233,35 @@ details[open] > .config-summary::before {
|
||||||
.config-content {
|
.config-content {
|
||||||
padding-left: 1.5rem; /* Indent content */
|
padding-left: 1.5rem; /* Indent content */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Animation for winning cells --- */
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 0 rgba(0, 255, 110, 0.7); /* Emerald-400 */
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: scale(1.02);
|
||||||
|
box-shadow: 0 0 10px 10px rgba(0, 255, 110, 0.5); /* Emerald-400 transparent */
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
box-shadow: 0 0 0 0 rgba(0, 255, 110, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- Style for winning cells --- */
|
||||||
|
.bingo-cell.win-cell {
|
||||||
|
/* Apply a distinct border to indicate win */
|
||||||
|
border-color: #10b981; /* Emerald-500 */
|
||||||
|
border-width: 3px; /* Make border more prominent */
|
||||||
|
animation: pulse 1.5s infinite;
|
||||||
|
z-index: 15; /* Ensure winning cells are on top of highlighted/others */
|
||||||
|
/* Optional: Slightly different background tint? */
|
||||||
|
/* Example: background-color: rgba(16, 185, 129, 0.1); /* Light emerald tint */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure winning cell text is still readable over potential background tint */
|
||||||
|
.bingo-cell.win-cell .bingo-cell-text {
|
||||||
|
z-index: 16; /* Keep text above the cell's base styles/animations */
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Beango!</title>
|
<title>Beango!</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<link rel="stylesheet" href="css/beango.css?v=1.0.3">
|
<link rel="stylesheet" href="css/beango.css?v=1.0.4">
|
||||||
<link rel="icon" type="image/svg+xml" href="/bean.svg">
|
<link rel="icon" type="image/svg+xml" href="/bean.svg">
|
||||||
</head>
|
</head>
|
||||||
<body class="flex flex-col items-center justify-center p-4 font-sans relative">
|
<body class="flex flex-col items-center justify-center p-4 font-sans relative">
|
||||||
|
|
@ -439,7 +439,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="module" src="js/beango.js?v=1.0.2"></script>
|
<script type="module" src="js/beango.js?v=1.0.3"></script>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import { toggleConfig, exportSettings, importSettings, resetAllSettings, explodeBeans, randomizeBoard, clearMarks, generateBoard, resetSettings } from './js/beango.js';
|
import { toggleConfig, exportSettings, importSettings, resetAllSettings, explodeBeans, randomizeBoard, clearMarks, generateBoard, resetSettings } from './js/beango.js';
|
||||||
window.explodeBeans = explodeBeans;
|
window.explodeBeans = explodeBeans;
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,8 @@ function refreshMarkedCellStyles() {
|
||||||
markedCells.forEach(cell => {
|
markedCells.forEach(cell => {
|
||||||
applyMarkedCellStyle(cell); // Re-apply based on current settings
|
applyMarkedCellStyle(cell); // Re-apply based on current settings
|
||||||
});
|
});
|
||||||
|
// After refreshing marked styles, check for wins
|
||||||
|
checkWinConditions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Save current header settings to localStorage ---
|
// --- Save current header settings to localStorage ---
|
||||||
|
|
@ -726,6 +728,7 @@ export function randomizeBoard() {
|
||||||
|
|
||||||
clearSearch(); // Clear search highlights and input
|
clearSearch(); // Clear search highlights and input
|
||||||
clearMarks(false); // Clear visual marks
|
clearMarks(false); // Clear visual marks
|
||||||
|
checkWinConditions(); // Check for wins after randomization (should be none)
|
||||||
saveBoardState(); // Save the new randomized state (including cleared marks)
|
saveBoardState(); // Save the new randomized state (including cleared marks)
|
||||||
showNotification('Board randomized!', 'success');
|
showNotification('Board randomized!', 'success');
|
||||||
}
|
}
|
||||||
|
|
@ -734,6 +737,7 @@ function selectCell(cell) {
|
||||||
cell.classList.toggle("marked"); // Toggle the dedicated 'marked' class
|
cell.classList.toggle("marked"); // Toggle the dedicated 'marked' class
|
||||||
applyMarkedCellStyle(cell); // Apply/remove styles based on new state and settings
|
applyMarkedCellStyle(cell); // Apply/remove styles based on new state and settings
|
||||||
saveBoardState(); // RE-ADD: Save updated marks immediately after click
|
saveBoardState(); // RE-ADD: Save updated marks immediately after click
|
||||||
|
checkWinConditions(); // Check for wins after a cell is selected/deselected
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearMarks(save = true) {
|
export function clearMarks(save = true) {
|
||||||
|
|
@ -741,17 +745,19 @@ export function clearMarks(save = true) {
|
||||||
cells.forEach(cell => {
|
cells.forEach(cell => {
|
||||||
if (cell.classList.contains('marked')) {
|
if (cell.classList.contains('marked')) {
|
||||||
cell.classList.remove('marked');
|
cell.classList.remove('marked');
|
||||||
// applyMarkedCellStyle(cell); // Redundant call removed
|
|
||||||
// Apply default style ONLY to the cell just unmarked
|
// Apply default style ONLY to the cell just unmarked
|
||||||
applyCellStyle(cell);
|
applyCellStyle(cell);
|
||||||
}
|
}
|
||||||
// Ensure styles are reset even if class was somehow missing
|
cell.classList.remove('win-cell'); // NEW: Remove win highlight
|
||||||
// applyCellStyle(cell); // REMOVED Unconditional call
|
|
||||||
});
|
});
|
||||||
|
// Remove win class from all cells, even unmarked ones
|
||||||
|
cells.forEach(cell => cell.classList.remove('win-cell'));
|
||||||
|
|
||||||
if (save) {
|
if (save) {
|
||||||
saveBoardState(); // Save cleared marks
|
saveBoardState(); // Save cleared marks
|
||||||
showNotification('Marks cleared.', 'info');
|
showNotification('Marks cleared.', 'info');
|
||||||
}
|
}
|
||||||
|
// No need to call checkWinConditions here, as all marks are cleared
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fisher-Yates (aka Knuth) Shuffle Algorithm
|
// Fisher-Yates (aka Knuth) Shuffle Algorithm
|
||||||
|
|
@ -1494,8 +1500,106 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
// Equalize sizes as the very last step after all content and styles are set
|
// Equalize sizes as the very last step after all content and styles are set
|
||||||
equalizeCellSizes(); // <-- MOVED HERE
|
equalizeCellSizes(); // <-- MOVED HERE
|
||||||
|
// Check for win conditions after loading everything
|
||||||
|
checkWinConditions();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- Function to check win conditions ---
|
||||||
|
function checkWinConditions() {
|
||||||
|
const board = document.getElementById('bingo-board');
|
||||||
|
if (!board) return;
|
||||||
|
const cells = board.querySelectorAll('.bingo-cell');
|
||||||
|
if (cells.length === 0) return; // No cells to check
|
||||||
|
|
||||||
|
const size = parseInt(localStorage.getItem(vars.LS_BOARD_SIZE) || '5', 10);
|
||||||
|
const markedIndices = getMarkedIndices(); // Get the indices of marked cells
|
||||||
|
|
||||||
|
if (markedIndices.length < size) { // Not enough marks for a win
|
||||||
|
// Ensure no win class remains if marks are removed below threshold
|
||||||
|
cells.forEach(cell => cell.classList.remove('win-cell'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const winningIndices = new Set();
|
||||||
|
|
||||||
|
// Create a representation of the board (e.g., 2D array or set)
|
||||||
|
const markedSet = new Set(markedIndices);
|
||||||
|
|
||||||
|
// Check Rows
|
||||||
|
for (let r = 0; r < size; r++) {
|
||||||
|
let rowWin = true;
|
||||||
|
const rowIndices = [];
|
||||||
|
for (let c = 0; c < size; c++) {
|
||||||
|
const index = r * size + c;
|
||||||
|
rowIndices.push(index);
|
||||||
|
if (!markedSet.has(index)) {
|
||||||
|
rowWin = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rowWin) {
|
||||||
|
rowIndices.forEach(idx => winningIndices.add(idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Columns
|
||||||
|
for (let c = 0; c < size; c++) {
|
||||||
|
let colWin = true;
|
||||||
|
const colIndices = [];
|
||||||
|
for (let r = 0; r < size; r++) {
|
||||||
|
const index = r * size + c;
|
||||||
|
colIndices.push(index);
|
||||||
|
if (!markedSet.has(index)) {
|
||||||
|
colWin = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (colWin) {
|
||||||
|
colIndices.forEach(idx => winningIndices.add(idx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Diagonal (Top-Left to Bottom-Right)
|
||||||
|
let diag1Win = true;
|
||||||
|
const diag1Indices = [];
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
const index = i * size + i;
|
||||||
|
diag1Indices.push(index);
|
||||||
|
if (!markedSet.has(index)) {
|
||||||
|
diag1Win = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (diag1Win) {
|
||||||
|
diag1Indices.forEach(idx => winningIndices.add(idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Diagonal (Top-Right to Bottom-Left)
|
||||||
|
let diag2Win = true;
|
||||||
|
const diag2Indices = [];
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
const index = i * size + (size - 1 - i);
|
||||||
|
diag2Indices.push(index);
|
||||||
|
if (!markedSet.has(index)) {
|
||||||
|
diag2Win = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (diag2Win) {
|
||||||
|
diag2Indices.forEach(idx => winningIndices.add(idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply 'win-cell' class
|
||||||
|
cells.forEach((cell, index) => {
|
||||||
|
if (winningIndices.has(index)) {
|
||||||
|
cell.classList.add('win-cell');
|
||||||
|
} else {
|
||||||
|
cell.classList.remove('win-cell');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --- Settings Import/Export ---
|
// --- Settings Import/Export ---
|
||||||
export function exportSettings() {
|
export function exportSettings() {
|
||||||
const settingsToExport = {};
|
const settingsToExport = {};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue