From ef1bf0b688d789c38197bba49cb23f67ef93a3b2 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Mon, 16 Dec 2024 05:17:44 -0500 Subject: [PATCH] [+] Restart project, rewrite in svelte --- .gitignore | 42 +- .vscode/extensions.json | 3 + .vscode/settings.json | 18 - README.md | 51 +- bun.lockb | Bin 61118 -> 46236 bytes index.html | 34 +- package.json | 16 +- public/favicon.ico | Bin 15406 -> 0 bytes public/logo.svg | 1 - public/logo192.png | Bin 10432 -> 0 bytes public/logo512.png | Bin 28700 -> 0 bytes public/manifest.json | 25 - public/robots.txt | 3 - public/vite.svg | 1 + src/App.css | 5 - src/App.tsx | 8 - src/app.scss | 69 ++ src/assets/svelte.svg | 1 + src/components/AddPuzzleScreen/index.js | 119 ---- .../AddPuzzleScreen/styles.module.scss | 159 ----- src/components/CheckSolution/index.js | 44 -- .../CheckSolution/styles.module.scss | 38 -- src/components/Controls/index.js | 50 -- src/components/Controls/styles.module.scss | 47 -- src/components/Game/index.js | 91 --- src/components/Game/styles.module.scss | 32 - src/components/Grid/components/Cross.js | 36 -- src/components/Grid/components/Edge.js | 8 - src/components/Grid/components/Line.js | 35 - src/components/Grid/components/LineRow.js | 57 -- src/components/Grid/components/N.js | 16 - src/components/Grid/components/Node.js | 13 - src/components/Grid/components/NumberRow.js | 80 --- src/components/Grid/components/Row.js | 5 - src/components/Grid/index.js | 175 ----- src/components/Grid/styles.module.scss | 298 --------- src/components/Icons.js | 87 --- src/components/Info/index.js | 146 ----- src/components/Info/styles.module.scss | 186 ------ src/constants.js | 159 ----- src/examples.js | 608 ------------------ src/index.scss | 13 - src/main.ts | 10 + src/main.tsx | 5 - src/reportWebVitals.js | 13 - src/setupTests.js | 5 - src/utils.js | 191 ------ src/vite-env.d.ts | 1 + svelte.config.js | 7 + tsconfig.app.json | 31 - tsconfig.json | 24 +- tsconfig.node.json | 17 +- vite.config.ts | 4 +- 53 files changed, 198 insertions(+), 2889 deletions(-) create mode 100644 .vscode/extensions.json delete mode 100644 .vscode/settings.json delete mode 100644 public/favicon.ico delete mode 100644 public/logo.svg delete mode 100644 public/logo192.png delete mode 100644 public/logo512.png delete mode 100644 public/manifest.json delete mode 100644 public/robots.txt create mode 100644 public/vite.svg delete mode 100644 src/App.css delete mode 100644 src/App.tsx create mode 100644 src/app.scss create mode 100644 src/assets/svelte.svg delete mode 100644 src/components/AddPuzzleScreen/index.js delete mode 100644 src/components/AddPuzzleScreen/styles.module.scss delete mode 100644 src/components/CheckSolution/index.js delete mode 100644 src/components/CheckSolution/styles.module.scss delete mode 100644 src/components/Controls/index.js delete mode 100644 src/components/Controls/styles.module.scss delete mode 100644 src/components/Game/index.js delete mode 100644 src/components/Game/styles.module.scss delete mode 100644 src/components/Grid/components/Cross.js delete mode 100644 src/components/Grid/components/Edge.js delete mode 100644 src/components/Grid/components/Line.js delete mode 100644 src/components/Grid/components/LineRow.js delete mode 100644 src/components/Grid/components/N.js delete mode 100644 src/components/Grid/components/Node.js delete mode 100644 src/components/Grid/components/NumberRow.js delete mode 100644 src/components/Grid/components/Row.js delete mode 100644 src/components/Grid/index.js delete mode 100644 src/components/Grid/styles.module.scss delete mode 100644 src/components/Icons.js delete mode 100644 src/components/Info/index.js delete mode 100644 src/components/Info/styles.module.scss delete mode 100644 src/constants.js delete mode 100644 src/examples.js delete mode 100644 src/index.scss create mode 100644 src/main.ts delete mode 100644 src/main.tsx delete mode 100644 src/reportWebVitals.js delete mode 100644 src/setupTests.js delete mode 100644 src/utils.js create mode 100644 svelte.config.js delete mode 100644 tsconfig.app.json 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 abf2dfb8f06abca92350cc2f9ea1798d70566662..d2053e0f78180af337adcd61ef3d426b253f51b9 100644 GIT binary patch delta 11251 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 dFWQ$?m)AI5?PtF+LAph{} + - - - - - - - - - - - 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 643ac3063b4be8062bcafce7ccdfb4e318781b20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15406 zcmeHNYiv}<6~3mCs{U&7BmWSA>-Ay`_WF%&j2{>qjDZl$8v_o+*gOKU%`+761M_qO zfi%1V4OLY|RUbl0ny3#&P1UGM=_3+tMb%1e38^cGmQoirH1X;AX74d~@7{a&-rWUv z+paX4y)$RdYi7=zIcGF2P5X@Y@WUF{ zchDj8fbrlVYW&-~H_>Yy>#1;3Fsjc4A6{3M@%fn>yNCS`4?ITBq7T(WA|nekkzxWGOo`qOp&^Eny%a@Oy8=J^WOAB8gXPf+mRXyZP8 zIbai|C*wo99%LF9LK*3IOzYFSW+J}fz2{*g?{Q<+z=seT|o|AJG`5I zcXW^4c@hCTf{*P3bO2lB)waCO=jIRhY_Y|+wq`of#eO=uX0dJm2wjnrZIsy5s6K(Q z)S!Qcbzlcy8Jeu+YV&ja>D(lX_)LE2zia6H2hToDxJ&pMYlUU`mA__fclyTNqN{1v>|hq#MkJ>p!JcGucCe-wTAxE{~nBEGj>YHLzw?vM99L*L!G zkv@2SAKm)m0lK(;rPnnPasDbEeE1)b3;Ko)Y^|%L#jJCid$^k(BK!}~A8r2&JdCFQ z3HtbrrvDx0z|cc7ePPDs_Y%goyiE^c<+uI~oMDjbXpIPWLVf;&ss#~J7Pb>=yd7>>vU z9M^#pxP?xV>$JQ;;L%WULMPAv?KpHTyt>w5+!H!Mi}_DWmJHc}KqdQfZzW0Jt}-YZ zObaxVz<*kHFujFw4seNzS#w(~UgGTstpU)EcOC+Pz-L22y`9U@edIHSe4wqjgBPE3 zk!J9IbM$zZxz(8mz1`0|gxAby>Rou3S|2jjQmko6Q+qYM-eb(I;C^8BfU&0??UJ&Q zVLS66_o`Pt4Z{W+w$*kXVBdMYCv+y^9*Dcw;pGeH1n1Lwm(HWr)zdhy=RN-9vgeq$ z37vM#qghDPxwdNvVvpvZm@{0;Ee&|N!K~H19{xw-TJ_@+&vgB9{*j@7XE*8WH-m# z-Pa#%6Y@deANza($IIP#jL~;P?oBb^TxnG2O;I^30gw6Yw zczBRFK|EtUjVa-|In}(F{&D7z;{W#PKHBm4EKg%S%z?x>l7%k<4{{Ng+gsG$fbNka zz+S<8c;L+ojKpWWziIB}DIk=iE^jzbnMql`J|YJSwJV`i`3h{Lr2y zb7{!fr_ep}ahQu_;J3p8`-wBauFr29?kMmHpm*dF-|K4kpSSk8j=?+5V86WD!6V-$ zYX)yH=kS}W>owH{NtC5 z_!Z^@>m2VF5l4BhsZqs+T52oedCzE_56Acw_)qotA&ZdG@mtIRekmM34-3HakjnWB z2$ACXqmg+Cucg$>--!UIQ#gMrVx)BbT7*E2b2 \ No newline at end of file diff --git a/public/logo192.png b/public/logo192.png deleted file mode 100644 index c175075e0d6d7627964dd5c7e32c76d1f6412a8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10432 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 - )} - - ); -}; - -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()], })