diff --git a/.gitignore b/.gitignore index d9d2984..a547bf3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,24 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - +# Logs +logs +*.log npm-debug.log* yarn-debug.log* yarn-error.log* +pnpm-debug.log* +lerna-debug.log* -*/.idea -.idea \ No newline at end of file +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..bdef820 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 97ce882..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "files.autoSave": "onFocusChange", - "editor.defaultFormatter": "dbaeumer.vscode-eslint", - "editor.formatOnPaste": true, - "eslint.validate": [ - "javascript", - "javascriptreact", - "typescript", - "typescriptreact" - ], - "eslint.format.enable": true, - "[javascript]": { - "editor.defaultFormatter": "dbaeumer.vscode-eslint", - }, - "[javascriptreact]": { - "editor.defaultFormatter": "dbaeumer.vscode-eslint", - }, -} \ No newline at end of file diff --git a/README.md b/README.md index ae2e6a4..e6cd94f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,47 @@ -This is a react app for slither link game with a few predefined puzzles. -This is focussed mainly on the UI hence code to check for solution is a simple match check and not based on an algorithm. -This app is hosted via [github pages](https://pages.github.com/). Visit the app [here](https://ameygohil.github.io/slither-link/). -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/bun.lockb b/bun.lockb index abf2dfb..d2053e0 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/index.html b/index.html index 7f99963..b6c5f0a 100644 --- a/index.html +++ b/index.html @@ -1,35 +1,13 @@ - + - - - - - - - - - - - SlitherLink + + + + Vite + Svelte + TS -
- + diff --git a/package.json b/package.json index 2a903a2..844e067 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,21 @@ { - "name": "slither-link", + "name": "slither-link-v2", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", - "preview": "vite preview" - }, - "dependencies": { - "preact": "^10.25.0" + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json" }, "devDependencies": { - "@preact/preset-vite": "^2.9.1", + "@sveltejs/vite-plugin-svelte": "^5.0.0", + "@tsconfig/svelte": "^5.0.4", "sass-embedded": "^1.83.0", + "svelte": "^5.2.7", + "svelte-check": "^4.1.0", + "tslib": "^2.8.1", "typescript": "~5.6.2", "vite": "^6.0.1" } diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 643ac30..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/logo.svg b/public/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/public/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index c175075..0000000 Binary files a/public/logo192.png and /dev/null differ diff --git a/public/logo512.png b/public/logo512.png deleted file mode 100644 index 3132b31..0000000 Binary files a/public/logo512.png and /dev/null differ diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index b063c6e..0000000 --- a/public/manifest.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "short_name": "SlitherLink", - "name": "SlitherLink React App", - "icons": [ - { - "src": "favicon.ico", - "sizes": "64x64 32x32 24x24 16x16", - "type": "image/x-icon" - }, - { - "src": "logo192.png", - "type": "image/png", - "sizes": "192x192" - }, - { - "src": "logo512.png", - "type": "image/png", - "sizes": "512x512" - } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" -} diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index e9e57dc..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Disallow: diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/App.css b/src/App.css deleted file mode 100644 index e16d143..0000000 --- a/src/App.css +++ /dev/null @@ -1,5 +0,0 @@ -body, html, #app { - height: 100%; - width: 100%; - box-sizing: border-box; -} diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index a5b35c1..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import Game from "./components/Game"; -import "./App.css"; - -const App = () => { - return ; -}; - -export default App; diff --git a/src/app.scss b/src/app.scss new file mode 100644 index 0000000..8272bca --- /dev/null +++ b/src/app.scss @@ -0,0 +1,69 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +#app { + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/src/assets/svelte.svg b/src/assets/svelte.svg new file mode 100644 index 0000000..c5e0848 --- /dev/null +++ b/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/AddPuzzleScreen/index.js b/src/components/AddPuzzleScreen/index.js deleted file mode 100644 index 4dd5eb1..0000000 --- a/src/components/AddPuzzleScreen/index.js +++ /dev/null @@ -1,119 +0,0 @@ -import * as React from "react"; -import {getMatrix, getNumbers, multiStyles} from "../../utils"; -import Controls from "../Controls"; -import Grid from "../Grid"; -import N from "../Grid/components/N"; - -import styles from "./styles.module.scss"; - -const AddPuzzleScreen = ({open, onClose}) => { - const [dim, setDim] = React.useState([3, 3]); - const [gridMat, setGridMat] = React.useState([]); - const [gridNumbers, setGridNumbers] = React.useState([]); - - React.useEffect(() => { - if (!isNaN(dim[0]) && dim[0] > 0 && !isNaN(dim[1]) && dim[1] > 0) { - setGridMat(getMatrix(dim, [], gridNumbers)); - } - }, [dim[0], dim[1]]); - - React.useEffect(() => { - setGridNumbers(getNumbers(gridMat)); - }, [JSON.stringify(gridMat)]); - - const [gridReset, setGridReset] = React.useState(false); - React.useEffect(() => { - if (gridReset) { - if (!isNaN(dim[0]) && dim[0] > 0 && !isNaN(dim[1]) && dim[1] > 0) { - setGridNumbers([]); - setGridMat(getMatrix(dim)); - } - setGridReset(false); - } - }, [gridReset]); - const [submitState, setSubmitState] = React.useState("none"); - const [submitText, setSubmitText] = React.useState("Submit"); - const onSubmit = () => { - setSubmitState("passed"); - setSubmitText("Thanks for submitting! 😀"); - }; - React.useEffect(() => { - let timeout; - if (submitState === "passed") { - timeout = setTimeout(() => { - setSubmitState("none"); - setSubmitText("Submit"); - }, 5000); - } - - return () => !isNaN(timeout) && clearTimeout(timeout); - }, [submitState]); - - const shouldShowGrid = - !isNaN(dim[0]) && dim[0] > 0 && !isNaN(dim[1]) && dim[1] > 0; - - return ( - <> - {open && ( -
- - -
-
Set dimensions
-
-
- { - setGridReset(true); - setDim([n, dim[1]]); - }} - editorMode - className={styles.input} - /> - X - { - setGridReset(true); - setDim([dim[0], n]); - }} - editorMode - className={styles.input} - /> -
-
-
-
-
Set matrix
-
-
- {shouldShowGrid ? ( - - ) : ( - "Please set valid dimensions above" - )} -
-
-
- {shouldShowGrid && ( - - {submitText} - - )} -
-
- setGridReset(true)} editorMode /> -
- )} - - ); -}; - -export default AddPuzzleScreen; diff --git a/src/components/AddPuzzleScreen/styles.module.scss b/src/components/AddPuzzleScreen/styles.module.scss deleted file mode 100644 index d04b397..0000000 --- a/src/components/AddPuzzleScreen/styles.module.scss +++ /dev/null @@ -1,159 +0,0 @@ -* { - box-sizing: border-box; -} - -.screen { - position: fixed; - height: 100vh; - width: 100vw; - background-color: #212121; - z-index: 3; - font-family: monospace; - display: flex; - padding: 50px 40px; - align-items: flex-start; - justify-content: flex-start; - overflow-y: auto; - flex-direction: column; - gap: 50px; - - .cross { - $size: 20px; - height: $size; - width: $size; - position: fixed; - top: 40px; - right: 40px; - background-color: inherit; - padding: 3 * $size / 4; - z-index: 3; - cursor: pointer; - - &:after, &:before { - content: ""; - height: $size / 8; - width: $size; - background-color: #b0bec5; - position: absolute; - top: 50%; - left: 50%; - border-radius: $size / 8; - } - - &:after { - transform: translate(-50%, -50%) rotate(45deg); - } - - &:before { - transform: translate(-50%, -50%) rotate(-45deg); - } - } - - section { - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: flex-start; - gap: 20px; - font-size: 17px; - color: #e0e0e0; - width: 100%; - - & > span { - padding-left: 20px; - } - - a { - color: #00b0ff; - text-decoration: none; - } - } - - .title { - display: flex; - align-items: center; - justify-content: center; - width: 100%; - margin-bottom: 10px; - font-size: 26px; - text-transform: uppercase; - font-weight: 600; - color: #f5f5f5; - } - - .content { - line-height: inherit; - font-size: inherit; - padding-left: 20px; - color: inherit; - position: relative; - display: flex; - flex-direction: column; - gap: 20px; - width: 100%; - - .matrixGrid { - display: flex; - align-self: center; - justify-self: center; - gap: 20px; - align-items: center; - justify-content: center; - width: 100%; - } - - .submitButton { - display: flex; - align-items: center; - justify-content: center; - background-color: #263238; - height: auto; - width: auto; - padding: 10px 15px; - font-size: 20px; - border: 2px solid #455a64; - margin-top: 20px; - color: #fafafa; - - align-self: center; - justify-self: center; - border-radius: 10px; - cursor: pointer; - transition: all 0.2s; - - &:hover { - border-color: #78909c; - transform: scale(1.01); - color: white; - } - - &.failed { - color: #ff5722; - border-color: #ff5722; - } - - &.passed { - color: #00e676; - border-color: #00e676; - } - } - } - - .dimInputWrapper { - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - - .input { - background-color: #282c34; - border-radius: 6px; - display: inline; - - input { - border-radius: 6px; - font-family: monospace; - } - } - } -} diff --git a/src/components/CheckSolution/index.js b/src/components/CheckSolution/index.js deleted file mode 100644 index 70baedf..0000000 --- a/src/components/CheckSolution/index.js +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from "react"; -import {getActiveEdges, multiStyles} from "../../utils"; - -import styles from "./styles.module.scss"; - -const CheckSolution = ({matrix, solution, setCheck}) => { - const [text, setText] = React.useState("Check Solution"); - const [state, setState] = React.useState("none"); - - React.useEffect(() => { - let timeout; - if (state !== "none") { - timeout = setTimeout(() => { - setState("none"); - setCheck("none"); - setText("Check Solution"); - }, 4000); - } - - return () => !isNaN(timeout) && clearTimeout(timeout); - }, [state]); - return ( -
{ - let check = - JSON.stringify(getActiveEdges(matrix)) === JSON.stringify(solution); - if (check) { - setText("That is correct! 😀"); - setState("passed"); - setCheck("passed"); - } else { - setText("Wrong Solution 😔"); - setState("failed"); - setCheck("failed"); - } - }} - > - {text} -
- ); -}; - -export default CheckSolution; diff --git a/src/components/CheckSolution/styles.module.scss b/src/components/CheckSolution/styles.module.scss deleted file mode 100644 index c2a9cb5..0000000 --- a/src/components/CheckSolution/styles.module.scss +++ /dev/null @@ -1,38 +0,0 @@ -* { - box-sizing: border-box; -} - -.button { - display: flex; - align-items: center; - justify-content: center; - background-color: #263238; - height: 50px; - width: auto; - padding: 10px 15px; - font-size: 20px; - border: 2px solid #455a64; - margin-top: 20px; - color: #fafafa; - - border-radius: 10px; - cursor: pointer; - transition: all 0.2s; - - - &:hover { - border-color: #78909c; - transform: scale(1.01); - color: white; - } - - &.failed { - color: #ff5722; - border-color: #ff5722; - } - - &.passed { - color: #00e676; - border-color: #00e676; - } -} diff --git a/src/components/Controls/index.js b/src/components/Controls/index.js deleted file mode 100644 index 48ce966..0000000 --- a/src/components/Controls/index.js +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from "react"; -import AddPuzzleScreen from "../AddPuzzleScreen"; -import {Plus, Redo, Refresh, Reset, Undo} from "../Icons"; - -import styles from "./styles.module.scss"; - -const Controls = ({onRefresh, onReset, onUndo, onRedo, editorMode}) => { - const [showAddScreen, setShowAddScreen] = React.useState(false); - - return ( - <> -
- {!editorMode && ( -
- - Refresh -
- )} -
- - Reset -
- {!editorMode && ( -
- - Undo -
- )} - {!editorMode && ( -
- - Redo -
- )} - {!editorMode && ( -
setShowAddScreen(true)}> - - Add -
- )} -
- setShowAddScreen(false)} - /> - - ); -}; - -export default Controls; diff --git a/src/components/Controls/styles.module.scss b/src/components/Controls/styles.module.scss deleted file mode 100644 index fb13aea..0000000 --- a/src/components/Controls/styles.module.scss +++ /dev/null @@ -1,47 +0,0 @@ -* { - box-sizing: border-box; -} - -.controls { - position: fixed; - bottom: 10px; - left: 10px; - display: flex; - align-items: center; - justify-content: center; - gap: 10px; - - & > div { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 12px; - color: #90a4ae; - gap: 2px; - cursor: pointer; - - & > svg { - background-color: #263238; - height: 40px; - width: 40px; - padding: 9px; - border: 2px solid #455a64; - font-family: Georgia, 'Times New Roman', Times, serif; - color: #fafafa; - border-radius: 50%; - transition: all 0.2s; - font-style: italic; - } - - &:hover { - transform: scale(1.1); - - & > svg { - border-color: #78909c; - font-size: 22px; - color: white; - } - } - } -} diff --git a/src/components/Game/index.js b/src/components/Game/index.js deleted file mode 100644 index 39fb871..0000000 --- a/src/components/Game/index.js +++ /dev/null @@ -1,91 +0,0 @@ -import * as React from "react"; -import {examples} from "../../examples"; -import {copy, getEdges, getMatrix} from "../../utils"; -import CheckSolution from "../CheckSolution"; -import Controls from "../Controls"; -import Grid from "../Grid"; -import Info from "../Info"; - -import styles from "./styles.module.scss"; - -const Game = () => { - const [matrix, setMatrix] = React.useState([]); - const [{dim = [], numbers, solution}] = React.useState( - examples[Math.floor(Math.random() * examples.length)] - ); - - const [history, setHistory] = React.useState([]); - const [historyIndex, setHistoryIndex] = React.useState(-1); - - const [check, setCheck] = React.useState("none"); - - const updateMatrix = (matrix) => { - setHistory([...history.slice(0, historyIndex + 1), copy(matrix)]); - setHistoryIndex(historyIndex + 1); - setMatrix(matrix); - }; - - // initializing matrix with example - React.useEffect(() => { - if (dim.length) { - let temp = getMatrix(dim, [], numbers); - updateMatrix(temp); - } - }, [dim.length]); - - const onUndo = () => { - // check if undo is possible - if (historyIndex < 1) { - return; - } - - // performing undo - setMatrix(copy(history[historyIndex - 1])); - setHistoryIndex(historyIndex - 1); - }; - - const onRedo = () => { - // check if redo is possible - if (historyIndex + 1 === history.length) { - return; - } - - // performing undo - setMatrix(copy(history[historyIndex + 1])); - setHistoryIndex(historyIndex + 1); - }; - - const onReset = () => { - if (dim.length) { - // if matrix already empty - if (getEdges(matrix).length === 0) { - return; - } - updateMatrix(getMatrix(dim, [], numbers)); - } - }; - - const onRefresh = () => { - window.location.reload(); - }; - - return ( -
-

- Slither - Link -

- - - - -
- ); -}; - -export default Game; diff --git a/src/components/Game/styles.module.scss b/src/components/Game/styles.module.scss deleted file mode 100644 index 802b7e5..0000000 --- a/src/components/Game/styles.module.scss +++ /dev/null @@ -1,32 +0,0 @@ -main { - font-size: 24px; - font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; - background-color: #23262f; - height: 100%; - width: 100%; - color: #fafafa; - display: flex; - align-items: center; - justify-content: center; - gap: 20px; - flex-direction: column; - box-sizing: border-box; - padding: 0 22px; -} - -.heading { - font-size: 25px; - text-align: center; - - span { - color: #7986cb; - - &:nth-of-type(even) { - color: #8c9eff; - } - - &:nth-of-type(odd) { - color: #64b5f6; - } - } -} diff --git a/src/components/Grid/components/Cross.js b/src/components/Grid/components/Cross.js deleted file mode 100644 index 96a7519..0000000 --- a/src/components/Grid/components/Cross.js +++ /dev/null @@ -1,36 +0,0 @@ -import {multiStyles} from "../../../utils"; -import styles from "../styles.module.scss"; - -const Cross = ({ - orientation = "h", - className, - onRightClick, - onMiddleClick, - ...props -}) => { - return ( -
{ - e.preventDefault(); - onRightClick(); - }} - onMouseDown={(e) => { - if (e.button === 1) { - onMiddleClick(); - } - }} - > - - -
- ); -}; - -export default Cross; diff --git a/src/components/Grid/components/Edge.js b/src/components/Grid/components/Edge.js deleted file mode 100644 index 1c34679..0000000 --- a/src/components/Grid/components/Edge.js +++ /dev/null @@ -1,8 +0,0 @@ -import Cross from "./Cross"; -import Line from "./Line"; - -const Edge = ({notAllowed, ...props}) => { - return notAllowed ? : ; -}; - -export default Edge; diff --git a/src/components/Grid/components/Line.js b/src/components/Grid/components/Line.js deleted file mode 100644 index 21f2308..0000000 --- a/src/components/Grid/components/Line.js +++ /dev/null @@ -1,35 +0,0 @@ -import {multiStyles} from "../../../utils"; -import styles from "../styles.module.scss"; - -const Line = ({ - orientation = "h", - hovered, - active, - className, - onRightClick, - onMiddleClick, - ...props -}) => { - return ( -
{ - e.preventDefault(); - onRightClick(); - }} - onMouseDown={(e) => { - if (e.button === 1) { - onMiddleClick(); - } - }} - /> - ); -}; - -export default Line; diff --git a/src/components/Grid/components/LineRow.js b/src/components/Grid/components/LineRow.js deleted file mode 100644 index 77ecbd5..0000000 --- a/src/components/Grid/components/LineRow.js +++ /dev/null @@ -1,57 +0,0 @@ -import {EDGE_STATE} from "../../../constants"; -import {findNeighbor, isNodeActive} from "../../../utils"; -import Edge from "./Edge"; -import Node from "./Node"; -import Row from "./Row"; - -const LineRow = ({ - matX, - mat = [], - n = 1, - onLineClick, - onLineRightClick, - onLineMiddleClick, -}) => { - return ( - - {mat.length && - Array(n - 1) - .fill(0) - .map((_, i) => { - const edgeIdx = findNeighbor([matX, i], [matX, i + 1], mat); - const showEdge = edgeIdx !== -1; - return [ - , - onLineClick(matX, i, "horizontal")} - onRightClick={() => onLineRightClick(matX, i, "horizontal")} - onMiddleClick={() => onLineMiddleClick(matX, i, "horizontal")} - hovered={ - showEdge && - mat[matX][i].neigh[edgeIdx].state === EDGE_STATE.HOVERED - ? 1 - : 0 - } - key={`edge_${matX + i}`} - />, - ]; - }) - .concat([ - , - ])} - - ); -}; - -export default LineRow; diff --git a/src/components/Grid/components/N.js b/src/components/Grid/components/N.js deleted file mode 100644 index 1cef61f..0000000 --- a/src/components/Grid/components/N.js +++ /dev/null @@ -1,16 +0,0 @@ -import {multiStyles} from "../../../utils"; -import styles from "../styles.module.scss"; - -const N = ({className, value, setNum, editorMode, ...props}) => { - const v = value >= 0 && !isNaN(value) ? value : "" - - return ( - {editorMode && setNum(parseInt(e.target.value))} - value={v} - /> || v} - ) -} - -export default N diff --git a/src/components/Grid/components/Node.js b/src/components/Grid/components/Node.js deleted file mode 100644 index 9f05c3e..0000000 --- a/src/components/Grid/components/Node.js +++ /dev/null @@ -1,13 +0,0 @@ -import {multiStyles} from "../../../utils"; -import styles from "../styles.module.scss"; - -const Node = ({className, active, ...props}) => { - return ( -
- ); -}; - -export default Node; diff --git a/src/components/Grid/components/NumberRow.js b/src/components/Grid/components/NumberRow.js deleted file mode 100644 index caeab61..0000000 --- a/src/components/Grid/components/NumberRow.js +++ /dev/null @@ -1,80 +0,0 @@ -import {EDGE_STATE} from "../../../constants"; -import {findNeighbor} from "../../../utils"; -import Edge from "./Edge"; -import N from "./N"; -import Row from "./Row"; - -const NumberRow = ({ - matX, - mat = [], - n = 1, - onLineClick, - onLineRightClick, - onLineMiddleClick, - onNumberChange, - editorMode, -}) => { - const endEdgeIdx = - mat.length && findNeighbor([matX, n - 1], [matX + 1, n - 1], mat); - const showEndEdge = endEdgeIdx !== -1; - return ( - - {mat.length && - Array(n - 1) - .fill(0) - .map((_, i) => { - const edgeIdx = findNeighbor([matX, i], [matX + 1, i], mat); - const showEdge = edgeIdx !== -1; - return [ - onLineClick(matX, i, "vertical")} - onRightClick={() => onLineRightClick(matX, i, "vertical")} - onMiddleClick={() => onLineMiddleClick(matX, i, "vertical")} - hovered={ - showEdge && - mat[matX][i].neigh[edgeIdx].state === EDGE_STATE.HOVERED - ? 1 - : 0 - } - key={`edge_${matX + i}`} - />, - onNumberChange(matX, i, n)} - editorMode={editorMode} - key={`number_${matX + i}`} - />, - ]; - }) - .concat([ - onLineClick(matX, n - 1, "vertical")} - onRightClick={() => onLineRightClick(matX, n - 1, "vertical")} - onMiddleClick={() => onLineMiddleClick(matX, n - 1, "vertical")} - hovered={ - showEndEdge && - mat[matX][n - 1].neigh[endEdgeIdx].state === EDGE_STATE.HOVERED - ? 1 - : 0 - } - key={`edge_${matX + n - 1}`} - />, - ])} - - ); -}; - -export default NumberRow; diff --git a/src/components/Grid/components/Row.js b/src/components/Grid/components/Row.js deleted file mode 100644 index 505a238..0000000 --- a/src/components/Grid/components/Row.js +++ /dev/null @@ -1,5 +0,0 @@ -import styles from "../styles.module.scss"; - -const Row = ({children}) =>
{children}
; - -export default Row; diff --git a/src/components/Grid/index.js b/src/components/Grid/index.js deleted file mode 100644 index 17b7584..0000000 --- a/src/components/Grid/index.js +++ /dev/null @@ -1,175 +0,0 @@ -import {EDGE_STATE} from "../../constants"; -import {findNeighbor, getNeighbors, multiStyles} from "../../utils"; -import LineRow from "./components/LineRow"; -import NumberRow from "./components/NumberRow"; -import styles from "./styles.module.scss"; - -/* - Grid traversal - (0, 0) -- (0, 1) -- (0, 2) --> - | | | - | | | - (1, 0) -- (1, 1) -- (1, 2) --> - | | | - | | | - (2, 0) -- (2, 1) -- (2, 2) --> - | | | - | | | - V V V -*/ - -export const DEFAULT_NODE = {neigh: [], n: -1}; -/* - structure for neigh elements: - {state: , loc: [x, y]} -*/ - -const Grid = ({matrix, setMatrix, readOnly, editorMode, state, className}) => { - const nHorLine = matrix?.length || 0; - const nVerLine = matrix?.[0]?.length || 0; - - if (nHorLine === 0 || nVerLine === 0) { - return null; - } - - const updateMatrix = (dataArray) => { - let temp = matrix.slice(); - dataArray.forEach(({node: [x, y], data}) => { - temp[x][y] = {...temp[x][y], ...data}; - }); - setMatrix(temp); - }; - - const onLineClick = (x, y, direction, click) => { - if (readOnly) { - return; - } - - const isMiddleClick = click === "middle"; - const node = [x, y]; - const otherNode = direction === "horizontal" ? [x, y + 1] : [x + 1, y]; - let nodeUpdateData = {}; - let otherNodeUpdateData = {}; - const neighborIndex = findNeighbor(node, otherNode, matrix); - const otherNeighborIndex = findNeighbor(otherNode, node, matrix); - - // if there was already an edge (ACTIVE | NOT_ALLOWED) - if (neighborIndex !== -1) { - // if the edge was NOT_ALLOWED - const isNewEdgeStateEmpty = - matrix[x][y].neigh[neighborIndex].state === EDGE_STATE.NOT_ALLOWED; - let newNeighbors = getNeighbors(node, matrix).slice(); - newNeighbors.splice(neighborIndex, 1); - nodeUpdateData = { - neigh: [ - ...newNeighbors, - ...(isNewEdgeStateEmpty || isMiddleClick - ? [] - : [{state: EDGE_STATE.NOT_ALLOWED, loc: otherNode}]), - ], - }; - let newOtherNeighbors = getNeighbors(otherNode, matrix).slice(); - newOtherNeighbors.splice(otherNeighborIndex, 1); - otherNodeUpdateData = { - neigh: [ - ...newOtherNeighbors, - ...(isNewEdgeStateEmpty || isMiddleClick - ? [] - : [{state: EDGE_STATE.NOT_ALLOWED, loc: node}]), - ], - }; - } else if (!isMiddleClick) { - nodeUpdateData = { - neigh: [ - ...matrix[x][y].neigh, - { - state: - click === "left" ? EDGE_STATE.ACTIVE : EDGE_STATE.NOT_ALLOWED, - loc: otherNode, - }, - ], - }; - otherNodeUpdateData = { - neigh: [ - ...matrix[otherNode[0]][otherNode[1]].neigh, - { - state: - click === "left" ? EDGE_STATE.ACTIVE : EDGE_STATE.NOT_ALLOWED, - loc: node, - }, - ], - }; - } - updateMatrix([ - {node, data: nodeUpdateData}, - {node: otherNode, data: otherNodeUpdateData}, - ]); - }; - - const onLineLeftClick = (x, y, direction) => - onLineClick(x, y, direction, "left"); - const onLineRightClick = (x, y, direction) => - onLineClick(x, y, direction, "right"); - const onLineMiddleClick = (x, y, direction) => - onLineClick(x, y, direction, "middle"); - - const onNumberChange = (x, y, num) => { - if (!editorMode || readOnly) { - return; - } - updateMatrix([{node: [x, y], data: {n: num}}]); - }; - - return ( -
e.preventDefault()} - > - {Array(nHorLine - 1) - .fill(0) - .map((_, i) => { - return [ - , - , - ]; - }) - .concat([ - , - ])} -
- ); -}; - -export default Grid; diff --git a/src/components/Grid/styles.module.scss b/src/components/Grid/styles.module.scss deleted file mode 100644 index ab31362..0000000 --- a/src/components/Grid/styles.module.scss +++ /dev/null @@ -1,298 +0,0 @@ -$gridColor: #607d8b; -$gridActiveColor: #90a4ae; -$gridHoverColor: #eceff1; -$invalidColor: #ff8a80; -$validColor: #00e676; - -$transitionDuration: 0.2s; - -$gridScale: 1; - -$nodeSize: $gridScale * 6px; -@media (max-width: 500px) { - $gridScale: 0.5; -} -$nodeActiveSize: $gridScale * 7px; - -$edgeLength: $gridScale * 50px; -$edgeBreadth: $gridScale * 2px; - -$fontSize: $gridScale * 24px; - -$animationSeperation: 0.075s; -$animationScale: 1.5; -$animationDuration: 0.25s; -$animationTimingFunction: linear; -$animationFillMode: forwards; - -// canvas -.row, .canvas { - display: flex; - justify-content: center; - align-items: center; -} - -.canvas { - align-items: flex-start; - flex-direction: column; - overflow-x: auto; - box-sizing: border-box; - max-width: 100%; - padding: 50px; - border-radius: 10px; - background-color: #282c34; - - &.readOnly, &.passed { - * { - pointer-events: none; - cursor: default; - } - } -} - -// grid elements -.node { - display: flex; - height: $nodeSize; - width: $nodeSize; - background-color: $gridColor; - border-radius: 50%; - z-index: 1; - transition: background-color $transitionDuration; - - &.active { - background-color: $gridActiveColor; - width: $nodeActiveSize; - height: $nodeActiveSize; - margin: - ($nodeActiveSize - $nodeSize) / 2; - } -} - -.line { - display: flex; - $lineColor: $gridColor; - background-repeat: repeat; - opacity: 0; - position: relative; - cursor: pointer; - $interactionOffset: ($nodeSize - $edgeBreadth) * 4; - - &:after, &:before { - content: ""; - background-color: transparent; - position: absolute; - } - - &.horizontal { - background-size: 4*$edgeBreadth 100%; - background-image: linear-gradient(90deg, $lineColor 50%, transparent 50%); - height: $edgeBreadth; - width: $edgeLength; - - &:after, &:before { - height: $interactionOffset; - width: 100%; - left: 0; - } - - &:after { - top: 100%; - } - - &:before { - bottom: 100%; - } - } - - &.vertical { - background-size: 100% 4*$edgeBreadth; - background-image: linear-gradient(180deg, $lineColor 50%, transparent 50%); - height: $edgeLength; - width: $edgeBreadth; - margin: 0 ($nodeSize - $edgeBreadth) / 2; - - &:after, &:before { - width: $interactionOffset; - height: 100%; - top: 0; - } - - &:after { - right: 100%; - } - - &:before { - left: 100%; - } - } - - &:hover, &.hovered { - transition: opacity $transitionDuration; - opacity: 1; - } - - &.active { - opacity: 1; - background: $gridActiveColor; - transition: background-color $transitionDuration; - - &:hover { - background: $gridHoverColor; - - &.horizontal { - height: 1.5 * $edgeBreadth; - } - - &.vertical { - width: 1.5 * $edgeBreadth; - margin: 0 (($nodeSize - 1.5 * $edgeBreadth) / 2); - } - } - } - - &.cross { - opacity: 1; - background: none; - display: flex; - align-items: center; - justify-content: center; - - & > span { - position: absolute; - width: 6 * $edgeBreadth; - height: 3 * $edgeBreadth / 4; - background-color: $invalidColor; - border-radius: 2 * $edgeBreadth; - transition: all $transitionDuration; - - &:first-child { - transform: rotate(45deg); - } - - &:last-child { - transform: rotate(-45deg); - } - } - - &:hover { - & > span { - width: 7 * $edgeBreadth; - height: $edgeBreadth; - background-color: $gridHoverColor; - } - } - } -} - -.number { - font-size: $fontSize; - display: flex; - align-items: center; - justify-content: center; - height: $edgeLength; - width: $edgeLength; - user-select: none; - - .invalid { - color: $invalidColor; - } - - input { - text-align: center; - height: inherit; - width: inherit; - background: inherit; - outline: none; - box-shadow: none; - border: inherit; - color: inherit; - font-size: inherit; - display: inherit; - align-items: inherit; - justify-content: inherit; - cursor: inherit; - } -} - -.canvas.failed { - .node.active { - background-color: $invalidColor; - } - - .line { - &:not(.cross){ - &:not(:hover) { - background-color: $invalidColor; - } - } - } -} - -.canvas.passed { - - .node.active { - animation: node $animationDuration $animationTimingFunction $animationFillMode; - } - - .line:not(.cross) { - &.horizontal { - animation: lineX $animationDuration $animationTimingFunction $animationFillMode; - } - - &.vertical { - animation: lineY $animationDuration $animationTimingFunction $animationFillMode; - } - } - - .node.active, .line:not(.cross) { - @for $i from 1 through 50 { - &:nth-child(#{$i}) { - animation-delay: ($i - 1) * $animationSeperation; - } - } - } - -} - -@keyframes node { - 0% { - background-color: $validColor; - transform: scale(1); - } - 50% { - transform: scale($animationScale); - } - 100% { - background-color: $validColor; - transform: scale(1); - } -} - -@keyframes lineX { - 0% { - background-color: $validColor; - transform: scaleY(1); - } - 50% { - transform: scaleY(1.5 * $animationScale); - } - 100% { - background-color: $validColor; - transform: scaleY(1); - } -} - - -@keyframes lineY { - 0% { - background-color: $validColor; - transform: scaleX(1); - } - 50% { - transform: scaleX(1.5 * $animationScale); - } - 100% { - background-color: $validColor; - transform: scaleX(1); - } -} diff --git a/src/components/Icons.js b/src/components/Icons.js deleted file mode 100644 index db28bdc..0000000 --- a/src/components/Icons.js +++ /dev/null @@ -1,87 +0,0 @@ -export const Undo = ({className, onClick}) => { - return ( - - - - ); -}; - -export const Redo = ({className, onClick}) => { - return ( - - - - - ); -}; - -export const Refresh = ({className, onClick}) => { - return ( - - - - - ); -}; - -export const Reset = ({className, onClick}) => { - return ( - - - - - ); -}; - -export const Plus = ({className, onClick}) => { - return ( - - - - - ); -}; diff --git a/src/components/Info/index.js b/src/components/Info/index.js deleted file mode 100644 index 9e622ca..0000000 --- a/src/components/Info/index.js +++ /dev/null @@ -1,146 +0,0 @@ -import * as React from "react"; -import {EXAMPLE_GRID_PROPS, NOT_ALLOWED_1_GRID_PROPS, NOT_ALLOWED_2_GRID_PROPS,} from "../../constants"; -import {getMatrix} from "../../utils"; -import Grid from "../Grid"; - -import styles from "./styles.module.scss"; - -const Info = () => { - const [open, setOpen] = React.useState(false); - - return ( - <> -
setOpen(true)}> -
i
- Info -
- {open && ( -
- setOpen(false)} /> - -
-
Rules
-
- Connect adjacent dots with vertical or horizontal lines, creating - a single loop. -
- -
-
-
- Crossovers or branches are not allowed (as shown by dotted lines - below). -
- - -
-
-
- Numbers in the puzzle indicate the number of lines that should - surround it. -
-
- You can't draw lines around zeroes. -
-
- Each puzzle has just one uniques solution. -
-
-
-
How to begin
-
- Begin with the zero next to 3. If no such case is present, then - use one of the rules in the{" "} - - wikipedia link - {" "} - to start off. -
-
- Since no lines can be drawn around zero, mark crosses around it as - shown. -
-
- Now there's a cross in one space around 3. So we know the three - lines of 3 can only be drawn in the remaining three spaces. -
-
- Next, these lines can only be extended in one direction each. -
-
Continue using the same logic.
-
-
-
Hints
- - Keep eliminating possibilities by marking crosses in spaces - between dots where a line isn't possible, i.e., if you have - already completed required lines or where a line creation may - create a branch or a deadend. Visit the{" "} - - wikipedia link - {" "} - for more hints. - -
-
-
Controls
- - - - - - - - - - - - - - - -
- Left Mouse Button - Toggle line
- Right Mouse Button - Mark line as crossed/not allowed
- Middle Mouse Button - Reset line state
-
-
- )} - - ); -}; - -export default Info; diff --git a/src/components/Info/styles.module.scss b/src/components/Info/styles.module.scss deleted file mode 100644 index 4a2a94d..0000000 --- a/src/components/Info/styles.module.scss +++ /dev/null @@ -1,186 +0,0 @@ -* { - box-sizing: border-box; -} - -.container { - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; - position: fixed; - bottom: 10px; - right: 10px; - gap: 2px; - cursor: pointer; - - .button { - display: flex; - align-items: center; - justify-content: center; - background-color: #263238; - height: 40px; - width: 40px; - padding: 10px; - font-size: 20px; - border: 2px solid #455a64; - font-family: Georgia, 'Times New Roman', Times, serif; - border-radius: 50%; - transition: all 0.2s; - font-style: italic; - } - - span { - font-size: 12px; - color: #90a4ae; - } - - &:hover { - transform: scale(1.1); - - .button { - border-color: #78909c; - font-size: 22px; - color: white; - } - } -} - -.info { - position: fixed; - height: 100vh; - width: 100vw; - background-color: #212121; - z-index: 2; - font-family: monospace; - display: flex; - padding: 50px 40px; - align-items: flex-start; - justify-content: flex-start; - overflow-y: auto; - flex-direction: column; - gap: 50px; - - .cross { - $size: 20px; - height: $size; - width: $size; - position: fixed; - top: 40px; - right: 40px; - background-color: inherit; - padding: 3 * $size / 4; - z-index: 3; - cursor: pointer; - - &:after, &:before { - content: ""; - height: $size / 8; - width: $size; - background-color: #b0bec5; - position: absolute; - top: 50%; - left: 50%; - border-radius: $size / 8; - } - - &:after { - transform: translate(-50%, -50%) rotate(45deg); - } - - &:before { - transform: translate(-50%, -50%) rotate(-45deg); - } - } - - section { - display: flex; - flex-direction: column; - align-items: flex-start; - justify-content: flex-start; - gap: 20px; - font-size: 17px; - color: #e0e0e0; - width: 100%; - - & > span { - padding-left: 20px; - } - - a { - color: #00b0ff; - text-decoration: none; - } - } - - .title { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - margin-bottom: 10px; - font-size: 26px; - text-transform: uppercase; - font-weight: 600; - color: #f5f5f5; - } - - .item { - line-height: inherit; - font-size: inherit; - padding-left: 20px; - color: inherit; - position: relative; - display: flex; - flex-direction: column; - gap: 20px; - width: 100%; - - &:before { - content: ""; - position: absolute; - width: 7px; - height: 7px; - top: 7px; - left: 0; - box-sizing: border-box; - border-radius: 50%; - background-color: #424242; - border: 1.5px solid #9e9e9e; - } - - .eg { - display: flex; - flex-wrap: wrap; - align-self: center; - justify-self: center; - gap: 20px; - align-items: center; - justify-content: center; - width: 100%; - } - } - - table { - width: 100%; - padding-left: 20px; - - tr { - width: 100%; - - td { - width: 50%; - padding-bottom: 10px; - - &:last-child { - padding-left: 10px; - } - } - - &:last-child { - td { - padding-bottom: 0; - } - } - } - } -} diff --git a/src/constants.js b/src/constants.js deleted file mode 100644 index cb74265..0000000 --- a/src/constants.js +++ /dev/null @@ -1,159 +0,0 @@ -export const EDGE_STATE = { - ACTIVE: "ACTIVE", - NOT_ALLOWED: "NOT_ALLOWED", - HOVERED: "HOOVERED", -}; - -export const EXAMPLE_GRID_PROPS = { - dim: [7, 7], - edges: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [0, 2], notAllowed: true}, - {a: [0, 1], b: [1, 1]}, - {a: [0, 2], b: [0, 3], notAllowed: true}, - {a: [0, 2], b: [1, 2], notAllowed: true}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 3], b: [1, 3]}, - {a: [0, 4], b: [0, 5]}, - {a: [0, 4], b: [1, 4], notAllowed: true}, - {a: [0, 5], b: [0, 6]}, - {a: [0, 5], b: [1, 5], notAllowed: true}, - {a: [0, 6], b: [0, 7]}, - {a: [0, 6], b: [1, 6], notAllowed: true}, - {a: [0, 7], b: [1, 7]}, - {a: [1, 0], b: [1, 1], notAllowed: true}, - {a: [1, 0], b: [2, 0]}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 2], b: [1, 3], notAllowed: true}, - {a: [1, 2], b: [2, 2]}, - {a: [1, 3], b: [1, 4]}, - {a: [1, 3], b: [2, 3], notAllowed: true}, - {a: [1, 4], b: [1, 5]}, - {a: [1, 4], b: [2, 4], notAllowed: true}, - {a: [1, 5], b: [1, 6]}, - {a: [1, 5], b: [2, 5], notAllowed: true}, - {a: [1, 6], b: [1, 7], notAllowed: true}, - {a: [1, 6], b: [2, 6]}, - {a: [1, 7], b: [2, 7]}, - {a: [2, 0], b: [2, 1]}, - {a: [2, 1], b: [3, 1]}, - {a: [2, 2], b: [2, 3]}, - {a: [2, 2], b: [3, 2], notAllowed: true}, - {a: [2, 3], b: [2, 4], notAllowed: true}, - {a: [2, 3], b: [3, 3]}, - {a: [2, 4], b: [2, 5], notAllowed: true}, - {a: [2, 4], b: [3, 4], notAllowed: true}, - {a: [2, 5], b: [2, 6]}, - {a: [2, 5], b: [3, 5]}, - {a: [2, 6], b: [2, 7], notAllowed: true}, - {a: [2, 6], b: [3, 6], notAllowed: true}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 0], b: [3, 1], notAllowed: true}, - {a: [3, 1], b: [3, 2]}, - {a: [3, 1], b: [4, 1], notAllowed: true}, - {a: [3, 2], b: [4, 2]}, - {a: [3, 3], b: [3, 4]}, - {a: [3, 4], b: [3, 5], notAllowed: true}, - {a: [3, 4], b: [4, 4]}, - {a: [3, 5], b: [3, 6], notAllowed: true}, - {a: [3, 5], b: [4, 5]}, - {a: [3, 6], b: [3, 7]}, - {a: [3, 6], b: [4, 6]}, - {a: [4, 0], b: [4, 1], notAllowed: true}, - {a: [4, 1], b: [4, 2], notAllowed: true}, - {a: [4, 1], b: [5, 1], notAllowed: true}, - {a: [4, 2], b: [4, 3]}, - {a: [4, 2], b: [5, 2], notAllowed: true}, - {a: [4, 3], b: [4, 4], notAllowed: true}, - {a: [4, 3], b: [5, 3]}, - {a: [4, 4], b: [4, 5]}, - {a: [4, 4], b: [5, 4], notAllowed: true}, - {a: [4, 5], b: [4, 6], notAllowed: true}, - {a: [4, 5], b: [5, 5], notAllowed: true}, - {a: [4, 6], b: [4, 7]}, - {a: [4, 6], b: [5, 6], notAllowed: true}, - {a: [4, 7], b: [5, 7]}, - {a: [5, 0], b: [5, 1], notAllowed: true}, - {a: [5, 1], b: [5, 2]}, - {a: [5, 1], b: [6, 1]}, - {a: [5, 2], b: [5, 3]}, - {a: [5, 2], b: [6, 2], notAllowed: true}, - {a: [5, 3], b: [5, 4], notAllowed: true}, - {a: [5, 3], b: [6, 3], notAllowed: true}, - {a: [5, 4], b: [5, 5]}, - {a: [5, 4], b: [6, 4]}, - {a: [5, 5], b: [5, 6], notAllowed: true}, - {a: [5, 5], b: [6, 5]}, - {a: [5, 6], b: [5, 7]}, - {a: [5, 6], b: [6, 6]}, - {a: [6, 0], b: [6, 1]}, - {a: [6, 0], b: [7, 0]}, - {a: [6, 1], b: [7, 1], notAllowed: true}, - {a: [6, 2], b: [6, 3]}, - {a: [6, 2], b: [7, 2]}, - {a: [6, 3], b: [6, 4], notAllowed: true}, - {a: [6, 3], b: [7, 3]}, - {a: [6, 4], b: [6, 5], notAllowed: true}, - {a: [6, 4], b: [7, 4]}, - {a: [6, 5], b: [6, 6], notAllowed: true}, - {a: [6, 5], b: [7, 5]}, - {a: [6, 6], b: [6, 7]}, - {a: [6, 6], b: [7, 6], notAllowed: true}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 0], b: [7, 1]}, - {a: [7, 1], b: [7, 2]}, - {a: [7, 3], b: [7, 4]}, - {a: [7, 5], b: [7, 6]}, - {a: [7, 6], b: [7, 7]}, - ], - numbers: [ - {r: 1, c: 4, n: 3}, - {r: 1, c: 5, n: 2}, - {r: 1, c: 6, n: 2}, - {r: 2, c: 1, n: 2}, - {r: 2, c: 2, n: 2}, - {r: 2, c: 3, n: 2}, - {r: 2, c: 6, n: 3}, - {r: 3, c: 1, n: 2}, - {r: 3, c: 2, n: 2}, - {r: 3, c: 5, n: 1}, - {r: 3, c: 6, n: 2}, - {r: 4, c: 3, n: 2}, - {r: 4, c: 5, n: 3}, - {r: 4, c: 7, n: 3}, - {r: 5, c: 1, n: 0}, - {r: 5, c: 6, n: 0}, - {r: 5, c: 7, n: 3}, - {r: 6, c: 1, n: 2}, - {r: 6, c: 7, n: 3}, - {r: 7, c: 2, n: 2}, - {r: 7, c: 3, n: 3}, - {r: 7, c: 5, n: 2}, - ], -}; - -export const NOT_ALLOWED_1_GRID_PROPS = { - dim: [2, 2], - edges: [ - {a: [0, 1], b: [1, 1], hovered: true}, - {a: [1, 0], b: [1, 1], hovered: true}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 1], b: [2, 1]}, - ], - numbers: [{r: 2, c: 2, n: 2}], -}; - -export const NOT_ALLOWED_2_GRID_PROPS = { - dim: [2, 3], - edges: [ - {a: [0, 1], b: [1, 1]}, - {a: [0, 2], b: [1, 2]}, - {a: [1, 0], b: [1, 1], hovered: true}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 1], b: [2, 1], hovered: true}, - {a: [1, 2], b: [1, 3], hovered: true}, - {a: [1, 2], b: [2, 2], hovered: true}, - ], - numbers: [{r: 1, c: 2, n: 3}], -}; diff --git a/src/examples.js b/src/examples.js deleted file mode 100644 index 7b93bf0..0000000 --- a/src/examples.js +++ /dev/null @@ -1,608 +0,0 @@ -export const examples = [ - { - dim: [7, 7], - numbers: [ - {r: 1, c: 2, n: 2}, - {r: 1, c: 7, n: 3}, - {r: 2, c: 2, n: 3}, - {r: 2, c: 4, n: 2}, - {r: 2, c: 5, n: 2}, - {r: 2, c: 7, n: 1}, - {r: 3, c: 2, n: 3}, - {r: 3, c: 3, n: 2}, - {r: 3, c: 4, n: 2}, - {r: 3, c: 6, n: 2}, - {r: 3, c: 7, n: 2}, - {r: 4, c: 3, n: 2}, - {r: 4, c: 4, n: 0}, - {r: 4, c: 5, n: 3}, - {r: 4, c: 6, n: 2}, - {r: 5, c: 3, n: 2}, - {r: 5, c: 5, n: 3}, - {r: 5, c: 6, n: 2}, - {r: 6, c: 2, n: 2}, - {r: 6, c: 3, n: 1}, - {r: 6, c: 5, n: 1}, - {r: 7, c: 5, n: 3}, - {r: 7, c: 7, n: 3}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [1, 1]}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 3], b: [1, 3]}, - {a: [0, 4], b: [1, 4]}, - {a: [0, 6], b: [0, 7]}, - {a: [0, 6], b: [1, 6]}, - {a: [0, 7], b: [1, 7]}, - {a: [1, 0], b: [2, 0]}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 2], b: [2, 2]}, - {a: [1, 3], b: [2, 3]}, - {a: [1, 4], b: [2, 4]}, - {a: [1, 5], b: [1, 6]}, - {a: [1, 5], b: [2, 5]}, - {a: [1, 7], b: [2, 7]}, - {a: [2, 0], b: [3, 0]}, - {a: [2, 1], b: [2, 2]}, - {a: [2, 1], b: [3, 1]}, - {a: [2, 3], b: [3, 3]}, - {a: [2, 4], b: [3, 4]}, - {a: [2, 5], b: [2, 6]}, - {a: [2, 6], b: [3, 6]}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 0], b: [4, 0]}, - {a: [3, 1], b: [3, 2]}, - {a: [3, 2], b: [3, 3]}, - {a: [3, 4], b: [3, 5]}, - {a: [3, 5], b: [4, 5]}, - {a: [3, 6], b: [4, 6]}, - {a: [3, 7], b: [4, 7]}, - {a: [4, 0], b: [5, 0]}, - {a: [4, 1], b: [4, 2]}, - {a: [4, 1], b: [5, 1]}, - {a: [4, 2], b: [4, 3]}, - {a: [4, 3], b: [5, 3]}, - {a: [4, 4], b: [4, 5]}, - {a: [4, 4], b: [5, 4]}, - {a: [4, 6], b: [5, 6]}, - {a: [4, 7], b: [5, 7]}, - {a: [5, 0], b: [6, 0]}, - {a: [5, 1], b: [6, 1]}, - {a: [5, 3], b: [6, 3]}, - {a: [5, 4], b: [5, 5]}, - {a: [5, 5], b: [5, 6]}, - {a: [5, 7], b: [6, 7]}, - {a: [6, 0], b: [7, 0]}, - {a: [6, 1], b: [6, 2]}, - {a: [6, 2], b: [7, 2]}, - {a: [6, 3], b: [6, 4]}, - {a: [6, 4], b: [7, 4]}, - {a: [6, 5], b: [6, 6]}, - {a: [6, 5], b: [7, 5]}, - {a: [6, 6], b: [7, 6]}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 0], b: [7, 1]}, - {a: [7, 1], b: [7, 2]}, - {a: [7, 4], b: [7, 5]}, - {a: [7, 6], b: [7, 7]}, - ], - }, - { - dim: [7, 7], - numbers: [ - {r: 1, c: 4, n: 1}, - {r: 1, c: 7, n: 3}, - {r: 2, c: 1, n: 2}, - {r: 2, c: 2, n: 2}, - {r: 2, c: 3, n: 3}, - {r: 2, c: 4, n: 3}, - {r: 2, c: 5, n: 2}, - {r: 3, c: 1, n: 2}, - {r: 3, c: 2, n: 2}, - {r: 3, c: 5, n: 2}, - {r: 3, c: 6, n: 2}, - {r: 3, c: 7, n: 3}, - {r: 4, c: 1, n: 3}, - {r: 4, c: 2, n: 0}, - {r: 4, c: 3, n: 2}, - {r: 4, c: 7, n: 3}, - {r: 5, c: 1, n: 3}, - {r: 5, c: 5, n: 3}, - {r: 5, c: 6, n: 2}, - {r: 6, c: 2, n: 1}, - {r: 6, c: 4, n: 2}, - {r: 6, c: 6, n: 3}, - {r: 7, c: 2, n: 2}, - {r: 7, c: 6, n: 2}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [0, 2]}, - {a: [0, 2], b: [0, 3]}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 4], b: [0, 5]}, - {a: [0, 5], b: [0, 6]}, - {a: [0, 6], b: [0, 7]}, - {a: [0, 7], b: [1, 7]}, - {a: [1, 0], b: [1, 1]}, - {a: [1, 1], b: [2, 1]}, - {a: [1, 2], b: [1, 3]}, - {a: [1, 2], b: [2, 2]}, - {a: [1, 3], b: [2, 3]}, - {a: [1, 4], b: [1, 5]}, - {a: [1, 4], b: [2, 4]}, - {a: [1, 5], b: [1, 6]}, - {a: [1, 6], b: [1, 7]}, - {a: [2, 1], b: [3, 1]}, - {a: [2, 2], b: [3, 2]}, - {a: [2, 3], b: [2, 4]}, - {a: [2, 5], b: [2, 6]}, - {a: [2, 5], b: [3, 5]}, - {a: [2, 6], b: [2, 7]}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 0], b: [3, 1]}, - {a: [3, 0], b: [4, 0]}, - {a: [3, 2], b: [3, 3]}, - {a: [3, 3], b: [3, 4]}, - {a: [3, 4], b: [3, 5]}, - {a: [3, 6], b: [3, 7]}, - {a: [3, 6], b: [4, 6]}, - {a: [4, 0], b: [4, 1]}, - {a: [4, 1], b: [5, 1]}, - {a: [4, 2], b: [4, 3]}, - {a: [4, 2], b: [5, 2]}, - {a: [4, 3], b: [5, 3]}, - {a: [4, 4], b: [4, 5]}, - {a: [4, 4], b: [5, 4]}, - {a: [4, 5], b: [5, 5]}, - {a: [4, 6], b: [4, 7]}, - {a: [4, 7], b: [5, 7]}, - {a: [5, 0], b: [5, 1]}, - {a: [5, 0], b: [6, 0]}, - {a: [5, 2], b: [6, 2]}, - {a: [5, 3], b: [5, 4]}, - {a: [5, 5], b: [5, 6]}, - {a: [5, 6], b: [6, 6]}, - {a: [5, 7], b: [6, 7]}, - {a: [6, 0], b: [7, 0]}, - {a: [6, 2], b: [7, 2]}, - {a: [6, 3], b: [6, 4]}, - {a: [6, 3], b: [7, 3]}, - {a: [6, 4], b: [6, 5]}, - {a: [6, 5], b: [6, 6]}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 0], b: [7, 1]}, - {a: [7, 1], b: [7, 2]}, - {a: [7, 3], b: [7, 4]}, - {a: [7, 4], b: [7, 5]}, - {a: [7, 5], b: [7, 6]}, - {a: [7, 6], b: [7, 7]}, - ], - }, - { - dim: [7, 7], - numbers: [ - {r: 1, c: 2, n: 2}, - {r: 1, c: 4, n: 3}, - {r: 1, c: 5, n: 2}, - {r: 1, c: 6, n: 3}, - {r: 2, c: 2, n: 1}, - {r: 2, c: 3, n: 3}, - {r: 2, c: 4, n: 2}, - {r: 2, c: 6, n: 2}, - {r: 3, c: 2, n: 2}, - {r: 3, c: 4, n: 0}, - {r: 3, c: 5, n: 3}, - {r: 4, c: 1, n: 1}, - {r: 4, c: 2, n: 2}, - {r: 4, c: 3, n: 3}, - {r: 4, c: 5, n: 3}, - {r: 5, c: 1, n: 2}, - {r: 5, c: 2, n: 2}, - {r: 5, c: 3, n: 1}, - {r: 5, c: 4, n: 1}, - {r: 5, c: 5, n: 1}, - {r: 5, c: 6, n: 2}, - {r: 6, c: 1, n: 2}, - {r: 6, c: 3, n: 2}, - {r: 7, c: 4, n: 2}, - {r: 7, c: 5, n: 3}, - {r: 7, c: 7, n: 3}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [0, 2]}, - {a: [0, 2], b: [1, 2]}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 3], b: [1, 3]}, - {a: [0, 4], b: [1, 4]}, - {a: [0, 5], b: [0, 6]}, - {a: [0, 5], b: [1, 5]}, - {a: [0, 6], b: [0, 7]}, - {a: [0, 7], b: [1, 7]}, - {a: [1, 0], b: [2, 0]}, - {a: [1, 2], b: [2, 2]}, - {a: [1, 3], b: [2, 3]}, - {a: [1, 4], b: [2, 4]}, - {a: [1, 5], b: [1, 6]}, - {a: [1, 6], b: [2, 6]}, - {a: [1, 7], b: [2, 7]}, - {a: [2, 0], b: [2, 1]}, - {a: [2, 1], b: [3, 1]}, - {a: [2, 2], b: [2, 3]}, - {a: [2, 4], b: [2, 5]}, - {a: [2, 5], b: [3, 5]}, - {a: [2, 6], b: [3, 6]}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 1], b: [3, 2]}, - {a: [3, 2], b: [3, 3]}, - {a: [3, 3], b: [4, 3]}, - {a: [3, 4], b: [3, 5]}, - {a: [3, 4], b: [4, 4]}, - {a: [3, 6], b: [4, 6]}, - {a: [3, 7], b: [4, 7]}, - {a: [4, 0], b: [4, 1]}, - {a: [4, 0], b: [5, 0]}, - {a: [4, 1], b: [4, 2]}, - {a: [4, 2], b: [4, 3]}, - {a: [4, 4], b: [4, 5]}, - {a: [4, 5], b: [4, 6]}, - {a: [4, 7], b: [5, 7]}, - {a: [5, 0], b: [6, 0]}, - {a: [5, 1], b: [5, 2]}, - {a: [5, 1], b: [6, 1]}, - {a: [5, 2], b: [6, 2]}, - {a: [5, 3], b: [5, 4]}, - {a: [5, 3], b: [6, 3]}, - {a: [5, 4], b: [6, 4]}, - {a: [5, 5], b: [5, 6]}, - {a: [5, 5], b: [6, 5]}, - {a: [5, 6], b: [6, 6]}, - {a: [5, 7], b: [6, 7]}, - {a: [6, 0], b: [7, 0]}, - {a: [6, 1], b: [7, 1]}, - {a: [6, 2], b: [7, 2]}, - {a: [6, 3], b: [7, 3]}, - {a: [6, 4], b: [7, 4]}, - {a: [6, 5], b: [7, 5]}, - {a: [6, 6], b: [7, 6]}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 0], b: [7, 1]}, - {a: [7, 2], b: [7, 3]}, - {a: [7, 4], b: [7, 5]}, - {a: [7, 6], b: [7, 7]}, - ], - }, - { - dim: [7, 7], - numbers: [ - {r: 1, c: 2, n: 2}, - {r: 1, c: 3, n: 2}, - {r: 1, c: 4, n: 2}, - {r: 1, c: 5, n: 2}, - {r: 1, c: 6, n: 2}, - {r: 1, c: 7, n: 2}, - {r: 2, c: 1, n: 2}, - {r: 2, c: 7, n: 2}, - {r: 3, c: 1, n: 2}, - {r: 3, c: 3, n: 2}, - {r: 3, c: 4, n: 2}, - {r: 3, c: 5, n: 2}, - {r: 3, c: 7, n: 2}, - {r: 4, c: 1, n: 3}, - {r: 4, c: 5, n: 2}, - {r: 4, c: 7, n: 2}, - {r: 5, c: 2, n: 1}, - {r: 5, c: 4, n: 3}, - {r: 5, c: 5, n: 0}, - {r: 5, c: 6, n: 2}, - {r: 5, c: 7, n: 1}, - {r: 6, c: 1, n: 2}, - {r: 6, c: 2, n: 3}, - {r: 6, c: 4, n: 3}, - {r: 6, c: 5, n: 2}, - {r: 7, c: 5, n: 2}, - {r: 7, c: 6, n: 2}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [0, 2]}, - {a: [0, 2], b: [0, 3]}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 4], b: [0, 5]}, - {a: [0, 5], b: [0, 6]}, - {a: [0, 6], b: [0, 7]}, - {a: [0, 7], b: [1, 7]}, - {a: [1, 0], b: [1, 1]}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 2], b: [1, 3]}, - {a: [1, 3], b: [1, 4]}, - {a: [1, 4], b: [1, 5]}, - {a: [1, 5], b: [1, 6]}, - {a: [1, 6], b: [2, 6]}, - {a: [1, 7], b: [2, 7]}, - {a: [2, 0], b: [2, 1]}, - {a: [2, 0], b: [3, 0]}, - {a: [2, 1], b: [2, 2]}, - {a: [2, 2], b: [2, 3]}, - {a: [2, 3], b: [2, 4]}, - {a: [2, 4], b: [2, 5]}, - {a: [2, 5], b: [3, 5]}, - {a: [2, 6], b: [3, 6]}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 0], b: [4, 0]}, - {a: [3, 1], b: [3, 2]}, - {a: [3, 1], b: [4, 1]}, - {a: [3, 2], b: [3, 3]}, - {a: [3, 3], b: [3, 4]}, - {a: [3, 4], b: [4, 4]}, - {a: [3, 5], b: [4, 5]}, - {a: [3, 6], b: [4, 6]}, - {a: [3, 7], b: [4, 7]}, - {a: [4, 0], b: [4, 1]}, - {a: [4, 3], b: [4, 4]}, - {a: [4, 3], b: [5, 3]}, - {a: [4, 5], b: [4, 6]}, - {a: [4, 7], b: [5, 7]}, - {a: [5, 1], b: [5, 2]}, - {a: [5, 1], b: [6, 1]}, - {a: [5, 2], b: [6, 2]}, - {a: [5, 3], b: [5, 4]}, - {a: [5, 4], b: [6, 4]}, - {a: [5, 5], b: [5, 6]}, - {a: [5, 5], b: [6, 5]}, - {a: [5, 6], b: [6, 6]}, - {a: [5, 7], b: [6, 7]}, - {a: [6, 0], b: [6, 1]}, - {a: [6, 0], b: [7, 0]}, - {a: [6, 2], b: [6, 3]}, - {a: [6, 3], b: [6, 4]}, - {a: [6, 5], b: [7, 5]}, - {a: [6, 6], b: [7, 6]}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 0], b: [7, 1]}, - {a: [7, 1], b: [7, 2]}, - {a: [7, 2], b: [7, 3]}, - {a: [7, 3], b: [7, 4]}, - {a: [7, 4], b: [7, 5]}, - {a: [7, 6], b: [7, 7]}, - ], - }, - { - dim: [5, 5], - numbers: [ - {r: 1, c: 2, n: 3}, - {r: 1, c: 3, n: 1}, - {r: 1, c: 4, n: 2}, - {r: 2, c: 2, n: 3}, - {r: 2, c: 5, n: 2}, - {r: 3, c: 2, n: 2}, - {r: 3, c: 5, n: 3}, - {r: 4, c: 1, n: 2}, - {r: 4, c: 3, n: 1}, - {r: 4, c: 5, n: 2}, - {r: 5, c: 1, n: 0}, - {r: 5, c: 4, n: 3}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [0, 2]}, - {a: [0, 2], b: [1, 2]}, - {a: [0, 4], b: [0, 5]}, - {a: [0, 4], b: [1, 4]}, - {a: [0, 5], b: [1, 5]}, - {a: [1, 0], b: [2, 0]}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 1], b: [2, 1]}, - {a: [1, 3], b: [1, 4]}, - {a: [1, 3], b: [2, 3]}, - {a: [1, 5], b: [2, 5]}, - {a: [2, 0], b: [3, 0]}, - {a: [2, 1], b: [2, 2]}, - {a: [2, 2], b: [3, 2]}, - {a: [2, 3], b: [3, 3]}, - {a: [2, 4], b: [2, 5]}, - {a: [2, 4], b: [3, 4]}, - {a: [3, 0], b: [3, 1]}, - {a: [3, 1], b: [4, 1]}, - {a: [3, 2], b: [3, 3]}, - {a: [3, 4], b: [3, 5]}, - {a: [3, 5], b: [4, 5]}, - {a: [4, 1], b: [4, 2]}, - {a: [4, 2], b: [5, 2]}, - {a: [4, 3], b: [4, 4]}, - {a: [4, 3], b: [5, 3]}, - {a: [4, 4], b: [5, 4]}, - {a: [4, 5], b: [5, 5]}, - {a: [5, 2], b: [5, 3]}, - {a: [5, 4], b: [5, 5]}, - ], - }, - { - dim: [7, 7], - numbers: [ - {r: 1, c: 3, n: 2}, - {r: 2, c: 1, n: 2}, - {r: 2, c: 2, n: 3}, - {r: 2, c: 4, n: 2}, - {r: 2, c: 6, n: 2}, - {r: 3, c: 3, n: 1}, - {r: 3, c: 5, n: 3}, - {r: 4, c: 3, n: 2}, - {r: 4, c: 4, n: 3}, - {r: 4, c: 6, n: 3}, - {r: 4, c: 7, n: 2}, - {r: 5, c: 1, n: 3}, - {r: 5, c: 3, n: 0}, - {r: 5, c: 4, n: 2}, - {r: 6, c: 1, n: 2}, - {r: 6, c: 2, n: 3}, - {r: 6, c: 6, n: 2}, - {r: 7, c: 3, n: 1}, - {r: 7, c: 5, n: 3}, - {r: 7, c: 7, n: 3}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [1, 1]}, - {a: [0, 2], b: [0, 3]}, - {a: [0, 2], b: [1, 2]}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 4], b: [1, 4]}, - {a: [0, 5], b: [0, 6]}, - {a: [0, 5], b: [1, 5]}, - {a: [0, 6], b: [0, 7]}, - {a: [0, 7], b: [1, 7]}, - {a: [1, 0], b: [2, 0]}, - {a: [1, 1], b: [2, 1]}, - {a: [1, 2], b: [2, 2]}, - {a: [1, 3], b: [1, 4]}, - {a: [1, 3], b: [2, 3]}, - {a: [1, 5], b: [1, 6]}, - {a: [1, 6], b: [2, 6]}, - {a: [1, 7], b: [2, 7]}, - {a: [2, 0], b: [3, 0]}, - {a: [2, 1], b: [2, 2]}, - {a: [2, 3], b: [3, 3]}, - {a: [2, 4], b: [2, 5]}, - {a: [2, 4], b: [3, 4]}, - {a: [2, 5], b: [3, 5]}, - {a: [2, 6], b: [3, 6]}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 0], b: [3, 1]}, - {a: [3, 1], b: [3, 2]}, - {a: [3, 2], b: [4, 2]}, - {a: [3, 3], b: [4, 3]}, - {a: [3, 4], b: [4, 4]}, - {a: [3, 5], b: [4, 5]}, - {a: [3, 6], b: [4, 6]}, - {a: [3, 7], b: [4, 7]}, - {a: [4, 0], b: [4, 1]}, - {a: [4, 0], b: [5, 0]}, - {a: [4, 1], b: [4, 2]}, - {a: [4, 3], b: [4, 4]}, - {a: [4, 5], b: [4, 6]}, - {a: [4, 7], b: [5, 7]}, - {a: [5, 0], b: [5, 1]}, - {a: [5, 1], b: [5, 2]}, - {a: [5, 2], b: [6, 2]}, - {a: [5, 3], b: [5, 4]}, - {a: [5, 3], b: [6, 3]}, - {a: [5, 4], b: [5, 5]}, - {a: [5, 5], b: [5, 6]}, - {a: [5, 6], b: [6, 6]}, - {a: [5, 7], b: [6, 7]}, - {a: [6, 0], b: [6, 1]}, - {a: [6, 0], b: [7, 0]}, - {a: [6, 1], b: [6, 2]}, - {a: [6, 3], b: [6, 4]}, - {a: [6, 4], b: [6, 5]}, - {a: [6, 5], b: [7, 5]}, - {a: [6, 6], b: [7, 6]}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 0], b: [7, 1]}, - {a: [7, 1], b: [7, 2]}, - {a: [7, 2], b: [7, 3]}, - {a: [7, 3], b: [7, 4]}, - {a: [7, 4], b: [7, 5]}, - {a: [7, 6], b: [7, 7]}, - ], - }, - { - dim: [7, 7], - numbers: [ - {r: 1, c: 3, n: 1}, - {r: 1, c: 6, n: 3}, - {r: 1, c: 7, n: 2}, - {r: 2, c: 1, n: 2}, - {r: 2, c: 4, n: 2}, - {r: 2, c: 7, n: 2}, - {r: 3, c: 2, n: 2}, - {r: 3, c: 3, n: 1}, - {r: 3, c: 4, n: 2}, - {r: 3, c: 5, n: 0}, - {r: 3, c: 6, n: 3}, - {r: 4, c: 1, n: 2}, - {r: 4, c: 4, n: 2}, - {r: 4, c: 5, n: 3}, - {r: 5, c: 1, n: 3}, - {r: 5, c: 4, n: 2}, - {r: 5, c: 6, n: 2}, - {r: 6, c: 1, n: 2}, - {r: 6, c: 2, n: 2}, - {r: 6, c: 3, n: 2}, - {r: 6, c: 7, n: 1}, - {r: 7, c: 2, n: 2}, - {r: 7, c: 5, n: 1}, - ], - solution: [ - {a: [0, 0], b: [0, 1]}, - {a: [0, 0], b: [1, 0]}, - {a: [0, 1], b: [0, 2]}, - {a: [0, 2], b: [0, 3]}, - {a: [0, 3], b: [0, 4]}, - {a: [0, 4], b: [1, 4]}, - {a: [0, 5], b: [0, 6]}, - {a: [0, 5], b: [1, 5]}, - {a: [0, 6], b: [1, 6]}, - {a: [1, 0], b: [1, 1]}, - {a: [1, 1], b: [1, 2]}, - {a: [1, 2], b: [2, 2]}, - {a: [1, 3], b: [1, 4]}, - {a: [1, 3], b: [2, 3]}, - {a: [1, 5], b: [2, 5]}, - {a: [1, 6], b: [1, 7]}, - {a: [1, 7], b: [2, 7]}, - {a: [2, 0], b: [2, 1]}, - {a: [2, 0], b: [3, 0]}, - {a: [2, 1], b: [2, 2]}, - {a: [2, 3], b: [3, 3]}, - {a: [2, 5], b: [2, 6]}, - {a: [2, 6], b: [3, 6]}, - {a: [2, 7], b: [3, 7]}, - {a: [3, 0], b: [3, 1]}, - {a: [3, 1], b: [3, 2]}, - {a: [3, 2], b: [4, 2]}, - {a: [3, 3], b: [3, 4]}, - {a: [3, 4], b: [4, 4]}, - {a: [3, 5], b: [3, 6]}, - {a: [3, 5], b: [4, 5]}, - {a: [3, 7], b: [4, 7]}, - {a: [4, 0], b: [4, 1]}, - {a: [4, 0], b: [5, 0]}, - {a: [4, 1], b: [5, 1]}, - {a: [4, 2], b: [4, 3]}, - {a: [4, 3], b: [5, 3]}, - {a: [4, 4], b: [4, 5]}, - {a: [4, 6], b: [4, 7]}, - {a: [4, 6], b: [5, 6]}, - {a: [5, 0], b: [6, 0]}, - {a: [5, 1], b: [5, 2]}, - {a: [5, 2], b: [6, 2]}, - {a: [5, 3], b: [5, 4]}, - {a: [5, 4], b: [6, 4]}, - {a: [5, 5], b: [5, 6]}, - {a: [5, 5], b: [6, 5]}, - {a: [6, 0], b: [6, 1]}, - {a: [6, 1], b: [7, 1]}, - {a: [6, 2], b: [6, 3]}, - {a: [6, 3], b: [6, 4]}, - {a: [6, 5], b: [6, 6]}, - {a: [6, 6], b: [6, 7]}, - {a: [6, 7], b: [7, 7]}, - {a: [7, 1], b: [7, 2]}, - {a: [7, 2], b: [7, 3]}, - {a: [7, 3], b: [7, 4]}, - {a: [7, 4], b: [7, 5]}, - {a: [7, 5], b: [7, 6]}, - {a: [7, 6], b: [7, 7]}, - ], - }, -]; diff --git a/src/index.scss b/src/index.scss deleted file mode 100644 index 3e3b6a1..0000000 --- a/src/index.scss +++ /dev/null @@ -1,13 +0,0 @@ -body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', - monospace; -} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..6a7f6c9 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,10 @@ +import { mount } from 'svelte' +import './app.scss' +import './global.sass' +import App from './App.svelte' + +const app = mount(App, { + target: document.getElementById('app')!, +}) + +export default app diff --git a/src/main.tsx b/src/main.tsx deleted file mode 100644 index 42eaf17..0000000 --- a/src/main.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { render } from 'preact' -import './index.scss' -import App from './App.tsx' - -render(, document.getElementById('app')!) diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js deleted file mode 100644 index 81d1046..0000000 --- a/src/reportWebVitals.js +++ /dev/null @@ -1,13 +0,0 @@ -const reportWebVitals = (onPerfEntry) => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import("web-vitals").then(({getCLS, getFID, getFCP, getLCP, getTTFB}) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } -}; - -export default reportWebVitals; diff --git a/src/setupTests.js b/src/setupTests.js deleted file mode 100644 index 1dd407a..0000000 --- a/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import "@testing-library/jest-dom"; diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index cd8f091..0000000 --- a/src/utils.js +++ /dev/null @@ -1,191 +0,0 @@ -import {DEFAULT_NODE} from "./components/Grid"; -import {EDGE_STATE} from "./constants"; - -// get deep copy of JSON -export const copy = (json) => JSON.parse(JSON.stringify(json)); - -// to get multiple styles in space-seperated format -export const multiStyles = (styles, classNames) => - classNames - .reduce( - (classNames, className) => [ - ...classNames, - ...(!className ? [] : [styles?.[className] || className]), - ], - [] - ) - .join(" "); - -// to check if number is valid number -export const isValid = (n, lim) => n >= 0 && n <= lim; - -// to check all elements are valid numbers -export const areValid = (n, lim) => n.every((n) => isValid(n, lim)); - -export const getMatrix = ([dim1, dim2], edges = [], numbers = []) => { - const nRows = dim1; - const nCols = dim2; - - let temp = new Array(dim1 + 1) - .fill(0) - .map(() => new Array(dim2 + 1).fill(DEFAULT_NODE)); - - if (numbers.length > 0) { - numbers.forEach(({r, c, n}) => { - if (r <= nRows && c <= nCols) { - temp[r - 1][c - 1] = {...temp[r - 1][c - 1], n}; - } - }); - } - - if (edges.length > 0) { - edges.forEach(({a: [sx, sy], b: [ex, ey], notAllowed, hovered}) => { - const edgeState = notAllowed - ? EDGE_STATE.NOT_ALLOWED - : hovered - ? EDGE_STATE.HOVERED - : EDGE_STATE.ACTIVE; - let startX, startY, endX, endY, hor, ver; - hor = sx === ex; - ver = sy === ey; - - // excluding cases where both points are same - // or where edge is not hor | ver - // Assumption: all edges are between two adjacent nodes - if ((hor && ver) || (!hor && !ver)) { - return; - } - - // horizonal line - if (hor) { - startX = endX = sx; - if (sy > ey) { - startY = ey; - endY = sy; - } - if (sy < ey) { - startY = sy; - endY = ey; - } - } - // vertical line - if (ver) { - startY = endY = sy; - if (sx > ex) { - startX = ex; - endX = sx; - } - if (sx < ex) { - startX = sx; - endX = ex; - } - } - - // check if all nodes are valid nodes - if (areValid([startX, endX], nRows) && areValid([startY, endY], nCols)) { - temp[startX][startY] = { - ...temp[startX][startY], - neigh: [ - ...temp[startX][startY].neigh, - {state: edgeState, loc: [endX, endY]}, - ], - }; - temp[endX][endY] = { - ...temp[endX][endY], - neigh: [ - ...temp[endX][endY].neigh, - {state: edgeState, loc: [startX, startY]}, - ], - }; - } - }); - } - - return temp; -}; - -// to check if a node has an active edge -export const isNodeActive = (n) => - Array.isArray(n?.neigh) && - n.neigh.some((neighbor) => neighbor.state === EDGE_STATE.ACTIVE); - -// to get neighbors from matrix -export const getNeighbors = ([ax, ay], mat) => { - return mat[ax][ay]?.neigh || []; -}; - -// to check if two nodes are neighbor in a matrix -export const findNeighbor = ([ax, ay], [bx, by], mat) => { - const index = mat?.[ax]?.[ay]?.neigh.findIndex( - ({loc}) => loc[0] === bx && loc[1] === by - ); - return isNaN(index) ? -1 : index; -}; - -// get an array of all numbers present in the matrix -export const getNumbers = (mat) => { - let numbers = []; - let nRow = mat?.length; - let nCol = mat?.[0]?.length; - if (!nRow || !nCol) { - return; - } - - mat.forEach((row, r) => { - if (r >= nRow - 1) return; - row.forEach((node, c) => { - if (c >= nCol - 1) return; - numbers = [ - ...numbers, - ...(node.n > -1 ? [{r: r + 1, c: c + 1, n: node.n}] : []), - ]; - }); - }); - return numbers; -}; - -// get an array of all edges present in the matrix -export const getEdges = (mat) => { - let edges = []; - mat.forEach((row, sX) => { - row.forEach((node, sY) => { - let horEdges = []; - let verEdges = []; - node.neigh.forEach((edge) => { - const [eX, eY] = edge.loc; - if (eX > sX && eY === sY) { - verEdges = [ - ...verEdges, - { - a: [sX, sY], - b: [eX, eY], - ...(edge?.state === EDGE_STATE.NOT_ALLOWED - ? {notAllowed: true} - : {}), - ...(edge?.state === EDGE_STATE.HOVERED ? {hovered: true} : {}), - }, - ]; - } else if (eY > sY && eX === sX) { - horEdges = [ - ...horEdges, - { - a: [sX, sY], - b: [eX, eY], - ...(edge?.state === EDGE_STATE.NOT_ALLOWED - ? {notAllowed: true} - : {}), - ...(edge?.state === EDGE_STATE.HOVERED ? {hovered: true} : {}), - }, - ]; - } - }); - edges = [...edges, ...horEdges, ...verEdges]; - }); - }); - return edges; -}; - -// get an array of all active edges present in the matrix -export const getActiveEdges = (mat) => { - return getEdges(mat).filter((edge) => !edge?.notAllowed && !edge?.hovered); -}; diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe..4078e74 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1,2 @@ +/// /// diff --git a/svelte.config.js b/svelte.config.js new file mode 100644 index 0000000..b0683fd --- /dev/null +++ b/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/tsconfig.app.json b/tsconfig.app.json deleted file mode 100644 index d5cbc23..0000000 --- a/tsconfig.app.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "target": "ES2020", - "useDefineForClassFields": true, - "module": "ESNext", - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "skipLibCheck": true, - "paths": { - "react": ["./node_modules/preact/compat/"], - "react-dom": ["./node_modules/preact/compat/"] - }, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "isolatedModules": true, - "moduleDetection": "force", - "noEmit": true, - "jsx": "react-jsx", - "jsxImportSource": "preact", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true - }, - "include": ["src"] -} diff --git a/tsconfig.json b/tsconfig.json index 1ffef60..df56300 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,21 @@ { - "files": [], - "references": [ - { "path": "./tsconfig.app.json" }, - { "path": "./tsconfig.node.json" } - ] + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true, + "moduleDetection": "force" + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] } diff --git a/tsconfig.node.json b/tsconfig.node.json index db0becc..46d1fa3 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,23 +1,12 @@ { "compilerOptions": { + "composite": true, "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", - "target": "ES2022", - "lib": ["ES2023"], - "module": "ESNext", "skipLibCheck": true, - - /* Bundler mode */ + "module": "ESNext", "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "isolatedModules": true, - "moduleDetection": "force", - "noEmit": true, - - /* Linting */ "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, + "noEmit": true, "noUncheckedSideEffectImports": true }, "include": ["vite.config.ts"] diff --git a/vite.config.ts b/vite.config.ts index b995c32..d32eba1 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ import { defineConfig } from 'vite' -import preact from '@preact/preset-vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' // https://vite.dev/config/ export default defineConfig({ - plugins: [preact()], + plugins: [svelte()], })