Add winning

This commit is contained in:
Joey Yakimowich-Payne 2025-04-19 07:43:27 -06:00
commit d863129361
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
3 changed files with 141 additions and 5 deletions

View file

@ -233,3 +233,35 @@ details[open] > .config-summary::before {
.config-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 */
}

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Beango!</title>
<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">
</head>
<body class="flex flex-col items-center justify-center p-4 font-sans relative">
@ -439,7 +439,7 @@
</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">
import { toggleConfig, exportSettings, importSettings, resetAllSettings, explodeBeans, randomizeBoard, clearMarks, generateBoard, resetSettings } from './js/beango.js';
window.explodeBeans = explodeBeans;

View file

@ -231,6 +231,8 @@ function refreshMarkedCellStyles() {
markedCells.forEach(cell => {
applyMarkedCellStyle(cell); // Re-apply based on current settings
});
// After refreshing marked styles, check for wins
checkWinConditions();
}
// --- Save current header settings to localStorage ---
@ -726,6 +728,7 @@ export function randomizeBoard() {
clearSearch(); // Clear search highlights and input
clearMarks(false); // Clear visual marks
checkWinConditions(); // Check for wins after randomization (should be none)
saveBoardState(); // Save the new randomized state (including cleared marks)
showNotification('Board randomized!', 'success');
}
@ -734,6 +737,7 @@ function selectCell(cell) {
cell.classList.toggle("marked"); // Toggle the dedicated 'marked' class
applyMarkedCellStyle(cell); // Apply/remove styles based on new state and settings
saveBoardState(); // RE-ADD: Save updated marks immediately after click
checkWinConditions(); // Check for wins after a cell is selected/deselected
}
export function clearMarks(save = true) {
@ -741,17 +745,19 @@ export function clearMarks(save = true) {
cells.forEach(cell => {
if (cell.classList.contains('marked')) {
cell.classList.remove('marked');
// applyMarkedCellStyle(cell); // Redundant call removed
// Apply default style ONLY to the cell just unmarked
applyCellStyle(cell);
}
// Ensure styles are reset even if class was somehow missing
// applyCellStyle(cell); // REMOVED Unconditional call
cell.classList.remove('win-cell'); // NEW: Remove win highlight
});
// Remove win class from all cells, even unmarked ones
cells.forEach(cell => cell.classList.remove('win-cell'));
if (save) {
saveBoardState(); // Save cleared marks
showNotification('Marks cleared.', 'info');
}
// No need to call checkWinConditions here, as all marks are cleared
}
// 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
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 ---
export function exportSettings() {
const settingsToExport = {};