From e4dc8b72c9d6b16e32bf1acbde8704b002ba6985 Mon Sep 17 00:00:00 2001 From: Pavel Keyzik Date: Mon, 30 Sep 2019 20:32:42 +0300 Subject: [PATCH 1/4] Changed class component to functional inside Game.js file --- package-lock.json | 581 ++++++++++++++++++++++++++++++++++++++++------ package.json | 4 +- src/Game.js | 457 +++++++++++++++++++----------------- 3 files changed, 760 insertions(+), 282 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ccaf29..292c07c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1685,6 +1685,7 @@ "anymatch": "^2.0.0", "async-each": "^1.0.0", "braces": "^2.3.0", + "fsevents": "^1.2.2", "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", @@ -2309,11 +2310,6 @@ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -3037,14 +3033,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, "enhanced-resolve": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", @@ -3760,20 +3748,6 @@ "bser": "^2.0.0" } }, - "fbjs": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", - "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.18" - } - }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -3958,6 +3932,487 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "optional": true + } + } + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -4935,15 +5390,6 @@ "isarray": "1.0.0" } }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -5946,6 +6392,12 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -6009,15 +6461,6 @@ "lower-case": "^1.1.1" } }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", @@ -7761,14 +8204,6 @@ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==" }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "~2.0.3" - } - }, "prop-types": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", @@ -7946,14 +8381,13 @@ } }, "react": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/react/-/react-16.4.2.tgz", - "integrity": "sha512-dMv7YrbxO4y2aqnvA7f/ik9ibeLSHQJTI6TrYAenPSaQ6OXfb+Oti+oJiy8WBxgRzlKatYqtCjphTgDSCEiWFg==", + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.10.1.tgz", + "integrity": "sha512-2bisHwMhxQ3XQz4LiJJwG3360pY965pTl/MRrZYxIBKVj4fOHoDs5aZAkYXGxDRO1Li+SyjTAilQEbOmtQJHzA==", "requires": { - "fbjs": "^0.8.16", "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.0" + "prop-types": "^15.6.2" } }, "react-dev-utils": { @@ -7982,14 +8416,14 @@ } }, "react-dom": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.4.2.tgz", - "integrity": "sha512-Usl73nQqzvmJN+89r97zmeUpQDKDlh58eX6Hbs/ERdDHzeBzWy+ENk7fsGQ+5KxArV1iOFPT46/VneklK9zoWw==", + "version": "16.10.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.10.1.tgz", + "integrity": "sha512-SmM4ZW0uug0rn95U8uqr52I7UdNf6wdGLeXDmNLfg3y5q5H9eAbdjF5ubQc3bjDyRrvdAB2IKG7X0GzSpnn5Mg==", "requires": { - "fbjs": "^0.8.16", "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.0" + "prop-types": "^15.6.2", + "scheduler": "^0.16.1" } }, "react-error-overlay": { @@ -8024,6 +8458,7 @@ "extract-text-webpack-plugin": "3.0.2", "file-loader": "1.1.5", "fs-extra": "3.0.1", + "fsevents": "^1.1.3", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", "object-assign": "4.1.1", @@ -8778,6 +9213,15 @@ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, + "scheduler": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.1.tgz", + "integrity": "sha512-MIuie7SgsqMYOdCXVFZa8SKoNorJZUWHW8dPgto7uEHn1lX3fg2Gu0TzgK8USj76uxV7vB5eRMnZs/cdEHg+cg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", @@ -9676,11 +10120,6 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, - "ua-parser-js": { - "version": "0.7.19", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz", - "integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ==" - }, "uglify-js": { "version": "3.4.9", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", @@ -10276,6 +10715,7 @@ "requires": { "anymatch": "^1.3.0", "async-each": "^1.0.0", + "fsevents": "^1.0.0", "glob-parent": "^2.0.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", @@ -10485,11 +10925,6 @@ "iconv-lite": "0.4.24" } }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" - }, "whatwg-url": { "version": "4.8.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", diff --git a/package.json b/package.json index 7c3a226..52036ac 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ ], "main": "src/index.js", "dependencies": { - "react": "16.4.2", - "react-dom": "16.4.2", + "react": "^16.10.1", + "react-dom": "^16.10.1", "react-scripts": "1.1.4", "react-testing-library": "5.2.1" }, diff --git a/src/Game.js b/src/Game.js index 81ed9a9..96e5239 100644 --- a/src/Game.js +++ b/src/Game.js @@ -1,35 +1,29 @@ -import React, { Component, createRef } from "react"; +import React, { useState, useEffect, useCallback, useRef } from "react"; -class Game extends Component { - constructor(props) { - super(props); - const { boardSizeX, boardSizeY } = props; - this.spritesPos = this.generateSpritesPos(boardSizeX, boardSizeY); - this.moves = 0; // please check readme - this.remainingSprites = boardSizeY; - this.boardRef = createRef(); - // initially user is placed in center - this.state = { - userPos: { - x: Math.floor(boardSizeX / 2), - y: Math.floor(boardSizeY / 2) - }, - hasFinished: false - }; - } +function Game({ boardSizeX, boardSizeY }) { + const [spritesPos] = useState(generateSpritesPos(boardSizeX, boardSizeY)); + const [moves, setMoves] = useState(0); // please check readme + // initially user is placed in center + const [userPos, setUserPos] = useState({ + x: Math.floor(boardSizeX / 2), + y: Math.floor(boardSizeY / 2) + }); + const [hasFinished, setHasFinished] = useState(false); + const boardRef = useRef(); + let remainingSprites = boardSizeY; - componentDidMount() { - this.focusBoard(); - } + useEffect(() => { + focusBoard(); + }, []); - focusBoard() { - const boardRef = this.boardRef.current; - if(boardRef) { - boardRef.focus(); + const focusBoard = () => { + const boardRefElement = boardRef.current; + if (boardRefElement) { + boardRefElement.focus(); } - } + }; - generateSpritesPos(boardSizeX, boardSizeY) { + function generateSpritesPos(boardSizeX, boardSizeY) { const spritesPos = []; for (let i = 0; i < boardSizeY; i += 1) { const spritePos = Math.floor(Math.random() * boardSizeX); @@ -40,217 +34,266 @@ class Game extends Component { return spritesPos; } - updateMove({ x, y }) { - if (this.spritesPos[y] === x) { - this.spritesPos[y] = -1; - this.remainingSprites -= 1; - } + const updateMove = useCallback( + ({ x, y }) => { + if (spritesPos[y] === x) { + spritesPos[y] = -1; + remainingSprites -= 1; + } - const hasFinished = this.remainingSprites === 0; + const hasFinishedAfterMove = remainingSprites === 0; - if (!this.state.hasFinished && hasFinished) { - this.setState({ - hasFinished: true - }); - } - } + if (!hasFinished && hasFinishedAfterMove) { + setHasFinished(true); + } + }, + [spritesPos] + ); - moveUp = ({ userPos }) => { - const userPosY = userPos.y; - let newY; + const moveUp = useCallback( + userPos => { + const userPosY = userPos.y; + let newY; - if (userPosY > 0) { - newY = userPosY - 1; - this.moves += 1; - } else { - newY = userPosY; - } + if (userPosY > 0) { + newY = userPosY - 1; + setMoves(moves + 1); + } else { + newY = userPosY; + } - const newUserPos = { - x: userPos.x, - y: newY - }; + const newUserPos = { + x: userPos.x, + y: newY + }; - return { - userPos: newUserPos - }; - }; + return { + userPos: newUserPos + }; + }, + [moves] + ); - moveDown = ({ userPos }) => { - const userPosY = userPos.y; - let newY; - const { boardSizeY } = this.props; + const moveDown = useCallback( + userPos => { + const userPosY = userPos.y; + let newY; - if (userPosY < boardSizeY - 1) { - newY = userPosY + 1; - this.moves += 1; - } else { - newY = userPosY; - } + if (userPosY < boardSizeY - 1) { + newY = userPosY + 1; + setMoves(moves + 1); + } else { + newY = userPosY; + } - const newUserPos = { - x: userPos.x, - y: newY - }; + const newUserPos = { + x: userPos.x, + y: newY + }; - return { - userPos: newUserPos - }; - }; + return { + userPos: newUserPos + }; + }, + [moves] + ); - moveLeft = ({ userPos }) => { - const userPosX = userPos.x; - let newX; + const moveLeft = useCallback( + userPos => { + const userPosX = userPos.x; + let newX; - if (userPosX > 0) { - newX = userPosX - 1; - this.moves += 1; - } else { - newX = userPosX; - } + if (userPosX > 0) { + newX = userPosX - 1; + setMoves(moves + 1); + } else { + newX = userPosX; + } - const newUserPos = { - x: newX, - y: userPos.y - }; + const newUserPos = { + x: newX, + y: userPos.y + }; - return { - userPos: newUserPos - }; - }; + return { + userPos: newUserPos + }; + }, + [moves] + ); - moveRight = ({ userPos }) => { - const userPosX = userPos.x; - let newX; - const { boardSizeX } = this.props; + const moveRight = useCallback( + userPos => { + const userPosX = userPos.x; + let newX; - if (userPosX < boardSizeX - 1) { - newX = userPosX + 1; - this.moves += 1; - } else { - newX = userPosX; - } + if (userPosX < boardSizeX - 1) { + newX = userPosX + 1; + setMoves(moves + 1); + } else { + newX = userPosX; + } - const newUserPos = { - x: newX, - y: userPos.y - }; + const newUserPos = { + x: newX, + y: userPos.y + }; - return { - userPos: newUserPos - }; - }; + return { + userPos: newUserPos + }; + }, + [moves] + ); - handleGameClick = () => { - this.focusBoard(); - } + const handleGameClick = () => { + focusBoard(); + }; - keyAndClickHandler = event => { + const keyAndClickHandler = event => { const { key } = event; const arrowMapping = { - ArrowLeft: this.moveLeft, - ArrowRight: this.moveRight, - ArrowUp: this.moveUp, - ArrowDown: this.moveDown + ArrowLeft: moveLeft, + ArrowRight: moveRight, + ArrowUp: moveUp, + ArrowDown: moveDown }; const stateUpdater = arrowMapping[key]; - this.setState(stateUpdater, () => this.updateMove(this.state.userPos)); - } - renderBoard(boardSizeX, boardSizeY) { - const { - userPos: { x: userPosX, y: userPosY } - } = this.state; - const markup = []; - for (let i = 0; i < boardSizeY; i++) { - const rowInnerMarkup = []; - for (let j = 0; j < boardSizeX; j++) { - const classList = ["board-cell"]; - if (userPosY === i && userPosX === j) { - classList.push("has-user"); - } else if (this.spritesPos[i] === j) { - classList.push("has-sprite"); - const spriteType = j % 3 + 1; - classList.push(`sprite-${spriteType}`); - } + if (stateUpdater) { + const { userPos: updatedUserPos } = stateUpdater(userPos); + setUserPos(updatedUserPos); + updateMove(updatedUserPos); + } + }; - const className = classList.join(" "); - rowInnerMarkup.push(); + const renderBoard = useCallback( + (boardSizeX, boardSizeY) => { + const { x: userPosX, y: userPosY } = userPos; + const markup = []; + for (let i = 0; i < boardSizeY; i++) { + const rowInnerMarkup = []; + for (let j = 0; j < boardSizeX; j++) { + const classList = ["board-cell"]; + if (userPosY === i && userPosX === j) { + classList.push("has-user"); + } else if (spritesPos[i] === j) { + classList.push("has-sprite"); + const spriteType = (j % 3) + 1; + classList.push(`sprite-${spriteType}`); + } + + const className = classList.join(" "); + rowInnerMarkup.push(); + } + const rowMarkup = {rowInnerMarkup}; + markup.push(rowMarkup); } - const rowMarkup = {rowInnerMarkup}; - markup.push(rowMarkup); - } - return markup; - } + return markup; + }, + [userPos, spritesPos] + ); - render() { - const { boardSizeX, boardSizeY } = this.props; - return ( -
- {this.state.hasFinished ? ( + return ( +
+ {hasFinished ? ( +

+ Took   + {moves} +   moves +
+
+ Refresh page to play again +

+ ) : ( +
+ + {renderBoard(boardSizeX, boardSizeY)} +

- Took   - {this.moves} -   moves -
-
- Refresh page to play again + Moves so far   + {moves}

- ) : ( -
- +
-

- Moves so far -   - {this.moves} -

-
- - - - -
-
- )} -
- ); - } + + + + + + + + + + )} +
+ ); } export { Game }; From 35fb7cfa693556bcd94cf9d9e4fa726ec7d13349 Mon Sep 17 00:00:00 2001 From: Pavel Keyzik Date: Tue, 1 Oct 2019 10:42:52 +0300 Subject: [PATCH 2/4] Call generate sprites pos only after init component --- src/Game.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Game.js b/src/Game.js index 96e5239..e361ae0 100644 --- a/src/Game.js +++ b/src/Game.js @@ -1,7 +1,9 @@ import React, { useState, useEffect, useCallback, useRef } from "react"; function Game({ boardSizeX, boardSizeY }) { - const [spritesPos] = useState(generateSpritesPos(boardSizeX, boardSizeY)); + const [spritesPos] = useState(() => + generateSpritesPos(boardSizeX, boardSizeY) + ); const [moves, setMoves] = useState(0); // please check readme // initially user is placed in center const [userPos, setUserPos] = useState({ From 790bc37f1ed3398fe8b7a1c3c33d2ccd9368d8be Mon Sep 17 00:00:00 2001 From: Pavel Keyzik Date: Wed, 2 Oct 2019 12:57:23 +0300 Subject: [PATCH 3/4] Removed useCallback for moves functions --- src/Game.js | 148 ++++++++++++++++++++++++---------------------------- 1 file changed, 68 insertions(+), 80 deletions(-) diff --git a/src/Game.js b/src/Game.js index e361ae0..ea6fc43 100644 --- a/src/Game.js +++ b/src/Game.js @@ -52,101 +52,89 @@ function Game({ boardSizeX, boardSizeY }) { [spritesPos] ); - const moveUp = useCallback( - userPos => { - const userPosY = userPos.y; - let newY; + const moveUp = userPos => { + const userPosY = userPos.y; + let newY; - if (userPosY > 0) { - newY = userPosY - 1; - setMoves(moves + 1); - } else { - newY = userPosY; - } + if (userPosY > 0) { + newY = userPosY - 1; + setMoves(moves => moves + 1); + } else { + newY = userPosY; + } - const newUserPos = { - x: userPos.x, - y: newY - }; + const newUserPos = { + x: userPos.x, + y: newY + }; - return { - userPos: newUserPos - }; - }, - [moves] - ); + return { + userPos: newUserPos + }; + }; - const moveDown = useCallback( - userPos => { - const userPosY = userPos.y; - let newY; + const moveDown = userPos => { + const userPosY = userPos.y; + let newY; - if (userPosY < boardSizeY - 1) { - newY = userPosY + 1; - setMoves(moves + 1); - } else { - newY = userPosY; - } + if (userPosY < boardSizeY - 1) { + newY = userPosY + 1; + setMoves(moves => moves + 1); + } else { + newY = userPosY; + } - const newUserPos = { - x: userPos.x, - y: newY - }; + const newUserPos = { + x: userPos.x, + y: newY + }; - return { - userPos: newUserPos - }; - }, - [moves] - ); + return { + userPos: newUserPos + }; + }; - const moveLeft = useCallback( - userPos => { - const userPosX = userPos.x; - let newX; + const moveLeft = userPos => { + const userPosX = userPos.x; + let newX; - if (userPosX > 0) { - newX = userPosX - 1; - setMoves(moves + 1); - } else { - newX = userPosX; - } + if (userPosX > 0) { + newX = userPosX - 1; + setMoves(moves => moves + 1); + } else { + newX = userPosX; + } - const newUserPos = { - x: newX, - y: userPos.y - }; + const newUserPos = { + x: newX, + y: userPos.y + }; - return { - userPos: newUserPos - }; - }, - [moves] - ); + return { + userPos: newUserPos + }; + }; - const moveRight = useCallback( - userPos => { - const userPosX = userPos.x; - let newX; + const moveRight = userPos => { + const userPosX = userPos.x; + let newX; - if (userPosX < boardSizeX - 1) { - newX = userPosX + 1; - setMoves(moves + 1); - } else { - newX = userPosX; - } + if (userPosX < boardSizeX - 1) { + newX = userPosX + 1; + setMoves(moves => moves + 1); + } else { + newX = userPosX; + } - const newUserPos = { - x: newX, - y: userPos.y - }; + const newUserPos = { + x: newX, + y: userPos.y + }; - return { - userPos: newUserPos - }; - }, - [moves] - ); + return { + userPos: newUserPos + }; + }; const handleGameClick = () => { focusBoard(); From af32f9ec32e77cb22fc2a114a7aff6c38920a3fd Mon Sep 17 00:00:00 2001 From: Pavel Keyzik Date: Wed, 2 Oct 2019 13:21:13 +0300 Subject: [PATCH 4/4] Moved SVG icons to variable --- src/Game.js | 68 +++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/Game.js b/src/Game.js index ea6fc43..7aad28a 100644 --- a/src/Game.js +++ b/src/Game.js @@ -1,5 +1,33 @@ import React, { useState, useEffect, useCallback, useRef } from "react"; +const upArrow = ( + + + + +); + +const rightArrow = ( + + + + +); + +const leftArrow = ( + + + + +); + +const downArrow = ( + + + + +); + function Game({ boardSizeX, boardSizeY }) { const [spritesPos] = useState(() => generateSpritesPos(boardSizeX, boardSizeY) @@ -218,15 +246,7 @@ function Game({ boardSizeX, boardSizeY }) { keyAndClickHandler(event); }} > - - - - + {upArrow}