WIP
This commit is contained in:
parent
f67606b944
commit
1e71255371
9 changed files with 389 additions and 335 deletions
|
@ -1,24 +1,15 @@
|
|||
import { makePersisted } from "@solid-primitives/storage";
|
||||
import connections from "./assets/connections.json";
|
||||
import { shuffleArray } from "./utils";
|
||||
import { createStore } from "solid-js/store";
|
||||
import { tauriStorage } from "@solid-primitives/storage/tauri";
|
||||
|
||||
type Connection = (typeof connections)[number];
|
||||
type Answer = Connection["answers"][number];
|
||||
|
||||
function fromIndex(index: number): [number, number] {
|
||||
const col = index % 4;
|
||||
const row = (index - col) / 4;
|
||||
return [row, col];
|
||||
type Solution = {
|
||||
id: number
|
||||
mistakes: number
|
||||
}
|
||||
|
||||
type AppStore = {
|
||||
puzzleId: number;
|
||||
pinnedCount: number;
|
||||
selected: number[];
|
||||
solvedGroups: Answer[];
|
||||
puzzle: number[];
|
||||
solutions: Solution[]
|
||||
};
|
||||
|
||||
export default function useAppModel() {
|
||||
|
@ -26,138 +17,23 @@ export default function useAppModel() {
|
|||
"__TAURI_INTERNALS__" in window ? tauriStorage("AppStore") : localStorage;
|
||||
const [store, setStore] = makePersisted(
|
||||
createStore<AppStore>({
|
||||
puzzleId: 1,
|
||||
pinnedCount: 0,
|
||||
selected: [],
|
||||
solvedGroups: [],
|
||||
puzzle: shuffleArray(Array.from({ length: 16 }, (_, i) => i)),
|
||||
solutions: []
|
||||
}),
|
||||
{
|
||||
name: "slick-connections",
|
||||
storage,
|
||||
serialize(data) {
|
||||
return JSON.stringify({
|
||||
...data,
|
||||
selected: [],
|
||||
});
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const answers = (): Answer[] => {
|
||||
return connections.find((x) => x.id === store.puzzleId)!.answers;
|
||||
};
|
||||
|
||||
const handleSelectGame = (newId: number) => {
|
||||
setStore({
|
||||
puzzleId: newId,
|
||||
selected: [],
|
||||
pinnedCount: 0,
|
||||
puzzle: shuffleArray(Array.from({ length: 16 }, (_, i) => i)),
|
||||
solvedGroups: [],
|
||||
});
|
||||
};
|
||||
|
||||
const getFromPuzzle = (index: number) => {
|
||||
const puzzleIndex = store.puzzle[index];
|
||||
const [groupIndex, memberIndex] = fromIndex(puzzleIndex);
|
||||
const group = answers()[groupIndex];
|
||||
return {
|
||||
group: group.group,
|
||||
level: group.level,
|
||||
answer: answers()[groupIndex].members[memberIndex],
|
||||
};
|
||||
};
|
||||
|
||||
const handleGuess = () => {
|
||||
const selected = store.puzzle.length === 4 ? [0, 1, 2, 3] : store.selected;
|
||||
const selectedAnswers = selected.map((x) => getFromPuzzle(x));
|
||||
const { level } = selectedAnswers[0];
|
||||
const isCorrect = selectedAnswers.every((x) => x.level === level);
|
||||
if (!isCorrect) {
|
||||
// TODO you got it wrong
|
||||
alert("wrong");
|
||||
return;
|
||||
}
|
||||
const selectedPinnedCount = selected.reduce(
|
||||
(acc, cur) => acc + (cur < store.pinnedCount ? 1 : 0),
|
||||
0
|
||||
);
|
||||
setStore({
|
||||
pinnedCount: store.pinnedCount - selectedPinnedCount,
|
||||
puzzle: store.puzzle.filter((x) =>
|
||||
selected.every((s) => store.puzzle[s] !== x)
|
||||
),
|
||||
selected: [],
|
||||
});
|
||||
const newSolvedGroup = answers().find((x) => x.level === level);
|
||||
if (newSolvedGroup != null) {
|
||||
setStore({
|
||||
solvedGroups: [...store.solvedGroups, newSolvedGroup],
|
||||
});
|
||||
}
|
||||
if (store.puzzle.length === 0) {
|
||||
// completely solved!
|
||||
}
|
||||
};
|
||||
|
||||
const handleShuffle = () => {
|
||||
const pinned = store.puzzle.slice(0, store.pinnedCount);
|
||||
const toShuffle = store.puzzle.slice(store.pinnedCount);
|
||||
setStore({
|
||||
puzzle: [...pinned, ...shuffleArray(toShuffle)],
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeselect = () => {
|
||||
setStore({
|
||||
selected: [],
|
||||
});
|
||||
};
|
||||
|
||||
const handlePinUnpin = () => {
|
||||
if (store.selected.every((x) => x < store.pinnedCount)) {
|
||||
// we are unpinning
|
||||
const puzzleStart = Array.from({ length: store.pinnedCount }, (_, i) => i)
|
||||
.filter((x) => !store.selected.includes(x))
|
||||
.map((x) => store.puzzle[x]);
|
||||
const puzzleMiddle = store.selected.map((x) => store.puzzle[x]);
|
||||
const puzzleEnd = store.puzzle.slice(store.pinnedCount);
|
||||
const newPuzzle = [...puzzleStart, ...puzzleMiddle, ...puzzleEnd];
|
||||
setStore({
|
||||
pinnedCount: store.pinnedCount - store.selected.length,
|
||||
selected: [],
|
||||
puzzle: newPuzzle,
|
||||
});
|
||||
return;
|
||||
}
|
||||
// we are pinning
|
||||
const puzzleStart = store.puzzle.slice(0, store.pinnedCount);
|
||||
const puzzleMid = store.selected
|
||||
.filter((x) => x >= store.pinnedCount)
|
||||
.map((x) => store.puzzle[x]);
|
||||
const puzzleEnd = Array.from(
|
||||
{ length: store.puzzle.length - store.pinnedCount },
|
||||
(_, i) => i + store.pinnedCount
|
||||
)
|
||||
.filter((x) => !store.selected.includes(x))
|
||||
.map((x) => store.puzzle[x]);
|
||||
setStore({
|
||||
pinnedCount: puzzleStart.length + puzzleMid.length,
|
||||
selected: [],
|
||||
puzzle: [...puzzleStart, ...puzzleMid, ...puzzleEnd],
|
||||
});
|
||||
};
|
||||
function setSolution(id: number, mistakes: number) {
|
||||
setStore("solutions", id, {
|
||||
id,
|
||||
mistakes
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
connections,
|
||||
store,
|
||||
setStore,
|
||||
handleGuess,
|
||||
handlePinUnpin,
|
||||
handleSelectGame,
|
||||
handleShuffle,
|
||||
handleDeselect,
|
||||
getFromPuzzle,
|
||||
setSolution,
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue