Some refactoring
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
@@ -20,6 +21,7 @@ module.exports = {
|
||||
},
|
||||
plugins: ["react", "prettier", "react-hooks", "import"],
|
||||
rules: {
|
||||
"no-undef": "error",
|
||||
"react/prop-types": "off",
|
||||
"react/no-unescaped-entities": "warn",
|
||||
"react-hooks/rules-of-hooks": "error",
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
body, html, #root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
+3
-28
@@ -1,35 +1,10 @@
|
||||
import * as React from "react";
|
||||
|
||||
import styles from "./App.styles.module.scss";
|
||||
import CheckSolution from "./components/CheckSolution";
|
||||
import Grid from "./components/Grid";
|
||||
import Info from "./components/Info";
|
||||
import {examples} from "./examples";
|
||||
import Game from "./components/Game";
|
||||
import "./App.css";
|
||||
|
||||
const App = () => {
|
||||
const [matrix, setMatirx] = React.useState([]);
|
||||
const [{dim, numbers, solution}] = React.useState(
|
||||
examples[Math.floor(Math.random() * examples.length)]
|
||||
);
|
||||
const [check, setCheck] = React.useState("none");
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1 className={styles.heading}>
|
||||
<span>Slither</span>
|
||||
<span>Link</span>
|
||||
</h1>
|
||||
<Grid
|
||||
dim={dim}
|
||||
numbers={numbers}
|
||||
matrix={matrix}
|
||||
updateMatrix={setMatirx}
|
||||
check={check}
|
||||
/>
|
||||
<Info />
|
||||
<CheckSolution matrix={matrix} solution={solution} setCheck={setCheck} />
|
||||
</main>
|
||||
);
|
||||
return <Game />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from "react";
|
||||
import {getNumbers, multiStyles} from "../../utils";
|
||||
import {getMatrix, getNumbers, multiStyles} from "../../utils";
|
||||
import Controls from "../Controls";
|
||||
import Grid from "../Grid";
|
||||
import N from "../Grid/components/N";
|
||||
|
||||
@@ -8,8 +9,14 @@ 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)]);
|
||||
@@ -17,10 +24,13 @@ const AddPuzzleScreen = ({open, onClose}) => {
|
||||
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 = () => {
|
||||
@@ -40,7 +50,7 @@ const AddPuzzleScreen = ({open, onClose}) => {
|
||||
}, [submitState]);
|
||||
|
||||
const shouldShowGrid =
|
||||
!isNaN(dim[0]) && dim[0] > 0 && !isNaN(dim[1]) && dim[1] > 0 && !gridReset;
|
||||
!isNaN(dim[0]) && dim[0] > 0 && !isNaN(dim[1]) && dim[1] > 0;
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -79,34 +89,27 @@ const AddPuzzleScreen = ({open, onClose}) => {
|
||||
<div className={styles.content}>
|
||||
<div className={styles.matrixGrid}>
|
||||
{shouldShowGrid ? (
|
||||
<Grid
|
||||
dim={dim}
|
||||
matrix={gridMat}
|
||||
updateMatrix={setGridMat}
|
||||
numbers={gridNumbers}
|
||||
onReset={() => {
|
||||
setGridNumbers([]);
|
||||
setGridReset(true);
|
||||
}}
|
||||
editorMode
|
||||
/>
|
||||
<Grid matrix={gridMat} setMatrix={setGridMat} editorMode />
|
||||
) : (
|
||||
"Please set valid dimensions above"
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<a
|
||||
href={`mailto:amey23399@gmail.com?subject=Slither Link Example&body=${JSON.stringify(
|
||||
gridNumbers
|
||||
)}`}
|
||||
className={multiStyles(styles, ["submitButton", submitState])}
|
||||
onClick={onSubmit}
|
||||
>
|
||||
{submitText}
|
||||
</a>
|
||||
{shouldShowGrid && (
|
||||
<a
|
||||
href={`mailto:amey23399@gmail.com?subject=Slither Link Example&body=${JSON.stringify(
|
||||
gridNumbers
|
||||
)}`}
|
||||
className={multiStyles(styles, ["submitButton", submitState])}
|
||||
onClick={onSubmit}
|
||||
>
|
||||
{submitText}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
<Controls onReset={() => setGridReset(true)} editorMode />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
font-size: 12px;
|
||||
color: #90a4ae;
|
||||
gap: 2px;
|
||||
cursor: pointer;
|
||||
|
||||
& > svg {
|
||||
background-color: #263238;
|
||||
@@ -28,21 +29,19 @@
|
||||
border: 2px solid #455a64;
|
||||
font-family: Georgia, 'Times New Roman', Times, serif;
|
||||
color: #fafafa;
|
||||
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
|
||||
& > svg {
|
||||
border-color: #78909c;
|
||||
font-size: 22px;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import * as React from "react";
|
||||
import {examples} from "../../examples";
|
||||
import {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 [check, setCheck] = React.useState("none");
|
||||
|
||||
// initializing matrix with example
|
||||
React.useEffect(() => {
|
||||
if (dim.length) {
|
||||
setMatrix(getMatrix(dim, [], numbers));
|
||||
}
|
||||
}, [dim.length]);
|
||||
|
||||
const onReset = () => {
|
||||
if (dim.length) {
|
||||
setMatrix(getMatrix(dim, [], numbers));
|
||||
}
|
||||
};
|
||||
|
||||
const onRefresh = () => {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1 className={styles.heading}>
|
||||
<span>Slither</span>
|
||||
<span>Link</span>
|
||||
</h1>
|
||||
<Grid matrix={matrix} setMatrix={setMatrix} state={check} />
|
||||
<Info />
|
||||
<CheckSolution matrix={matrix} solution={solution} setCheck={setCheck} />
|
||||
<Controls onReset={onReset} onRefresh={onRefresh} />
|
||||
</main>
|
||||
);
|
||||
};
|
||||
|
||||
export default Game;
|
||||
+62
-178
@@ -20,110 +20,19 @@ import styles from "./styles.module.scss";
|
||||
V V V
|
||||
*/
|
||||
|
||||
const DEFAULT_NODE = {neigh: [], n: -1};
|
||||
export const DEFAULT_NODE = {neigh: [], n: -1};
|
||||
/*
|
||||
structure for neigh elements:
|
||||
{state: <EDGE_STATE>, loc: [x, y]}
|
||||
*/
|
||||
|
||||
const Grid = ({
|
||||
dim = [3, 3],
|
||||
edges = [],
|
||||
numbers = [],
|
||||
matrix: propMatrix = [],
|
||||
updateMatrix: updatePropMatrix = () => {},
|
||||
readOnly,
|
||||
onReset: propOnReset,
|
||||
editorMode,
|
||||
check,
|
||||
className,
|
||||
}) => {
|
||||
const nRows = dim[0];
|
||||
const nCols = dim[1];
|
||||
const nHorLine = nRows + 1;
|
||||
const nVerLine = nCols + 1;
|
||||
const [matrix, setMatrix] = React.useState([]);
|
||||
const Grid = ({matrix, setMatrix, readOnly, editorMode, state, className}) => {
|
||||
const nHorLine = matrix?.length || 0;
|
||||
const nVerLine = matrix?.[0]?.length || 0;
|
||||
|
||||
const setPropMatrix = (matrix) => {
|
||||
if (Array.isArray(propMatrix)) {
|
||||
updatePropMatrix(matrix);
|
||||
}
|
||||
};
|
||||
|
||||
// initializing matrix with prop edges and numbers
|
||||
React.useEffect(() => {
|
||||
let temp = new Array(nHorLine)
|
||||
.fill(0)
|
||||
.map(() => new Array(nVerLine).fill(DEFAULT_NODE));
|
||||
numbers.forEach(({r, c, n}) => {
|
||||
if (r <= nRows && c <= nCols) {
|
||||
temp[r - 1][c - 1] = {...temp[r - 1][c - 1], n};
|
||||
}
|
||||
});
|
||||
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]},
|
||||
],
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
setMatrix(temp);
|
||||
setPropMatrix(temp);
|
||||
}, []);
|
||||
if (nHorLine === 0 || nVerLine === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const updateMatrix = (dataArray) => {
|
||||
let temp = matrix.slice();
|
||||
@@ -131,10 +40,13 @@ const Grid = ({
|
||||
temp[x][y] = {...temp[x][y], ...data};
|
||||
});
|
||||
setMatrix(temp);
|
||||
setPropMatrix(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];
|
||||
@@ -204,89 +116,61 @@ const Grid = ({
|
||||
onLineClick(x, y, direction, "middle");
|
||||
|
||||
const onNumberChange = (x, y, num) => {
|
||||
if (!editorMode || readOnly) {
|
||||
return;
|
||||
}
|
||||
updateMatrix([{node: [x, y], data: {n: num}}]);
|
||||
};
|
||||
|
||||
const onReset = () => {
|
||||
let temp = new Array(nHorLine)
|
||||
.fill(0)
|
||||
.map(() => new Array(nVerLine).fill(DEFAULT_NODE));
|
||||
numbers.forEach(({r, c, n}) => {
|
||||
if (r <= nRows && c <= nCols) {
|
||||
temp[r - 1][c - 1] = {...temp[r - 1][c - 1], n};
|
||||
}
|
||||
});
|
||||
if (editorMode) {
|
||||
propOnReset();
|
||||
}
|
||||
setMatrix(temp);
|
||||
setPropMatrix(temp);
|
||||
};
|
||||
|
||||
const onRefresh = () => {
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{matrix.length > 0 && (
|
||||
<div
|
||||
className={multiStyles(styles, [
|
||||
"canvas",
|
||||
className,
|
||||
check,
|
||||
readOnly && "readOnly",
|
||||
])}
|
||||
// disabling right click on grid
|
||||
onContextMenu={(e) => e.preventDefault()}
|
||||
>
|
||||
{Array(nHorLine - 1)
|
||||
.fill(0)
|
||||
.map((_, i) => {
|
||||
return [
|
||||
<LineRow
|
||||
matX={i}
|
||||
mat={matrix}
|
||||
n={nVerLine}
|
||||
onLineClick={onLineLeftClick}
|
||||
onLineRightClick={onLineRightClick}
|
||||
onLineMiddleClick={onLineMiddleClick}
|
||||
key={`line_row_${i}`}
|
||||
/>,
|
||||
<NumberRow
|
||||
matX={i}
|
||||
mat={matrix}
|
||||
n={nVerLine}
|
||||
onLineClick={onLineLeftClick}
|
||||
onLineRightClick={onLineRightClick}
|
||||
onLineMiddleClick={onLineMiddleClick}
|
||||
onNumberChange={onNumberChange}
|
||||
editorMode={editorMode}
|
||||
key={`number_row_${i}`}
|
||||
/>,
|
||||
];
|
||||
})
|
||||
.concat([
|
||||
<LineRow
|
||||
matX={nHorLine - 1}
|
||||
mat={matrix}
|
||||
n={nVerLine}
|
||||
onLineClick={onLineLeftClick}
|
||||
onLineRightClick={onLineRightClick}
|
||||
onLineMiddleClick={onLineMiddleClick}
|
||||
key={`line_row_${nHorLine - 1}`}
|
||||
/>,
|
||||
])}
|
||||
</div>
|
||||
)}
|
||||
{!readOnly && (
|
||||
<Controls
|
||||
onReset={onReset}
|
||||
onRefresh={onRefresh}
|
||||
editorMode={editorMode}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
<div
|
||||
className={multiStyles(styles, [
|
||||
"canvas",
|
||||
className,
|
||||
state,
|
||||
readOnly && "readOnly",
|
||||
])}
|
||||
// disabling right click on grid
|
||||
onContextMenu={(e) => e.preventDefault()}
|
||||
>
|
||||
{Array(nHorLine - 1)
|
||||
.fill(0)
|
||||
.map((_, i) => {
|
||||
return [
|
||||
<LineRow
|
||||
matX={i}
|
||||
mat={matrix}
|
||||
n={nVerLine}
|
||||
onLineClick={onLineLeftClick}
|
||||
onLineRightClick={onLineRightClick}
|
||||
onLineMiddleClick={onLineMiddleClick}
|
||||
key={`line_row_${i}`}
|
||||
/>,
|
||||
<NumberRow
|
||||
matX={i}
|
||||
mat={matrix}
|
||||
n={nVerLine}
|
||||
onLineClick={onLineLeftClick}
|
||||
onLineRightClick={onLineRightClick}
|
||||
onLineMiddleClick={onLineMiddleClick}
|
||||
onNumberChange={onNumberChange}
|
||||
editorMode={editorMode}
|
||||
key={`number_row_${i}`}
|
||||
/>,
|
||||
];
|
||||
})
|
||||
.concat([
|
||||
<LineRow
|
||||
matX={nHorLine - 1}
|
||||
mat={matrix}
|
||||
n={nVerLine}
|
||||
onLineClick={onLineLeftClick}
|
||||
onLineRightClick={onLineRightClick}
|
||||
onLineMiddleClick={onLineMiddleClick}
|
||||
key={`line_row_${nHorLine - 1}`}
|
||||
/>,
|
||||
])}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
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";
|
||||
@@ -13,8 +14,9 @@ const Info = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.button} onClick={() => setOpen(true)}>
|
||||
i
|
||||
<div className={styles.container} onClick={() => setOpen(true)}>
|
||||
<div className={styles.button}>i</div>
|
||||
<span>Info</span>
|
||||
</div>
|
||||
{open && (
|
||||
<div className={styles.info}>
|
||||
@@ -26,15 +28,36 @@ const Info = () => {
|
||||
Connect adjacent dots with vertical or horizontal lines, creating
|
||||
a single loop.
|
||||
<div className={styles.eg}>
|
||||
<Grid {...EXAMPLE_GRID_PROPS} />
|
||||
<Grid
|
||||
matrix={getMatrix(
|
||||
EXAMPLE_GRID_PROPS.dim,
|
||||
EXAMPLE_GRID_PROPS.edges,
|
||||
EXAMPLE_GRID_PROPS.numbers
|
||||
)}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.item}>
|
||||
Crossovers or branches are not allowed (as shown by dotted lines
|
||||
below).
|
||||
<div className={styles.eg}>
|
||||
<Grid {...NOT_ALLOWED_1_GRID_PROPS} />
|
||||
<Grid {...NOT_ALLOWED_2_GRID_PROPS} />
|
||||
<Grid
|
||||
matrix={getMatrix(
|
||||
NOT_ALLOWED_1_GRID_PROPS.dim,
|
||||
NOT_ALLOWED_1_GRID_PROPS.edges,
|
||||
NOT_ALLOWED_1_GRID_PROPS.numbers
|
||||
)}
|
||||
readOnly
|
||||
/>
|
||||
<Grid
|
||||
matrix={getMatrix(
|
||||
NOT_ALLOWED_2_GRID_PROPS.dim,
|
||||
NOT_ALLOWED_2_GRID_PROPS.edges,
|
||||
NOT_ALLOWED_2_GRID_PROPS.numbers
|
||||
)}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.item}>
|
||||
|
||||
@@ -2,31 +2,46 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.button {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
.container {
|
||||
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%;
|
||||
flex-direction: column;
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
gap: 2px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
font-style: italic;
|
||||
|
||||
.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 {
|
||||
border-color: #78909c;
|
||||
font-size: 22px;
|
||||
transform: scale(1.1);
|
||||
color: white;
|
||||
|
||||
.button {
|
||||
border-color: #78909c;
|
||||
font-size: 22px;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ export const EDGE_STATE = {
|
||||
};
|
||||
|
||||
export const EXAMPLE_GRID_PROPS = {
|
||||
readOnly: true,
|
||||
dim: [7, 7],
|
||||
edges: [
|
||||
{a: [0, 0], b: [0, 1]},
|
||||
@@ -135,7 +134,6 @@ export const EXAMPLE_GRID_PROPS = {
|
||||
};
|
||||
|
||||
export const NOT_ALLOWED_1_GRID_PROPS = {
|
||||
readOnly: true,
|
||||
dim: [2, 2],
|
||||
edges: [
|
||||
{a: [0, 1], b: [1, 1], hovered: true},
|
||||
@@ -147,7 +145,6 @@ export const NOT_ALLOWED_1_GRID_PROPS = {
|
||||
};
|
||||
|
||||
export const NOT_ALLOWED_2_GRID_PROPS = {
|
||||
readOnly: true,
|
||||
dim: [2, 3],
|
||||
edges: [
|
||||
{a: [0, 1], b: [1, 1]},
|
||||
|
||||
@@ -11,9 +11,3 @@ code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
||||
body, html, #root {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {DEFAULT_NODE} from "./components/Grid";
|
||||
import {EDGE_STATE} from "./constants";
|
||||
|
||||
// to get multiple styles in space-seperated format
|
||||
@@ -18,6 +19,88 @@ 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) &&
|
||||
|
||||
Reference in New Issue
Block a user