4 Commits

6 changed files with 63 additions and 15 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "vue-nonograms-solid", "name": "vue-nonograms-solid",
"version": "1.9.2", "version": "1.9.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "vue-nonograms-solid", "name": "vue-nonograms-solid",
"version": "1.9.2", "version": "1.9.4",
"dependencies": { "dependencies": {
"fireworks-js": "^2.10.8", "fireworks-js": "^2.10.8",
"flag-icons": "^7.5.0", "flag-icons": "^7.5.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "vue-nonograms-solid", "name": "vue-nonograms-solid",
"version": "1.9.2", "version": "1.9.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -190,6 +190,7 @@ onUnmounted(() => {
gap: 20px; gap: 20px;
width: 100%; width: 100%;
padding-bottom: 50px; padding-bottom: 50px;
padding-top: 100px; /* Space for fixed NavBar */
} }
.install-banner { .install-banner {
@@ -204,6 +205,9 @@ onUnmounted(() => {
max-width: 600px; max-width: 600px;
margin: 0 auto 20px auto; /* Center it manually */ margin: 0 auto 20px auto; /* Center it manually */
box-shadow: var(--banner-shadow); box-shadow: var(--banner-shadow);
position: sticky;
left: 0;
right: 0;
} }
.install-text { .install-text {
@@ -239,6 +243,9 @@ onUnmounted(() => {
margin-right: auto; margin-right: auto;
max-width: 1200px; /* Keep constraint for panels */ max-width: 1200px; /* Keep constraint for panels */
width: 100%; width: 100%;
position: sticky;
left: 0;
right: 0;
} }
.board-section { .board-section {

View File

@@ -435,8 +435,10 @@ watch(isMobileMenuOpen, (val) => {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
z-index: 100; z-index: 100;
position: sticky; position: fixed;
top: 0; top: 0;
left: 0;
right: 0;
} }
.nav-left { .nav-left {

View File

@@ -2,6 +2,34 @@ import { defineStore } from 'pinia';
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { generateRandomGrid } from '@/utils/puzzleUtils'; import { generateRandomGrid } from '@/utils/puzzleUtils';
// Helper: Calculate hints for a line (row or column)
function calculateHints(line) {
const hints = [];
let currentRun = 0;
for (const cell of line) {
if (cell === 1) {
currentRun++;
} else {
if (currentRun > 0) {
hints.push(currentRun);
currentRun = 0;
}
}
}
if (currentRun > 0) {
hints.push(currentRun);
}
return hints.length > 0 ? hints : [0];
}
// Helper: Validate if a line matches its hints
function validateLine(line, targetHints) {
const currentHints = calculateHints(line);
if (currentHints.length !== targetHints.length) return false;
return currentHints.every((h, i) => h === targetHints[i]);
}
// Definicje zagadek (Static Puzzles) // Definicje zagadek (Static Puzzles)
const PUZZLES = { const PUZZLES = {
easy: { easy: {
@@ -249,20 +277,32 @@ export const usePuzzleStore = defineStore('puzzle', () => {
function checkWin() { function checkWin() {
let correct = true; let correct = true;
// Calculate expected hints from solution (truth)
// We do this dynamically to ensure we always check against the rules of the board
const solutionRows = solution.value;
const solutionCols = Array(size.value).fill().map((_, c) => solution.value.map(r => r[c]));
// Check Rows
for (let r = 0; r < size.value; r++) { for (let r = 0; r < size.value; r++) {
const targetHints = calculateHints(solutionRows[r]);
const playerLine = playerGrid.value[r];
if (!validateLine(playerLine, targetHints)) {
correct = false;
break;
}
}
if (correct) {
// Check Columns
for (let c = 0; c < size.value; c++) { for (let c = 0; c < size.value; c++) {
const playerCell = playerGrid.value[r][c]; const targetHints = calculateHints(solutionCols[c]);
const solutionCell = solution.value[r][c]; const playerLine = playerGrid.value.map(row => row[c]);
if (!validateLine(playerLine, targetHints)) {
const isFilled = playerCell === 1;
const shouldBeFilled = solutionCell === 1;
if (isFilled !== shouldBeFilled) {
correct = false; correct = false;
break; break;
} }
} }
if (!correct) break;
} }
if (correct) { if (correct) {

View File

@@ -130,7 +130,6 @@
} }
html { html {
overflow-x: hidden;
width: 100%; width: 100%;
} }
@@ -139,18 +138,18 @@ body {
padding: 20px; padding: 20px;
font-family: 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif; font-family: 'Segoe UI', 'Roboto', Helvetica, Arial, sans-serif;
background: var(--bg-gradient); background: var(--bg-gradient);
background-attachment: fixed;
background-size: cover;
color: var(--text-color); color: var(--text-color);
min-height: 100vh; min-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
overflow-x: hidden;
} }
/* Ensure no other content is visible */ /* Ensure no other content is visible */
#app { #app {
width: 100%; width: 100%;
max-width: 100vw;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;