diff --git a/src/components/Controls/index.js b/src/components/Controls/index.js
index b679069..01b6e08 100644
--- a/src/components/Controls/index.js
+++ b/src/components/Controls/index.js
@@ -1,11 +1,12 @@
import * as React from "react";
import AddPuzzleScreen from "../AddPuzzleScreen";
-import {Plus, Refresh, Reset} from "../Icons";
+import {Plus, Redo, Refresh, Reset, Undo} from "../Icons";
import styles from "./styles.module.scss";
-const Controls = ({onRefresh, onReset, editorMode}) => {
+const Controls = ({onRefresh, onReset, onUndo, onRedo, editorMode}) => {
const [showAddScreen, setShowAddScreen] = React.useState(false);
+
return (
<>
@@ -19,6 +20,14 @@ const Controls = ({onRefresh, onReset, editorMode}) => {
Reset
+
+
+ Undo
+
+
+
+ Redo
+
{!editorMode && (
setShowAddScreen(true)}>
diff --git a/src/components/Game/index.js b/src/components/Game/index.js
index 07b6fb1..39fb871 100644
--- a/src/components/Game/index.js
+++ b/src/components/Game/index.js
@@ -1,6 +1,6 @@
import * as React from "react";
import {examples} from "../../examples";
-import {getMatrix} from "../../utils";
+import {copy, getEdges, getMatrix} from "../../utils";
import CheckSolution from "../CheckSolution";
import Controls from "../Controls";
import Grid from "../Grid";
@@ -13,18 +13,55 @@ const Game = () => {
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) {
- setMatrix(getMatrix(dim, [], numbers));
+ 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) {
- setMatrix(getMatrix(dim, [], numbers));
+ // if matrix already empty
+ if (getEdges(matrix).length === 0) {
+ return;
+ }
+ updateMatrix(getMatrix(dim, [], numbers));
}
};
@@ -38,10 +75,15 @@ const Game = () => {
Slither
Link
-
+
-
+
);
};
diff --git a/src/utils.js b/src/utils.js
index 0ea4c16..cd8f091 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,6 +1,9 @@
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