basic functionality!
This commit is contained in:
parent
f462002407
commit
b6d12c7e47
2 changed files with 167 additions and 40 deletions
89
src/App.css
89
src/App.css
|
@ -19,6 +19,15 @@
|
|||
color: var(--color-foreground);
|
||||
background-color: var(--color-background);
|
||||
|
||||
/* --group-blue: lch(78.8% 23.7 270.9);
|
||||
--group-yellow: lch(74.83% 54.18 117.22);
|
||||
--group-green: lch(89.36% 57.75 90.6);
|
||||
--group-purple: lch(61.69% 41.01 319.57); */
|
||||
--group-blue: lch(80% 23.7 270.9);
|
||||
--group-yellow: lch(80% 54.18 117.22);
|
||||
--group-green: lch(80% 57.75 90.6);
|
||||
--group-purple: lch(80% 41.01 319.57);
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
|
@ -34,6 +43,11 @@
|
|||
--foreground-lightness: 90%;
|
||||
--foreground-chroma: 0;
|
||||
--foreground-hue: 0;
|
||||
|
||||
--group-blue: lch(30% 23.7 270.9);
|
||||
--group-yellow: lch(30% 54.18 117.22);
|
||||
--group-green: lch(30% 57.75 90.6);
|
||||
--group-purple: lch(30% 41.01 319.57);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,18 +66,21 @@
|
|||
}
|
||||
|
||||
.puzzle {
|
||||
--unit: 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1vmin;
|
||||
font-size: 3vmin;
|
||||
gap: calc(1 * var(--unit));
|
||||
font-size: calc(3 * var(--unit));
|
||||
font-weight: 600;
|
||||
width: calc((20 * 4 + 3) * var(--unit));
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.puzzle-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
height: 15vmin;
|
||||
gap: 1vmin;
|
||||
height: calc(15 * var(--unit));
|
||||
gap: calc(1 * var(--unit));
|
||||
}
|
||||
.puzzle-item {
|
||||
display: flex;
|
||||
|
@ -71,17 +88,44 @@
|
|||
align-items: center;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
width: 20vmin;
|
||||
border-radius: 1vmin;
|
||||
flex-grow: 0;
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
padding: 0;
|
||||
border-radius: calc(1 * var(--unit));
|
||||
background-color: var(--color-foreground-trace);
|
||||
}
|
||||
.puzzle-item:hover, .puzzle-item:focus-visible {
|
||||
box-shadow: 0 0 3vmin -1vmin inset var(--color-foreground);
|
||||
}
|
||||
.puzzle-item.is-selected {
|
||||
background-color: var(--color-foreground-faint);
|
||||
outline: 0.33vmin solid var(--color-foreground);
|
||||
outline: calc(0.33 * var(--unit)) solid var(--color-foreground);
|
||||
}
|
||||
.puzzle-group {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: calc(1 * var(--unit));
|
||||
|
||||
&[data-level="0"] {
|
||||
background-color: var(--group-blue);
|
||||
}
|
||||
|
||||
&[data-level="1"] {
|
||||
background-color: var(--group-yellow);
|
||||
}
|
||||
|
||||
&[data-level="2"] {
|
||||
background-color: var(--group-green);
|
||||
}
|
||||
|
||||
&[data-level="3"] {
|
||||
background-color: var(--group-purple);
|
||||
}
|
||||
}
|
||||
.puzzle-actions {
|
||||
display: flex;
|
||||
margin-top: calc(1 * var(--unit));
|
||||
gap: calc(1 * var(--unit));
|
||||
}
|
||||
|
||||
a {
|
||||
|
@ -97,3 +141,26 @@ a:hover {
|
|||
h1 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button {
|
||||
appearance: none;
|
||||
overflow: visible;
|
||||
background: var(--color-foreground-faint);
|
||||
color: var(--color-foreground);
|
||||
font-size: inherit;
|
||||
border: none;
|
||||
padding: 0.5em 1.5em;
|
||||
border-radius: calc(1 * var(--unit, 0.5em));
|
||||
}
|
||||
button:disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
button:focus-visible, button:hover {
|
||||
box-shadow: 0 0 3em -1.5em inset var(--color-foreground)
|
||||
}
|
||||
button:active {
|
||||
box-shadow: 0 0 3em -1.5em inset var(--color-foreground)
|
||||
}
|
||||
#submitButton {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
|
118
src/App.tsx
118
src/App.tsx
|
@ -3,6 +3,9 @@ import connections from "./assets/connections.json";
|
|||
import "./App.css";
|
||||
import { shuffleArray } from "./utils";
|
||||
|
||||
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;
|
||||
|
@ -11,52 +14,109 @@ function fromIndex(index: number): [number, number] {
|
|||
|
||||
function App() {
|
||||
const [puzzleIndex, setPuzzleIndex] = createSignal(0);
|
||||
// const [pinnedCount, setPinnedCount] = createSignal(0);
|
||||
const [selected, setSelected] = createSignal<number[]>([]);
|
||||
const puzzle = createMemo(() =>
|
||||
const [solvedGroups, setSolvedGroups] = createSignal<Answer[]>([])
|
||||
const [puzzle, setPuzzle] = createSignal(
|
||||
shuffleArray(
|
||||
Array(16)
|
||||
.fill(0)
|
||||
.map((_, i) => i)
|
||||
)
|
||||
);
|
||||
|
||||
const answers = () => connections[puzzleIndex()].answers;
|
||||
const getFromPuzzle = (index: number) => {
|
||||
const puzzleIndex = 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 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;
|
||||
}
|
||||
setPuzzle(puzzle().filter((x) => selected().every(s => puzzle()[s] !== x)));
|
||||
setSelected([]);
|
||||
const newSolvedGroup = answers().find((x) => x.level === level);
|
||||
if (newSolvedGroup != null) {
|
||||
setSolvedGroups([...solvedGroups(), newSolvedGroup])
|
||||
}
|
||||
};
|
||||
// const handlePinUnpin = () => {
|
||||
// const sel = selected()
|
||||
// if (sel.every(x => x <= pinnedCount())) {
|
||||
// // we are unpinning
|
||||
// return
|
||||
// }
|
||||
// // we are pinning
|
||||
// }
|
||||
|
||||
return (
|
||||
<main class="container">
|
||||
<h1>Slick Connections</h1>
|
||||
<div class="puzzle">
|
||||
<For each={[0, 1, 2, 3]}>
|
||||
{(row) => (
|
||||
<For each={solvedGroups()}>
|
||||
{({group, level, members}) => (
|
||||
<div class="puzzle-row">
|
||||
<For each={[0, 1, 2, 3]}>
|
||||
{(col) => {
|
||||
const index = 4 * row + col;
|
||||
const puzzleIndex = puzzle()[index];
|
||||
const [groupIndex, memberIndex] = fromIndex(puzzleIndex);
|
||||
const answer = answers()[groupIndex].members[memberIndex];
|
||||
return (
|
||||
<div
|
||||
classList={{
|
||||
"puzzle-item": true,
|
||||
"is-selected": selected().includes(index),
|
||||
}}
|
||||
tabindex="0"
|
||||
on:click={() => {
|
||||
setSelected(
|
||||
selected().includes(index)
|
||||
? selected().filter(x => x !== index)
|
||||
: [...selected(), index]
|
||||
);
|
||||
}}
|
||||
>
|
||||
{answer}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
<div class="puzzle-group" data-level={level}>
|
||||
<strong>{group}</strong>
|
||||
<div>{members.join(', ')}</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
<For each={[0, 1, 2, 3].slice(0, puzzle().length / 4)}>
|
||||
{(row) => (
|
||||
<div class="puzzle-row">
|
||||
{[0, 1, 2, 3].map((col) => {
|
||||
const index = 4 * row + col;
|
||||
return (
|
||||
<button
|
||||
classList={{
|
||||
"puzzle-item": true,
|
||||
"is-selected": selected().includes(index),
|
||||
}}
|
||||
type="button"
|
||||
on:click={() => {
|
||||
setSelected(
|
||||
selected().includes(index)
|
||||
? selected().filter((x) => x !== index)
|
||||
: [...selected(), index]
|
||||
);
|
||||
}}
|
||||
>
|
||||
{getFromPuzzle(index).answer}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
<div class="puzzle-actions">
|
||||
<button type="button" disabled={selected().length === 0}>
|
||||
Pin
|
||||
</button>
|
||||
<button
|
||||
id="submitButton"
|
||||
type="button"
|
||||
on:click={handleGuess}
|
||||
disabled={selected().length !== 4}
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue