Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b8dcacd18 | |||
| 4ef4f2b251 | |||
| 17d8cbfedd | |||
| a41e337c43 |
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-nonograms-solid",
|
"name": "vue-nonograms-solid",
|
||||||
"version": "1.6.1",
|
"version": "1.6.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "vue-nonograms-solid",
|
"name": "vue-nonograms-solid",
|
||||||
"version": "1.6.1",
|
"version": "1.6.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fireworks-js": "^2.10.8",
|
"fireworks-js": "^2.10.8",
|
||||||
"flag-icons": "^7.5.0",
|
"flag-icons": "^7.5.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-nonograms-solid",
|
"name": "vue-nonograms-solid",
|
||||||
"version": "1.6.1",
|
"version": "1.6.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed, onMounted, watch } from 'vue';
|
||||||
import { usePuzzleStore } from '@/stores/puzzle';
|
import { usePuzzleStore } from '@/stores/puzzle';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { calculateDifficulty } from '@/utils/puzzleUtils';
|
import { calculateDifficulty } from '@/utils/puzzleUtils';
|
||||||
@@ -12,6 +12,26 @@ const customSize = ref(10);
|
|||||||
const fillRate = ref(50);
|
const fillRate = ref(50);
|
||||||
const errorMsg = ref('');
|
const errorMsg = ref('');
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const savedSize = localStorage.getItem('nonograms_custom_size');
|
||||||
|
if (savedSize && !isNaN(savedSize)) {
|
||||||
|
customSize.value = Math.max(5, Math.min(80, Number(savedSize)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const savedFillRate = localStorage.getItem('nonograms_custom_fill_rate');
|
||||||
|
if (savedFillRate && !isNaN(savedFillRate)) {
|
||||||
|
fillRate.value = Math.max(10, Math.min(90, Number(savedFillRate)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(customSize, (newVal) => {
|
||||||
|
localStorage.setItem('nonograms_custom_size', newVal);
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(fillRate, (newVal) => {
|
||||||
|
localStorage.setItem('nonograms_custom_fill_rate', newVal);
|
||||||
|
});
|
||||||
|
|
||||||
const snapToStep = (value, step) => {
|
const snapToStep = (value, step) => {
|
||||||
const rounded = Math.round(value / step) * step;
|
const rounded = Math.round(value / step) * step;
|
||||||
return Math.max(5, Math.min(80, rounded));
|
return Math.max(5, Math.min(80, rounded));
|
||||||
|
|||||||
@@ -91,15 +91,33 @@ const solveLineLogic = (lineState, hints) => {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const len = hints[hintIndex];
|
const len = hints[hintIndex];
|
||||||
|
// maxStart logic: we need enough space for this block (len) + subsequent blocks/gaps (suffixMin[hintIndex+1])
|
||||||
|
// suffixMin[hintIndex] = len + (m - hintIndex - 1) + suffixMin[hintIndex+1]
|
||||||
|
// Actually suffixMin[hintIndex] already includes everything needed from here to end.
|
||||||
|
// So if we place block at start, end is start + len.
|
||||||
|
// Total space needed is suffixMin[hintIndex].
|
||||||
|
// So start can go up to n - suffixMin[hintIndex].
|
||||||
const maxStart = n - suffixMin[hintIndex];
|
const maxStart = n - suffixMin[hintIndex];
|
||||||
|
|
||||||
for (let start = pos; start <= maxStart; start++) {
|
for (let start = pos; start <= maxStart; start++) {
|
||||||
if (hasFilled(pos, start)) continue;
|
if (hasFilled(pos, start)) continue; // Must be empty before this block
|
||||||
if (hasCross(start, start + len)) continue;
|
if (hasCross(start, start + len)) continue; // Block space must be free of crosses
|
||||||
if (start + len < n && lineState[start + len] === 1) continue;
|
|
||||||
const nextPos = start + len < n ? start + len + 1 : start + len;
|
// If not the last block, we need a gap after
|
||||||
if (canPlaceSuffix(nextPos, hintIndex + 1)) {
|
if (hintIndex < m - 1) {
|
||||||
memoSuffix[pos][hintIndex] = true;
|
if (start + len < n && lineState[start + len] === 1) continue; // Gap must not be filled
|
||||||
return true;
|
// We can assume gap is at start + len. Next block starts at least at start + len + 1
|
||||||
|
const nextPos = start + len + 1;
|
||||||
|
if (canPlaceSuffix(nextPos, hintIndex + 1)) {
|
||||||
|
memoSuffix[pos][hintIndex] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Last block
|
||||||
|
// Check if we can fill the rest with empty
|
||||||
|
if (hasFilled(start + len, n)) continue;
|
||||||
|
memoSuffix[pos][hintIndex] = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memoSuffix[pos][hintIndex] = false;
|
memoSuffix[pos][hintIndex] = false;
|
||||||
@@ -115,16 +133,42 @@ const solveLineLogic = (lineState, hints) => {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
const len = hints[hintCount - 1];
|
const len = hints[hintCount - 1];
|
||||||
const maxStart = pos - len - 1;
|
|
||||||
|
// Logic for prefix:
|
||||||
|
// We are placing the (hintCount-1)-th block ending at 'start + len' <= pos.
|
||||||
|
// So 'start' <= pos - len.
|
||||||
|
// But we also need to ensure there is space for previous blocks.
|
||||||
|
// However, the simple constraint is just iterating backwards.
|
||||||
|
|
||||||
|
// maxStart: if this is the only block, maxStart = pos - len.
|
||||||
|
// If there are previous blocks, we need a gap before this block.
|
||||||
|
// So previous block ended at start - 1.
|
||||||
|
// Actually the recursive call will handle space check.
|
||||||
|
// But for the gap check:
|
||||||
|
// If we place block at 'start', we need lineState[start-1] != 1 (if start > 0).
|
||||||
|
// And we recursively check canPlacePrefix(start-1, count-1).
|
||||||
|
// But if start=0 and count > 1, impossible.
|
||||||
|
|
||||||
|
const maxStart = pos - len; // Simplified, loop condition handles rest
|
||||||
|
|
||||||
for (let start = maxStart; start >= 0; start--) {
|
for (let start = maxStart; start >= 0; start--) {
|
||||||
if (hasCross(start, start + len)) continue;
|
if (hasCross(start, start + len)) continue;
|
||||||
if (start + len < pos && lineState[start + len] === 1) continue;
|
if (hasFilled(start + len, pos)) continue; // Must be empty after this block up to pos
|
||||||
if (hasFilled(start + len, pos)) continue;
|
|
||||||
if (start > 0 && lineState[start - 1] === 1) continue;
|
// Check gap before
|
||||||
const prevPos = start > 0 ? start - 1 : 0;
|
if (hintCount > 1) {
|
||||||
if (canPlacePrefix(prevPos, hintCount - 1)) {
|
if (start === 0) continue; // No space for previous blocks
|
||||||
memoPrefix[pos][hintCount] = true;
|
if (lineState[start - 1] === 1) continue; // Gap must not be filled
|
||||||
return true;
|
const prevPos = start - 1;
|
||||||
|
if (canPlacePrefix(prevPos, hintCount - 1)) {
|
||||||
|
memoPrefix[pos][hintCount] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// First block
|
||||||
|
if (hasFilled(0, start)) continue; // Before first block must be empty
|
||||||
|
memoPrefix[pos][hintCount] = true;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memoPrefix[pos][hintCount] = false;
|
memoPrefix[pos][hintCount] = false;
|
||||||
@@ -136,7 +180,14 @@ const solveLineLogic = (lineState, hints) => {
|
|||||||
const len = hints[i];
|
const len = hints[i];
|
||||||
const starts = [];
|
const starts = [];
|
||||||
for (let start = 0; start <= n - len; start++) {
|
for (let start = 0; start <= n - len; start++) {
|
||||||
if (!canPlacePrefix(start, i)) continue;
|
if (i === 0) {
|
||||||
|
if (!canPlacePrefix(start, 0)) continue;
|
||||||
|
} else {
|
||||||
|
if (start === 0) continue;
|
||||||
|
if (lineState[start - 1] === 1) continue;
|
||||||
|
if (!canPlacePrefix(start - 1, i)) continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (hasCross(start, start + len)) continue;
|
if (hasCross(start, start + len)) continue;
|
||||||
if (start + len < n && lineState[start + len] === 1) continue;
|
if (start + len < n && lineState[start + len] === 1) continue;
|
||||||
const nextPos = start + len < n ? start + len + 1 : start + len;
|
const nextPos = start + len < n ? start + len + 1 : start + len;
|
||||||
|
|||||||
Reference in New Issue
Block a user