From 3f50b68d656f445eccb374a47ce72b3510f72aa9 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Thu, 3 Jun 2021 20:57:59 +0900 Subject: [PATCH 01/70] =?UTF-8?q?feat:=20=EA=B0=9C=EB=B0=9C=ED=99=98?= =?UTF-8?q?=EA=B2=BD=20=EC=84=B8=ED=8C=85(eslint,=20prettier)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress.json | 1 + package.json | 19 +++++++++++ src/constants/index.js | 0 tsconfig.json | 72 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+) create mode 100644 cypress.json create mode 100644 package.json create mode 100644 src/constants/index.js create mode 100644 tsconfig.json diff --git a/cypress.json b/cypress.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/cypress.json @@ -0,0 +1 @@ +{} diff --git a/package.json b/package.json new file mode 100644 index 000000000..98b705ac2 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "dependencies": { + "cypress": "^7.4.0", + "typescript": "^4.3.2" + }, + "name": "javascript-racingcar", + "version": "1.0.0", + "main": "index.js", + "repository": "https://github.com/jwon42/javascript-racingcar.git", + "author": "jwon42 ", + "license": "MIT", + "devDependencies": { + "@typescript-eslint/eslint-plugin": "^4.26.0", + "@typescript-eslint/parser": "^4.26.0", + "eslint": "^7.27.0", + "eslint-config-airbnb-base": "^14.2.1", + "eslint-plugin-import": "^2.23.4" + } +} diff --git a/src/constants/index.js b/src/constants/index.js new file mode 100644 index 000000000..e69de29bb diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..9cb0b440f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,72 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ + + /* Module Resolution Options */ + // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + "types": ["cypress"], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } +} From 2007e09f4f0aee35e520d8c9eef1b2c1e116d58f Mon Sep 17 00:00:00 2001 From: jwon42 Date: Thu, 3 Jun 2021 20:59:21 +0900 Subject: [PATCH 02/70] =?UTF-8?q?feat:=20Car=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/car.js | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/model/car.js diff --git a/src/model/car.js b/src/model/car.js new file mode 100644 index 000000000..ae3b8e168 --- /dev/null +++ b/src/model/car.js @@ -0,0 +1,10 @@ +export default class Car { + constructor(name) { + this.name = name; + this.position = 0; + } + + moveForward() { + this.position += 1; + } + } From dee9627cf9c7322c29203eed940a3090a78e0133 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 17:41:18 +0900 Subject: [PATCH 03/70] =?UTF-8?q?feat:=20=ED=85=9C=ED=94=8C=EB=A6=BF,=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=9F=AC=20=EC=84=A4=EA=B3=84=20=ED=9B=84=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 23 ++++++++++++++++++ .gitignore | 3 +++ .prettierrc | 5 ++++ src/constants/{index.js => index.ts} | 0 src/controller/validtor.ts | 0 src/index.ts | 1 + src/model/car.js | 10 -------- src/model/car.ts | 13 +++++++++++ src/view/renderer.ts | 21 +++++++++++++++++ src/view/templates/index.ts | 5 ++++ src/view/templates/input-section.ts | 28 ++++++++++++++++++++++ src/view/templates/progress-section.ts | 32 ++++++++++++++++++++++++++ src/view/templates/result-section.ts | 14 +++++++++++ 13 files changed, 145 insertions(+), 10 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .prettierrc rename src/constants/{index.js => index.ts} (100%) create mode 100644 src/controller/validtor.ts create mode 100644 src/index.ts delete mode 100644 src/model/car.js create mode 100644 src/model/car.ts create mode 100644 src/view/renderer.ts create mode 100644 src/view/templates/index.ts create mode 100644 src/view/templates/input-section.ts create mode 100644 src/view/templates/progress-section.ts create mode 100644 src/view/templates/result-section.ts diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..e431fdea7 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + env: { + browser: true, + es2021: true, + }, + extends: [ + 'airbnb-base', + ], + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 12, + sourceType: 'module', + }, + plugins: [ + '@typescript-eslint', + ], + rules: { + }, + ignorePattern: [ + 'dist/', + 'node_modules/', + ], +}; diff --git a/.gitignore b/.gitignore index 882ea6b5d..6ac8f096f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +package-lock.json +yarn.lock + # Created by https://www.toptal.com/developers/gitignore/api/node,vscode,intellij,webstorm # Edit at https://www.toptal.com/developers/gitignore?templates=node,vscode,intellij,webstorm diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..9499f6cf6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "printWidth": 120 + } \ No newline at end of file diff --git a/src/constants/index.js b/src/constants/index.ts similarity index 100% rename from src/constants/index.js rename to src/constants/index.ts diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts new file mode 100644 index 000000000..e69de29bb diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..c9c1fdc45 --- /dev/null +++ b/src/index.ts @@ -0,0 +1 @@ +const app = (): void => {}; diff --git a/src/model/car.js b/src/model/car.js deleted file mode 100644 index ae3b8e168..000000000 --- a/src/model/car.js +++ /dev/null @@ -1,10 +0,0 @@ -export default class Car { - constructor(name) { - this.name = name; - this.position = 0; - } - - moveForward() { - this.position += 1; - } - } diff --git a/src/model/car.ts b/src/model/car.ts new file mode 100644 index 000000000..c0982a46b --- /dev/null +++ b/src/model/car.ts @@ -0,0 +1,13 @@ +export default class Car { + name: string; + position: number; + + constructor(name: string) { + this.name = name; + this.position = 0; + } + + moveForward(): void { + this.position += 1; + } +} diff --git a/src/view/renderer.ts b/src/view/renderer.ts new file mode 100644 index 000000000..6ff4e6903 --- /dev/null +++ b/src/view/renderer.ts @@ -0,0 +1,21 @@ +import { inputSection, progressSection, resultSection } from './templates/index.js'; + +const renderInputSection = (): void => { + document.getElementById('app')!.innerHTML = inputSection(); +}; + +const renderProgressSection = (): void => { + document.getElementById('app')!.insertAdjacentHTML(`beforeend`, progressSection()); +}; + +const renderCarNameDiv = (name: string): void => {}; + +const renderArrowDiv = (): void => {}; + +const renderSpinnerDiv = (): void => {}; + +const renderResultSection = (winners: string): void => { + document.getElementById('app')!.insertAdjacentHTML(`beforeend`, resultSection(winners)); +}; + +export { renderInputSection, renderProgressSection, renderResultSection }; diff --git a/src/view/templates/index.ts b/src/view/templates/index.ts new file mode 100644 index 000000000..172491b80 --- /dev/null +++ b/src/view/templates/index.ts @@ -0,0 +1,5 @@ +export { inputSection } from './input-section.js'; + +export { progressSection, carNameDiv, arrowDiv, spinnerDiv } from './progress-section.js'; + +export { resultSection } from './result-section.js'; diff --git a/src/view/templates/input-section.ts b/src/view/templates/input-section.ts new file mode 100644 index 000000000..102c4cab0 --- /dev/null +++ b/src/view/templates/input-section.ts @@ -0,0 +1,28 @@ +const inputSection = (): string => { + return ` +
+
+
+

🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„

+

+ 5자 μ΄ν•˜μ˜ μžλ™μ°¨ 이름을 콀마둜 κ΅¬λΆ„ν•˜μ—¬ μž…λ ₯ν•΄μ£Όμ„Έμš”.
+ μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH +

+
+ + +
+
+
+

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

+
+ + +
+
+
+
+ `; +} + +export { inputSection }; \ No newline at end of file diff --git a/src/view/templates/progress-section.ts b/src/view/templates/progress-section.ts new file mode 100644 index 000000000..a70b784a3 --- /dev/null +++ b/src/view/templates/progress-section.ts @@ -0,0 +1,32 @@ +const progressSection = (): string => { + return ` +
+
+
+
+ `; +} + +const carNameDiv = (name: string): string => { + return ` +
+
${name}
+
+ ` +} + +const arrowDiv = (): string => { + return ` +
⬇️️
+ ` +} + +const spinnerDiv = (): string => { + return ` +
+ +
+ ` +} + +export { progressSection, carNameDiv, arrowDiv, spinnerDiv }; \ No newline at end of file diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts new file mode 100644 index 000000000..6a8997a0a --- /dev/null +++ b/src/view/templates/result-section.ts @@ -0,0 +1,14 @@ +const resultSection = (winners: string): string => { + return ` +
+
+

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

+
+ +
+
+
+ `; +} + +export { resultSection }; \ No newline at end of file From 56ff4abaa0a39691ad61d1956ca5fe0da2c6dc1b Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 17:54:11 +0900 Subject: [PATCH 04/70] =?UTF-8?q?feat:=20=ED=85=9C=ED=94=8C=EB=A6=BF,=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=9F=AC=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .prettierrc | 1 + index.html | 62 +--------------------- index.html.backup | 71 ++++++++++++++++++++++++++ src/index.ts | 6 ++- src/view/templates/index.ts | 5 -- src/view/templates/input-section.ts | 2 +- src/view/templates/progress-section.ts | 2 +- src/view/templates/result-section.ts | 2 +- tsconfig.json | 16 ++++-- 9 files changed, 93 insertions(+), 74 deletions(-) create mode 100644 index.html.backup diff --git a/.prettierrc b/.prettierrc index 9499f6cf6..dd75ac73f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { + "parser": "typescript", "singleQuote": true, "trailingComma": "all", "printWidth": 120 diff --git a/index.html b/index.html index ea5891942..846cbd5b4 100644 --- a/index.html +++ b/index.html @@ -3,69 +3,11 @@ 🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„ - +
-
-
-
-

🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„

-

- 5자 μ΄ν•˜μ˜ μžλ™μ°¨ 이름을 콀마둜 κ΅¬λΆ„ν•˜μ—¬ μž…λ ₯ν•΄μ£Όμ„Έμš”.
- μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH -

-
- - -
-
-
-

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

-
- - -
-
-
-
-
-
-
-
EAST
-
⬇️️
-
⬇️️
-
-
-
WEST
-
⬇️️
-
-
-
SOUTH
-
-
- -
-
-
-
-
NORTH
-
-
- -
-
-
-
-
-
-
-

πŸ† μ΅œμ’… 우승자: EAST, WEST πŸ†

-
- -
-
-
+ diff --git a/index.html.backup b/index.html.backup new file mode 100644 index 000000000..ea5891942 --- /dev/null +++ b/index.html.backup @@ -0,0 +1,71 @@ + + + + + 🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„ + + + +
+
+
+
+

🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„

+

+ 5자 μ΄ν•˜μ˜ μžλ™μ°¨ 이름을 콀마둜 κ΅¬λΆ„ν•˜μ—¬ μž…λ ₯ν•΄μ£Όμ„Έμš”.
+ μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH +

+
+ + +
+
+
+

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

+
+ + +
+
+
+
+
+
+
+
EAST
+
⬇️️
+
⬇️️
+
+
+
WEST
+
⬇️️
+
+
+
SOUTH
+
+
+ +
+
+
+
+
NORTH
+
+
+ +
+
+
+
+
+
+
+

πŸ† μ΅œμ’… 우승자: EAST, WEST πŸ†

+
+ +
+
+
+
+ + diff --git a/src/index.ts b/src/index.ts index c9c1fdc45..603e9f132 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,5 @@ -const app = (): void => {}; +const app = (): void => { + console.log('ho'); +}; + +app(); diff --git a/src/view/templates/index.ts b/src/view/templates/index.ts index 172491b80..e69de29bb 100644 --- a/src/view/templates/index.ts +++ b/src/view/templates/index.ts @@ -1,5 +0,0 @@ -export { inputSection } from './input-section.js'; - -export { progressSection, carNameDiv, arrowDiv, spinnerDiv } from './progress-section.js'; - -export { resultSection } from './result-section.js'; diff --git a/src/view/templates/input-section.ts b/src/view/templates/input-section.ts index 102c4cab0..5838a43a6 100644 --- a/src/view/templates/input-section.ts +++ b/src/view/templates/input-section.ts @@ -25,4 +25,4 @@ const inputSection = (): string => { `; } -export { inputSection }; \ No newline at end of file +export { inputSection }; diff --git a/src/view/templates/progress-section.ts b/src/view/templates/progress-section.ts index a70b784a3..fa4363942 100644 --- a/src/view/templates/progress-section.ts +++ b/src/view/templates/progress-section.ts @@ -29,4 +29,4 @@ const spinnerDiv = (): string => { ` } -export { progressSection, carNameDiv, arrowDiv, spinnerDiv }; \ No newline at end of file +export { progressSection, carNameDiv, arrowDiv, spinnerDiv }; diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts index 6a8997a0a..ac0ae594c 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/templates/result-section.ts @@ -11,4 +11,4 @@ const resultSection = (winners: string): string => { `; } -export { resultSection }; \ No newline at end of file +export { resultSection }; diff --git a/tsconfig.json b/tsconfig.json index 9cb0b440f..7e6a5a9ba 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,17 @@ { + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules" + ], "compilerOptions": { /* Visit https://aka.ms/tsconfig.json to read more about this file */ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ + // "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ @@ -14,8 +20,8 @@ // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + "rootDir": "./src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ // "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ @@ -49,7 +55,7 @@ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ - "types": ["cypress"], /* Type declaration files to be included in compilation. */ + // "types": ["cypress"], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ From c6b6fdb5cb2b13c1b70a88b1cea428f70d481538 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 17:55:29 +0900 Subject: [PATCH 05/70] =?UTF-8?q?feat:=20=ED=85=9C=ED=94=8C=EB=A6=BF,=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=9F=AC=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/templates/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/view/templates/index.ts b/src/view/templates/index.ts index e69de29bb..e828e774f 100644 --- a/src/view/templates/index.ts +++ b/src/view/templates/index.ts @@ -0,0 +1,5 @@ +export { inputSection } from './input-section.js'; + +export { progressSection, carNameDiv, arrowDiv, spinnerDiv } from './progress-section.js'; + +export { resultSection } from './result-section.js'; \ No newline at end of file From c12581e925a37b4797b91724710f2d4a8c4085df Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 18:29:26 +0900 Subject: [PATCH 06/70] =?UTF-8?q?feat:=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/event.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/controller/event.ts diff --git a/src/controller/event.ts b/src/controller/event.ts new file mode 100644 index 000000000..2d53c1eae --- /dev/null +++ b/src/controller/event.ts @@ -0,0 +1,6 @@ +const setEventListener = (): void => { + document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); + document.getElementById('racing-count-submit')!.addEventListener('click', () => getCount()); +}; + +export { setEventListener }; From 488e51baf390cc669c788973c70709e69ce0a9f8 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 18:30:24 +0900 Subject: [PATCH 07/70] =?UTF-8?q?feat:=20input,=20button=EC=97=90=20id=20?= =?UTF-8?q?=EA=B0=92=20=EB=B0=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/templates/input-section.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/view/templates/input-section.ts b/src/view/templates/input-section.ts index 5838a43a6..6690a5a53 100644 --- a/src/view/templates/input-section.ts +++ b/src/view/templates/input-section.ts @@ -9,15 +9,15 @@ const inputSection = (): string => { μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH

- - + +

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

- - + +
From 0758455cd2069c6214a713c38efec348bc67aac5 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 20:42:58 +0900 Subject: [PATCH 08/70] =?UTF-8?q?feat:=20section=20id=20=EB=B0=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/templates/input-section.ts | 2 +- src/view/templates/progress-section.ts | 2 +- src/view/templates/result-section.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/view/templates/input-section.ts b/src/view/templates/input-section.ts index 6690a5a53..87a9884c4 100644 --- a/src/view/templates/input-section.ts +++ b/src/view/templates/input-section.ts @@ -1,6 +1,6 @@ const inputSection = (): string => { return ` -
+

🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„

diff --git a/src/view/templates/progress-section.ts b/src/view/templates/progress-section.ts index fa4363942..ac192ad9d 100644 --- a/src/view/templates/progress-section.ts +++ b/src/view/templates/progress-section.ts @@ -1,6 +1,6 @@ const progressSection = (): string => { return ` -
+
diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts index ac0ae594c..f44034aa1 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/templates/result-section.ts @@ -1,6 +1,6 @@ const resultSection = (winners: string): string => { return ` -
+

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

From fa41e63bd5db3f04a91638be7800d5c63bbf0c76 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 21:12:58 +0900 Subject: [PATCH 09/70] =?UTF-8?q?feat:=20game=20class=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/car.ts | 4 ++- src/model/game.ts | 67 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/model/game.ts diff --git a/src/model/car.ts b/src/model/car.ts index c0982a46b..0c4327e86 100644 --- a/src/model/car.ts +++ b/src/model/car.ts @@ -1,4 +1,4 @@ -export default class Car { +class Car { name: string; position: number; @@ -11,3 +11,5 @@ export default class Car { this.position += 1; } } + +export { Car }; \ No newline at end of file diff --git a/src/model/game.ts b/src/model/game.ts new file mode 100644 index 000000000..52a7b9e93 --- /dev/null +++ b/src/model/game.ts @@ -0,0 +1,67 @@ +import { Car } from './car'; + +class Game { + cars: Array; + winners: Array; + tryCount: number; + maxPosition: number; + + constructor(cars: Array, tryCount: number) { + this.cars = cars; + this.winners = []; + this.tryCount = tryCount; + this.maxPosition = 0; + } + + playGame = (): void => { + this.cars.forEach((car) => { + if (Math.floor(Math.random() * 9) + 1 >= 4) { + car.moveForward(); + } + }); + }; + + updateMaxPosition = (): void => { + this.cars.forEach((car) => { + if (car.position > this.maxPosition) { + this.maxPosition = car.position; + } + }); + }; + + getWinners = (): Array => { + this.cars.forEach((car) => { + if (car.position === this.maxPosition) { + this.winners.push(car.name); + } + }); + return this.winners; + }; +} + +export { Game }; + +export function getCarNames() { + const carNameInput = document.getElementById('car-names-input').value; + const carNameArray = carNameInput.split(','); + + const carNameValid = checkCarNames(carNameInput, carNameArray); + if (carNameValid !== ERROR_INPUT.NONE) { + alert(carNameValid); + resetCarNamesInput(); + return; + } + createCarObject(carNameArray); +} + +export function getCount() { + racingCount = document.getElementById('racing-count-input').value; + + const racingCountValid = checkRacingCount(); + if (racingCountValid !== ERROR_INPUT.NONE) { + alert(racingCountValid); + resetRacingCountInput(); + return; + } + startRacing(carObjectArray, racingCount); +} From d5a1b0c00faae36364de5a05473277014a9f0be5 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:14:59 +0900 Subject: [PATCH 10/70] =?UTF-8?q?feat:=20spinnerDiv=20=EC=A4=91=EC=95=99?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EC=9A=94=EC=86=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/templates/index.ts | 2 +- src/view/templates/input-section.ts | 2 +- src/view/templates/progress-section.ts | 20 +++++++++++--------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/view/templates/index.ts b/src/view/templates/index.ts index e828e774f..5f459f4e4 100644 --- a/src/view/templates/index.ts +++ b/src/view/templates/index.ts @@ -1,5 +1,5 @@ export { inputSection } from './input-section.js'; -export { progressSection, carNameDiv, arrowDiv, spinnerDiv } from './progress-section.js'; +export { progressSection, carNameDiv, spinnerDiv, arrowDiv } from './progress-section.js'; export { resultSection } from './result-section.js'; \ No newline at end of file diff --git a/src/view/templates/input-section.ts b/src/view/templates/input-section.ts index 87a9884c4..c07b33cd2 100644 --- a/src/view/templates/input-section.ts +++ b/src/view/templates/input-section.ts @@ -16,7 +16,7 @@ const inputSection = (): string => {

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

- +
diff --git a/src/view/templates/progress-section.ts b/src/view/templates/progress-section.ts index ac192ad9d..e046aebbf 100644 --- a/src/view/templates/progress-section.ts +++ b/src/view/templates/progress-section.ts @@ -7,26 +7,28 @@ const progressSection = (): string => { `; } -const carNameDiv = (name: string): string => { +const carNameDiv = (carName: string): string => { return `
-
${name}
+
${carName}
` } -const arrowDiv = (): string => { +const spinnerDiv = (): string => { return ` -
⬇️️
+
+
+ +
+
` } -const spinnerDiv = (): string => { +const arrowDiv = (): string => { return ` -
- -
+
⬇️️
` } -export { progressSection, carNameDiv, arrowDiv, spinnerDiv }; +export { progressSection, carNameDiv, spinnerDiv, arrowDiv }; From 26e72fee484e1c98773866d0e0f5b3cc46f960b8 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:16:03 +0900 Subject: [PATCH 11/70] =?UTF-8?q?feat:=20model=20=ED=8F=B4=EB=8D=94=20inde?= =?UTF-8?q?x=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/game.ts | 28 ++-------------------------- src/model/index.ts | 3 +++ 2 files changed, 5 insertions(+), 26 deletions(-) create mode 100644 src/model/index.ts diff --git a/src/model/game.ts b/src/model/game.ts index 52a7b9e93..3aee2509e 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -13,10 +13,11 @@ class Game { this.maxPosition = 0; } - playGame = (): void => { + play = (): void => { this.cars.forEach((car) => { if (Math.floor(Math.random() * 9) + 1 >= 4) { car.moveForward(); + this.updateMaxPosition(); } }); }; @@ -40,28 +41,3 @@ class Game { } export { Game }; - -export function getCarNames() { - const carNameInput = document.getElementById('car-names-input').value; - const carNameArray = carNameInput.split(','); - - const carNameValid = checkCarNames(carNameInput, carNameArray); - if (carNameValid !== ERROR_INPUT.NONE) { - alert(carNameValid); - resetCarNamesInput(); - return; - } - createCarObject(carNameArray); -} - -export function getCount() { - racingCount = document.getElementById('racing-count-input').value; - - const racingCountValid = checkRacingCount(); - if (racingCountValid !== ERROR_INPUT.NONE) { - alert(racingCountValid); - resetRacingCountInput(); - return; - } - startRacing(carObjectArray, racingCount); -} diff --git a/src/model/index.ts b/src/model/index.ts new file mode 100644 index 000000000..8ef7e4324 --- /dev/null +++ b/src/model/index.ts @@ -0,0 +1,3 @@ +export { Car } from './car.js'; + +export { Game } from './game.js'; \ No newline at end of file From e08451dfddda02d4bfa601fe42dc64871ad01fd8 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:17:12 +0900 Subject: [PATCH 12/70] =?UTF-8?q?feat:=20eventListener=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=EB=B0=8F=20=EA=B5=AC=ED=98=84=EB=B6=80=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/observer.ts | 57 ++++++++++++++++++++++++++++++++++++++ src/index.ts | 6 +++- 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/controller/observer.ts diff --git a/src/controller/observer.ts b/src/controller/observer.ts new file mode 100644 index 000000000..d7a0cfee3 --- /dev/null +++ b/src/controller/observer.ts @@ -0,0 +1,57 @@ +import { checkCarName } from './validtor.js'; +import { clearInput, preventInputValue, preventButtonClick } from './utils.js'; +import { Car } from '../model/index.js'; +import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; +import { playGame } from './player.js'; + +const createCarsObject = (carNameArray: Array) => { + let cars: Array = []; + + carNameArray.forEach((car) => { + cars.push(new Car(car)); + }); + return cars; +} + +const getCarNames = (): void => { + const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; + const carNameArray: Array = carNameInput?.value.split(','); + + if (checkCarName(carNameArray)) { + const carNameSubmitButton: HTMLButtonElement = document.getElementById('car-names-submit') as HTMLButtonElement; + + preventInputValue(carNameInput); + preventButtonClick(carNameSubmitButton); + return; + } + clearInput(carNameInput); +}; + +const getTryCount = (): void => { + const tryCountInput: HTMLInputElement = document.getElementById('racing-count-input') as HTMLInputElement; + const tryCount: number = Number(tryCountInput?.value); + + if (tryCount > 0) { + const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; + const tryCountSubmitButton: HTMLButtonElement = document.getElementById('racing-count-submit') as HTMLButtonElement; + const carNameArray: Array = carNameInput?.value.split(','); + const cars: Array = createCarsObject(carNameArray); + + preventInputValue(tryCountInput); + preventButtonClick(tryCountSubmitButton); + renderProgressSection(); + renderCarNameDiv(carNameArray); + renderSpinnerDiv(carNameArray) + playGame(cars, tryCount); + return; + } + clearInput(tryCountInput); +}; + + +const setEventListener = (): void => { + document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); + document.getElementById('racing-count-submit')!.addEventListener('click', () => getTryCount()); +}; + +export { setEventListener }; diff --git a/src/index.ts b/src/index.ts index 603e9f132..353c138d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,9 @@ +import { setEventListener } from './controller/observer.js'; +import { renderInputSection } from './view/renderer.js'; + const app = (): void => { - console.log('ho'); + renderInputSection(); + setEventListener(); }; app(); From 10e4f37da2efb78dbac1297a440ab30c2fa2291f Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:18:59 +0900 Subject: [PATCH 13/70] =?UTF-8?q?feat:=20element=20=EC=A1=B0=EC=9E=91=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80(clearInput,=20disableIn?= =?UTF-8?q?putValue,=20disableButtonClick)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/utils.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/controller/utils.ts diff --git a/src/controller/utils.ts b/src/controller/utils.ts new file mode 100644 index 000000000..fa4777bbd --- /dev/null +++ b/src/controller/utils.ts @@ -0,0 +1,15 @@ +const clearInput = (element: HTMLInputElement) => { + element.value = ''; + element.focus(); +}; + +const preventInputValue = (element: HTMLInputElement) => { + element.disabled = true; +} + +const preventButtonClick = (element: HTMLButtonElement) => { + element.disabled = true; +} + + +export { clearInput, preventInputValue, preventButtonClick }; From f2824b6624ec0fec844d8cd5f835f9a7d027637e Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:19:57 +0900 Subject: [PATCH 14/70] =?UTF-8?q?feat:=20element=20=EC=A1=B0=EC=9E=91=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=98=A4=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/controller/utils.ts b/src/controller/utils.ts index fa4777bbd..c643b50d6 100644 --- a/src/controller/utils.ts +++ b/src/controller/utils.ts @@ -3,13 +3,13 @@ const clearInput = (element: HTMLInputElement) => { element.focus(); }; -const preventInputValue = (element: HTMLInputElement) => { +const disableInputValue = (element: HTMLInputElement) => { element.disabled = true; } -const preventButtonClick = (element: HTMLButtonElement) => { +const disableButtonClick = (element: HTMLButtonElement) => { element.disabled = true; } -export { clearInput, preventInputValue, preventButtonClick }; +export { clearInput, disableInputValue, disableButtonClick }; From 2ef3dfa9f132c9162768fa245230eb84ac30a897 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:20:32 +0900 Subject: [PATCH 15/70] =?UTF-8?q?feat:=20element=20=EC=A1=B0=EC=9E=91?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/observer.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/controller/observer.ts b/src/controller/observer.ts index d7a0cfee3..2de8f3ca0 100644 --- a/src/controller/observer.ts +++ b/src/controller/observer.ts @@ -1,5 +1,5 @@ import { checkCarName } from './validtor.js'; -import { clearInput, preventInputValue, preventButtonClick } from './utils.js'; +import { clearInput, disableInputValue, disableButtonClick } from './utils.js'; import { Car } from '../model/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; import { playGame } from './player.js'; @@ -20,8 +20,8 @@ const getCarNames = (): void => { if (checkCarName(carNameArray)) { const carNameSubmitButton: HTMLButtonElement = document.getElementById('car-names-submit') as HTMLButtonElement; - preventInputValue(carNameInput); - preventButtonClick(carNameSubmitButton); + disableInputValue(carNameInput); + disableButtonClick(carNameSubmitButton); return; } clearInput(carNameInput); @@ -37,8 +37,8 @@ const getTryCount = (): void => { const carNameArray: Array = carNameInput?.value.split(','); const cars: Array = createCarsObject(carNameArray); - preventInputValue(tryCountInput); - preventButtonClick(tryCountSubmitButton); + disableInputValue(tryCountInput); + disableButtonClick(tryCountSubmitButton); renderProgressSection(); renderCarNameDiv(carNameArray); renderSpinnerDiv(carNameArray) From 2cf8b362b8e170e5a5b165b1ebcf011af28680b4 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:21:47 +0900 Subject: [PATCH 16/70] =?UTF-8?q?feat:=20=EA=B2=8C=EC=9E=84=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EA=BB=8D=EB=8D=B0=EA=B8=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/player.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 src/controller/player.ts diff --git a/src/controller/player.ts b/src/controller/player.ts new file mode 100644 index 000000000..b49bb2e0d --- /dev/null +++ b/src/controller/player.ts @@ -0,0 +1,5 @@ +import { Car } from '../model/car.js'; + +const playGame = (cars: Array, tryCount: number) => {}; + +export { playGame }; From d019b85e8a45eff0643d4c1f7abe4c04a53cfd16 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:22:22 +0900 Subject: [PATCH 17/70] =?UTF-8?q?feat:=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EB=B6=80=20=ED=8C=8C=EC=9D=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/validtor.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index e69de29bb..6cc54cf18 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -0,0 +1,5 @@ +const checkCarName = (CarNameArray: Array): boolean => { + return true; +}; + +export { checkCarName }; From a254301256f7050e97a84483a47e58f1c0bd0fc3 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Fri, 4 Jun 2021 23:23:05 +0900 Subject: [PATCH 18/70] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A6=84,=20=EC=8A=A4?= =?UTF-8?q?=ED=94=BC=EB=84=88=20renderer=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/renderer.ts | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 6ff4e6903..f247b5005 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,4 +1,4 @@ -import { inputSection, progressSection, resultSection } from './templates/index.js'; +import { inputSection, progressSection, carNameDiv, spinnerDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { document.getElementById('app')!.innerHTML = inputSection(); @@ -8,14 +8,31 @@ const renderProgressSection = (): void => { document.getElementById('app')!.insertAdjacentHTML(`beforeend`, progressSection()); }; -const renderCarNameDiv = (name: string): void => {}; +const renderCarNameDiv = (carNameArray: Array): void => { + carNameArray.forEach((carName) => { + document.getElementsByClassName('mt-4 d-flex')[0].insertAdjacentHTML(`beforeend`, carNameDiv(carName)); + }); +}; -const renderArrowDiv = (): void => {}; +const renderSpinnerDiv = (carNameArray: Array): void => { + console.log(carNameArray.length) + for (let index = 0; index < carNameArray.length; index += 1) { + console.log(index); + document.getElementsByClassName('mr-2')[index].insertAdjacentHTML(`beforeend`, spinnerDiv()); + } +}; -const renderSpinnerDiv = (): void => {}; +const renderArrowDiv = (carNameArray: Array): void => {}; const renderResultSection = (winners: string): void => { document.getElementById('app')!.insertAdjacentHTML(`beforeend`, resultSection(winners)); }; -export { renderInputSection, renderProgressSection, renderResultSection }; +export { + renderInputSection, + renderProgressSection, + renderCarNameDiv, + renderSpinnerDiv, + renderArrowDiv, + renderResultSection, +}; From d1b1ffa0e551869cf2ff2618b386f54ea315a506 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 11:55:41 +0900 Subject: [PATCH 19/70] =?UTF-8?q?refactor:=20=EC=B4=88=EA=B8=B0=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=A7=81=20=EB=B0=8F=20=EC=83=81=ED=99=A9?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EB=8B=A8=EC=9D=BC=20=EB=A0=8C?= =?UTF-8?q?=EB=8D=94=EB=A7=81=EC=9D=84=20=EC=9C=84=ED=95=B4=20view?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B0=98=EB=B3=B5=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/renderer.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/view/renderer.ts b/src/view/renderer.ts index f247b5005..8240b618f 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -8,18 +8,12 @@ const renderProgressSection = (): void => { document.getElementById('app')!.insertAdjacentHTML(`beforeend`, progressSection()); }; -const renderCarNameDiv = (carNameArray: Array): void => { - carNameArray.forEach((carName) => { - document.getElementsByClassName('mt-4 d-flex')[0].insertAdjacentHTML(`beforeend`, carNameDiv(carName)); - }); +const renderCarNameDiv = (element: Element, carName: string): void => { + element.insertAdjacentHTML(`beforeend`, carNameDiv(carName)); }; -const renderSpinnerDiv = (carNameArray: Array): void => { - console.log(carNameArray.length) - for (let index = 0; index < carNameArray.length; index += 1) { - console.log(index); - document.getElementsByClassName('mr-2')[index].insertAdjacentHTML(`beforeend`, spinnerDiv()); - } +const renderSpinnerDiv = (element: Element): void => { + element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }; const renderArrowDiv = (carNameArray: Array): void => {}; From 82327de338f23c85bfb3f8f2d23bf539cd4063cf Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 11:58:05 +0900 Subject: [PATCH 20/70] =?UTF-8?q?refactor:=20event.ts=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/event.ts | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 src/controller/event.ts diff --git a/src/controller/event.ts b/src/controller/event.ts deleted file mode 100644 index 2d53c1eae..000000000 --- a/src/controller/event.ts +++ /dev/null @@ -1,6 +0,0 @@ -const setEventListener = (): void => { - document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); - document.getElementById('racing-count-submit')!.addEventListener('click', () => getCount()); -}; - -export { setEventListener }; From f25d201e0609aebb3880682465f66dfabdb7ef34 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 11:58:56 +0900 Subject: [PATCH 21/70] =?UTF-8?q?feat:=20querySelector,=20queryselectorAll?= =?UTF-8?q?=20=EB=8B=A8=EC=B6=95=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/utils.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/controller/utils.ts b/src/controller/utils.ts index c643b50d6..3a145fdfd 100644 --- a/src/controller/utils.ts +++ b/src/controller/utils.ts @@ -1,3 +1,7 @@ +const $ = (selector: string): Element | null => document.querySelector(selector); + +const $$ = (selector: string): NodeListOf => document.querySelectorAll(selector); + const clearInput = (element: HTMLInputElement) => { element.value = ''; element.focus(); @@ -12,4 +16,4 @@ const disableButtonClick = (element: HTMLButtonElement) => { } -export { clearInput, disableInputValue, disableButtonClick }; +export { $, $$, clearInput, disableInputValue, disableButtonClick }; From 78baebfb7090c16b438c8cb3c05a82d5b20abff4 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 12:00:11 +0900 Subject: [PATCH 22/70] =?UTF-8?q?feat:=202=EB=8B=A8=EA=B3=84=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=B4=88=EA=B8=B0=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/observer.ts | 10 +++------- src/controller/player.ts | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/controller/observer.ts b/src/controller/observer.ts index 2de8f3ca0..e93088a2b 100644 --- a/src/controller/observer.ts +++ b/src/controller/observer.ts @@ -1,7 +1,6 @@ import { checkCarName } from './validtor.js'; import { clearInput, disableInputValue, disableButtonClick } from './utils.js'; import { Car } from '../model/index.js'; -import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; import { playGame } from './player.js'; const createCarsObject = (carNameArray: Array) => { @@ -15,7 +14,7 @@ const createCarsObject = (carNameArray: Array) => { const getCarNames = (): void => { const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; - const carNameArray: Array = carNameInput?.value.split(','); + const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); if (checkCarName(carNameArray)) { const carNameSubmitButton: HTMLButtonElement = document.getElementById('car-names-submit') as HTMLButtonElement; @@ -34,15 +33,12 @@ const getTryCount = (): void => { if (tryCount > 0) { const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; const tryCountSubmitButton: HTMLButtonElement = document.getElementById('racing-count-submit') as HTMLButtonElement; - const carNameArray: Array = carNameInput?.value.split(','); + const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); const cars: Array = createCarsObject(carNameArray); disableInputValue(tryCountInput); disableButtonClick(tryCountSubmitButton); - renderProgressSection(); - renderCarNameDiv(carNameArray); - renderSpinnerDiv(carNameArray) - playGame(cars, tryCount); + playGame(cars, carNameArray, tryCount); return; } clearInput(tryCountInput); diff --git a/src/controller/player.ts b/src/controller/player.ts index b49bb2e0d..18dc3adff 100644 --- a/src/controller/player.ts +++ b/src/controller/player.ts @@ -1,5 +1,19 @@ import { Car } from '../model/car.js'; +import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; +import { $, $$ } from './utils.js'; -const playGame = (cars: Array, tryCount: number) => {}; +const setProgressSection = (carNameArray: Array) => { + renderProgressSection(); + carNameArray.forEach((carName) => { + renderCarNameDiv($('.mt-4.d-flex') as Element, carName); + }); + $$('.mr-2').forEach((element) => { + renderSpinnerDiv(element); + }) +}; + +const playGame = (cars: Array, carNameArray: Array, tryCount: number) => { + setProgressSection(carNameArray); +}; export { playGame }; From 58b444060879f78dbcb0649ccc04e3429aa4167e Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 12:32:20 +0900 Subject: [PATCH 23/70] =?UTF-8?q?refactor:=20game=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EC=97=90=EC=84=9C=20count=ED=9A=9F=EC=88=98=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/game.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/model/game.ts b/src/model/game.ts index 3aee2509e..a8163f60b 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -1,18 +1,16 @@ import { Car } from './car'; - class Game { cars: Array; winners: Array; - tryCount: number; maxPosition: number; - constructor(cars: Array, tryCount: number) { + constructor(cars: Array) { this.cars = cars; this.winners = []; - this.tryCount = tryCount; this.maxPosition = 0; } + play = (): void => { this.cars.forEach((car) => { if (Math.floor(Math.random() * 9) + 1 >= 4) { From 8a19503f1ee738a72f9dff3d33307e54873f07af Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 15:11:47 +0900 Subject: [PATCH 24/70] =?UTF-8?q?feat:=20=ED=99=94=EC=82=B4=ED=91=9C=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85=20=EB=A0=8C=EB=8D=94=EB=9F=AC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/view/renderer.ts | 6 ++++-- src/view/templates/result-section.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 8240b618f..d35967bf9 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,4 +1,4 @@ -import { inputSection, progressSection, carNameDiv, spinnerDiv, resultSection } from './templates/index.js'; +import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { document.getElementById('app')!.innerHTML = inputSection(); @@ -16,7 +16,9 @@ const renderSpinnerDiv = (element: Element): void => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }; -const renderArrowDiv = (carNameArray: Array): void => {}; +const renderArrowDiv = (element: Element): void => { + element.insertAdjacentHTML(`afterend`, arrowDiv()); +}; const renderResultSection = (winners: string): void => { document.getElementById('app')!.insertAdjacentHTML(`beforeend`, resultSection(winners)); diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts index f44034aa1..00697ac01 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/templates/result-section.ts @@ -4,7 +4,7 @@ const resultSection = (winners: string): string => {

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

- +
From 2d9a86bf997b07e371a0214ea351107d78ef5ecb Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 15:12:29 +0900 Subject: [PATCH 25/70] =?UTF-8?q?feat:=20car=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=EC=97=90=20index=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/car.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/model/car.ts b/src/model/car.ts index 0c4327e86..1ef2c0dc2 100644 --- a/src/model/car.ts +++ b/src/model/car.ts @@ -1,10 +1,12 @@ class Car { name: string; position: number; + index: number; - constructor(name: string) { + constructor(name: string, index: number) { this.name = name; this.position = 0; + this.index = index; } moveForward(): void { From 6ab18d5844698103d16a41c1356f0700fadab2d4 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 15:13:49 +0900 Subject: [PATCH 26/70] =?UTF-8?q?feat:=20game=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=20=EC=83=9D=EC=84=B1=20=ED=9B=84=20=EA=B2=8C=EC=9E=84?= =?UTF-8?q?=20=EC=8B=A4=ED=96=89=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=202=EB=8B=A8=EA=B3=84=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EC=8B=9C=EB=8F=84=ED=9A=9F=EC=88=98?= =?UTF-8?q?=EB=B3=84=EB=A1=9C=20=EB=A1=9C=EC=A7=81=20=EB=B6=84=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/observer.ts | 31 ++++++++++++++++------------ src/controller/player.ts | 42 ++++++++++++++++++++++++++------------ src/model/game.ts | 1 - 3 files changed, 47 insertions(+), 27 deletions(-) diff --git a/src/controller/observer.ts b/src/controller/observer.ts index e93088a2b..d4c3a1f53 100644 --- a/src/controller/observer.ts +++ b/src/controller/observer.ts @@ -1,16 +1,18 @@ import { checkCarName } from './validtor.js'; import { clearInput, disableInputValue, disableButtonClick } from './utils.js'; -import { Car } from '../model/index.js'; -import { playGame } from './player.js'; - -const createCarsObject = (carNameArray: Array) => { - let cars: Array = []; - - carNameArray.forEach((car) => { - cars.push(new Car(car)); - }); - return cars; -} +import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; +import { startGame } from './player.js'; +import { $, $$ } from './utils.js'; + +const initProgressSection = (carNameArray: Array) => { + renderProgressSection(); + carNameArray.forEach((carName) => { + renderCarNameDiv($('.mt-4.d-flex') as Element, carName); + }); // 이름 div 생성 + $$('div.mr-2').forEach((element) => { + renderSpinnerDiv(element); + }) // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 +}; const getCarNames = (): void => { const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; @@ -34,16 +36,19 @@ const getTryCount = (): void => { const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; const tryCountSubmitButton: HTMLButtonElement = document.getElementById('racing-count-submit') as HTMLButtonElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - const cars: Array = createCarsObject(carNameArray); disableInputValue(tryCountInput); disableButtonClick(tryCountSubmitButton); - playGame(cars, carNameArray, tryCount); + initProgressSection(carNameArray); + startGame(carNameArray, tryCount); return; } clearInput(tryCountInput); }; +const setEventListenerRetry = (): void => { + document.getElementById('retry-button')!.addEventListener('ciick', () => {}); +} const setEventListener = (): void => { document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); diff --git a/src/controller/player.ts b/src/controller/player.ts index 18dc3adff..d5c08787d 100644 --- a/src/controller/player.ts +++ b/src/controller/player.ts @@ -1,19 +1,35 @@ -import { Car } from '../model/car.js'; -import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; -import { $, $$ } from './utils.js'; +import { Car, Game } from '../model/index.js'; +import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; +import { $$ } from './utils.js'; -const setProgressSection = (carNameArray: Array) => { - renderProgressSection(); - carNameArray.forEach((carName) => { - renderCarNameDiv($('.mt-4.d-flex') as Element, carName); +const createCarsObject = (carNameArray: Array) => { + let cars: Array = []; + + carNameArray.forEach((car, index) => { + cars.push(new Car(car, index)); }); - $$('.mr-2').forEach((element) => { - renderSpinnerDiv(element); - }) + return cars; }; -const playGame = (cars: Array, carNameArray: Array, tryCount: number) => { - setProgressSection(carNameArray); +const startGame = (carNameArray: Array, tryCount: number) => { + const racingGame: Game = new Game(createCarsObject(carNameArray)); + + for (let index = 0; index < tryCount; index += 1) { + racingGame.play(); + } + $$('div.car-player').forEach((element, index) => { + racingGame.cars.forEach((car) => { + if (car.index === index) { + for (let index = 0; index < car.position; index += 1) { + renderArrowDiv(element); + } + } + }); + }); + $$('div.d-flex.justify-center.mt-3').forEach((element) => { + element.remove(); + }) + renderResultSection(racingGame.getWinners().join(',').toLowerCase()); }; -export { playGame }; +export { startGame }; diff --git a/src/model/game.ts b/src/model/game.ts index a8163f60b..83436e2a2 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -10,7 +10,6 @@ class Game { this.maxPosition = 0; } - play = (): void => { this.cars.forEach((car) => { if (Math.floor(Math.random() * 9) + 1 >= 4) { From 2a9ba847229db85e89911cb41aec971c637bb7d0 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 17:05:24 +0900 Subject: [PATCH 27/70] =?UTF-8?q?feat:=20=EC=9E=90=EB=8F=99=EC=B0=A8=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/validtor.ts | 42 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index 6cc54cf18..c27160a80 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -1,5 +1,43 @@ -const checkCarName = (CarNameArray: Array): boolean => { +import { ALERT } from '../constants/index.js'; + +const checkEmptyInput = (input: HTMLInputElement) => { + return input.value.trim() === ''; +}; + +const checkElementsAlone = (array: Array) => { + return array.length < 2; +}; + +const checkElementsDouble = (array: Array) => { + return array.some((x) => { + return array.indexOf(x) !== array.lastIndexOf(x); + }); +}; + +const checkElementsLength = (array: Array) => { + for (let index = 0; index < array.length; index += 1) { + if (array[index].length > 5) { + return true; + } + } + return false; +}; + +const checkCarNames = (carNameInput: HTMLInputElement, carNameArray: Array): boolean => { + if (checkEmptyInput(carNameInput)) { + alert(ALERT.CAR_INPUT_EMPTY); + return false; + } else if (checkElementsAlone(carNameArray)) { + alert(ALERT.CAR_INPUT_ALONE); + return false; + } else if (checkElementsDouble(carNameArray)) { + alert(ALERT.CAR_INPUT_DOUBLE); + return false; + } else if (checkElementsLength(carNameArray)) { + alert(ALERT.CAR_INPUT_LENGTH); + return false; + } return true; }; -export { checkCarName }; +export { checkCarNames }; From b6a5ea721d5692f9e9677f61576095c775504187 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 17:06:22 +0900 Subject: [PATCH 28/70] =?UTF-8?q?feat:=20alert=20constant=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/alert.ts | 9 +++++++++ src/constants/index.ts | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/constants/alert.ts diff --git a/src/constants/alert.ts b/src/constants/alert.ts new file mode 100644 index 000000000..d126c81cf --- /dev/null +++ b/src/constants/alert.ts @@ -0,0 +1,9 @@ +const ALERT = { + CAR_INPUT_EMPTY: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”', + CAR_INPUT_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•˜μ„Έμš”', + CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', + CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', +}; + +export { ALERT }; diff --git a/src/constants/index.ts b/src/constants/index.ts index e69de29bb..df0f5c562 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -0,0 +1 @@ +export { ALERT } from './alert.js'; \ No newline at end of file From f91ff9daa776edeee12d721a30efa03c60423567 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 17:41:16 +0900 Subject: [PATCH 29/70] =?UTF-8?q?refactor:=20game=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EC=97=90=20=EB=A7=A4=20=EB=9D=BC=EC=9A=B4=EB=93=9C=20?= =?UTF-8?q?=EC=9A=B0=EC=8A=B9=EC=9E=90=EC=9D=98=20index=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/game.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/model/game.ts b/src/model/game.ts index 83436e2a2..7ae280d02 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -1,12 +1,14 @@ import { Car } from './car'; class Game { cars: Array; - winners: Array; + finalWinners: Array; + roundWinnersIndex: Array; maxPosition: number; constructor(cars: Array) { this.cars = cars; - this.winners = []; + this.finalWinners = []; + this.roundWinnersIndex = []; this.maxPosition = 0; } @@ -14,6 +16,7 @@ class Game { this.cars.forEach((car) => { if (Math.floor(Math.random() * 9) + 1 >= 4) { car.moveForward(); + this.roundWinnersIndex.push(car.index); this.updateMaxPosition(); } }); @@ -27,13 +30,17 @@ class Game { }); }; + initRoundWinnersIndex = (): void => { + this.roundWinnersIndex = []; + } + getWinners = (): Array => { this.cars.forEach((car) => { if (car.position === this.maxPosition) { - this.winners.push(car.name); + this.finalWinners.push(car.name); } }); - return this.winners; + return this.finalWinners; }; } From 4125eb40790ff39797e7760783ec90bdf8a59c13 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 17:55:32 +0900 Subject: [PATCH 30/70] =?UTF-8?q?refactor:=20element=20disable=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=EB=A5=BC=20toggle=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=EB=A1=9C=20=EC=97=85=EA=B7=B8?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/utils.ts | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/controller/utils.ts b/src/controller/utils.ts index 3a145fdfd..7f74744d2 100644 --- a/src/controller/utils.ts +++ b/src/controller/utils.ts @@ -7,13 +7,30 @@ const clearInput = (element: HTMLInputElement) => { element.focus(); }; -const disableInputValue = (element: HTMLInputElement) => { - element.disabled = true; -} +const toggleInputValueDisabled = (element: HTMLInputElement) => { + if (element.disabled) { + element.disabled = false; + } else { + element.disabled = true; + } +}; -const disableButtonClick = (element: HTMLButtonElement) => { - element.disabled = true; -} +const toggleClickButtonDisabled = (element: HTMLButtonElement) => { + if (element.disabled) { + element.disabled = false; + } else { + element.disabled = true; + } +}; +const removeChildNodes = (element: Element | null) => { + if (element) { + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } + } +}; -export { $, $$, clearInput, disableInputValue, disableButtonClick }; +export { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes }; From afcbab110b65d79f46c94f2ae6a1a78fcc2739fe Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 17:56:33 +0900 Subject: [PATCH 31/70] =?UTF-8?q?feat:=20input=20=EA=B0=92=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=EC=84=B1=20=EA=B2=80=EC=A6=9D=20=ED=8C=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EA=B0=92=20=EC=9E=85=EB=A0=A5=EC=97=AC?= =?UTF-8?q?=EB=B6=80,=20=EA=B8=B8=EC=9D=B4,=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/validtor.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index c27160a80..f22112af2 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -40,4 +40,15 @@ const checkCarNames = (carNameInput: HTMLInputElement, carNameArray: Array { + if (checkEmptyInput(tryCountInput)) { + alert(ALERT.TRY_INPUT_EMPTY); + return false; + } else if (Number(tryCountInput.value) > 20) { + alert(ALERT.TRY_INPUT_TOO_BIG); + return false; + } + return true; +} + +export { checkCarNames, checkTryCount }; From 7237d022b35f2f1ecd5e9b4a27014e2c93b83e71 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 17:57:19 +0900 Subject: [PATCH 32/70] =?UTF-8?q?feat:=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=20=EC=97=90=EB=9F=AC=20=EB=A9=94=EC=84=B8=EC=A7=80,?= =?UTF-8?q?=20=EC=9A=B0=EC=8A=B9=20=EC=B6=95=ED=95=98=20=EB=A9=94=EC=84=B8?= =?UTF-8?q?=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/alert.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/constants/alert.ts b/src/constants/alert.ts index d126c81cf..bc240f55c 100644 --- a/src/constants/alert.ts +++ b/src/constants/alert.ts @@ -4,6 +4,11 @@ const ALERT = { CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', + + TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', + TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', + + CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘' }; export { ALERT }; From 3d6681c183744226990e9b65756132ba2e9accd7 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 18:21:22 +0900 Subject: [PATCH 33/70] =?UTF-8?q?refactor:=20elementid=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=A0=95=EC=9D=98,=20prettier=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?,=20event=EC=99=80=20lintener=20=ED=95=A8=EC=88=98=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/alert.ts | 2 +- src/constants/elements.ts | 14 ++++++ src/constants/index.ts | 3 +- src/controller/event.ts | 12 +++++ src/controller/linstener.ts | 65 ++++++++++++++++++++++++++ src/controller/observer.ts | 58 ----------------------- src/controller/player.ts | 34 +++++++++----- src/controller/utils.ts | 6 ++- src/controller/validtor.ts | 2 +- src/index.ts | 4 +- src/model/car.ts | 2 +- src/model/game.ts | 2 +- src/model/index.ts | 1 - src/view/renderer.ts | 7 +-- src/view/templates/index.ts | 2 - src/view/templates/input-section.ts | 8 ++-- src/view/templates/progress-section.ts | 14 +++--- src/view/templates/result-section.ts | 2 +- 18 files changed, 142 insertions(+), 96 deletions(-) create mode 100644 src/constants/elements.ts create mode 100644 src/controller/event.ts create mode 100644 src/controller/linstener.ts delete mode 100644 src/controller/observer.ts diff --git a/src/constants/alert.ts b/src/constants/alert.ts index bc240f55c..5460fb075 100644 --- a/src/constants/alert.ts +++ b/src/constants/alert.ts @@ -8,7 +8,7 @@ const ALERT = { TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', - CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘' + CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', }; export { ALERT }; diff --git a/src/constants/elements.ts b/src/constants/elements.ts new file mode 100644 index 000000000..165b82612 --- /dev/null +++ b/src/constants/elements.ts @@ -0,0 +1,14 @@ +const ID = { + APP_DIV: 'app', + + CAR_NAME_DIV: '.mt-4.d-flex', + SPINNER_DIV: 'div.mr-2', + + CAR_NAME_INPUT: 'car-names-input', + CAR_NAME_SUBMIT: 'car-names-submit', + + RACING_COUNT_INPUT: 'racing-count-input', + RACING_COUNT_SUBMIT: 'racing-count-submit', +}; + +export { ID }; diff --git a/src/constants/index.ts b/src/constants/index.ts index df0f5c562..430e88113 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1 +1,2 @@ -export { ALERT } from './alert.js'; \ No newline at end of file +export { ID } from './elements.js'; +export { ALERT } from './alert.js'; diff --git a/src/controller/event.ts b/src/controller/event.ts new file mode 100644 index 000000000..8450cb293 --- /dev/null +++ b/src/controller/event.ts @@ -0,0 +1,12 @@ +import { getCarNames, getTryCount, initGame } from './linstener.js'; + +const setInputButtonsEventListener = (): void => { + document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); + document.getElementById('racing-count-submit')!.addEventListener('click', () => getTryCount()); +}; + +const setRetryButtonEventListener = (): void => { + document.getElementById('retry-button')!.addEventListener('click', () => initGame()); +}; + +export { setInputButtonsEventListener, setRetryButtonEventListener }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts new file mode 100644 index 000000000..ae34aa7bb --- /dev/null +++ b/src/controller/linstener.ts @@ -0,0 +1,65 @@ +import { startGame } from './player.js'; +import { ID } from '../constants/index.js'; +import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; +import { setInputButtonsEventListener } from './event.js'; +import { checkCarNames, checkTryCount } from './validtor.js'; +import { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; + +const getCarNames = (): void => { + const carNameInput: HTMLInputElement = document.getElementById(ID.CAR_NAME_INPUT) as HTMLInputElement; + const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); + + if (checkCarNames(carNameInput, carNameArray)) { + const carNameSubmitButton: HTMLButtonElement = document.getElementById(ID.CAR_NAME_SUBMIT) as HTMLButtonElement; + const tryCountInput: HTMLInputElement = document.getElementById(ID.RACING_COUNT_INPUT) as HTMLInputElement; + const tryCountSubmitButton: HTMLButtonElement = document.getElementById( + ID.RACING_COUNT_SUBMIT, + ) as HTMLButtonElement; + + toggleInputValueDisabled(carNameInput); + toggleClickButtonDisabled(carNameSubmitButton); + toggleInputValueDisabled(tryCountInput); + toggleClickButtonDisabled(tryCountSubmitButton); + tryCountInput.focus(); + return; + } + clearInput(carNameInput); +}; + +const getTryCount = (): void => { + const tryCountInput: HTMLInputElement = document.getElementById(ID.RACING_COUNT_INPUT) as HTMLInputElement; + const tryCount: number = Number(tryCountInput?.value); + + if (checkTryCount(tryCountInput)) { + const carNameInput: HTMLInputElement = document.getElementById(ID.CAR_NAME_INPUT) as HTMLInputElement; + const tryCountSubmitButton: HTMLButtonElement = document.getElementById( + ID.RACING_COUNT_SUBMIT, + ) as HTMLButtonElement; + const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); + + toggleInputValueDisabled(tryCountInput); + toggleClickButtonDisabled(tryCountSubmitButton); + setupProgressSection(carNameArray); + startGame(carNameArray, tryCount); + return; + } + clearInput(tryCountInput); +}; + +const setupProgressSection = (carNameArray: Array) => { + renderProgressSection(); + carNameArray.forEach((carName) => { + renderCarNameDiv($(ID.CAR_NAME_DIV) as Element, carName); + }); // 이름 div 생성 + $$(ID.SPINNER_DIV).forEach((element) => { + renderSpinnerDiv(element); + }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 +}; + +const initGame = (): void => { + removeChildNodes(document.getElementById(ID.APP_DIV)); + renderInputSection(); + setInputButtonsEventListener(); +}; + +export { getCarNames, getTryCount, initGame }; diff --git a/src/controller/observer.ts b/src/controller/observer.ts deleted file mode 100644 index d4c3a1f53..000000000 --- a/src/controller/observer.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { checkCarName } from './validtor.js'; -import { clearInput, disableInputValue, disableButtonClick } from './utils.js'; -import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv } from '../view/renderer.js'; -import { startGame } from './player.js'; -import { $, $$ } from './utils.js'; - -const initProgressSection = (carNameArray: Array) => { - renderProgressSection(); - carNameArray.forEach((carName) => { - renderCarNameDiv($('.mt-4.d-flex') as Element, carName); - }); // 이름 div 생성 - $$('div.mr-2').forEach((element) => { - renderSpinnerDiv(element); - }) // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 -}; - -const getCarNames = (): void => { - const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; - const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - - if (checkCarName(carNameArray)) { - const carNameSubmitButton: HTMLButtonElement = document.getElementById('car-names-submit') as HTMLButtonElement; - - disableInputValue(carNameInput); - disableButtonClick(carNameSubmitButton); - return; - } - clearInput(carNameInput); -}; - -const getTryCount = (): void => { - const tryCountInput: HTMLInputElement = document.getElementById('racing-count-input') as HTMLInputElement; - const tryCount: number = Number(tryCountInput?.value); - - if (tryCount > 0) { - const carNameInput: HTMLInputElement = document.getElementById('car-names-input') as HTMLInputElement; - const tryCountSubmitButton: HTMLButtonElement = document.getElementById('racing-count-submit') as HTMLButtonElement; - const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - - disableInputValue(tryCountInput); - disableButtonClick(tryCountSubmitButton); - initProgressSection(carNameArray); - startGame(carNameArray, tryCount); - return; - } - clearInput(tryCountInput); -}; - -const setEventListenerRetry = (): void => { - document.getElementById('retry-button')!.addEventListener('ciick', () => {}); -} - -const setEventListener = (): void => { - document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); - document.getElementById('racing-count-submit')!.addEventListener('click', () => getTryCount()); -}; - -export { setEventListener }; diff --git a/src/controller/player.ts b/src/controller/player.ts index d5c08787d..2ef41cd7e 100644 --- a/src/controller/player.ts +++ b/src/controller/player.ts @@ -1,6 +1,8 @@ +import { ALERT } from '../constants/alert.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { $$ } from './utils.js'; +import { setRetryButtonEventListener } from './event.js'; +import { $$, makeDelay } from './utils.js'; const createCarsObject = (carNameArray: Array) => { let cars: Array = []; @@ -11,25 +13,33 @@ const createCarsObject = (carNameArray: Array) => { return cars; }; -const startGame = (carNameArray: Array, tryCount: number) => { - const racingGame: Game = new Game(createCarsObject(carNameArray)); - - for (let index = 0; index < tryCount; index += 1) { - racingGame.play(); - } +const playGameOnce = (racingGame: Game) => { + racingGame.play(); $$('div.car-player').forEach((element, index) => { racingGame.cars.forEach((car) => { - if (car.index === index) { - for (let index = 0; index < car.position; index += 1) { + racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { + if (car.index === index && car.index === roundWinnerIndex) { renderArrowDiv(element); } - } + }); }); }); + racingGame.initRoundWinnersIndex(); +}; + +const startGame = async (carNameArray: Array, tryCount: number) => { + const racingGame: Game = new Game(createCarsObject(carNameArray)); + + for (let index = 0; index < tryCount; index += 1) { + await makeDelay(1000).then(() => playGameOnce(racingGame)); + } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ $$('div.d-flex.justify-center.mt-3').forEach((element) => { element.remove(); - }) - renderResultSection(racingGame.getWinners().join(',').toLowerCase()); + }); // κ²Œμž„ λλ‚˜λ©΄ spinner 제거 + const racingWinners: Array = racingGame.getWinners(); + renderResultSection(racingWinners.join(', ').toLowerCase()); + await makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + setRetryButtonEventListener(); }; export { startGame }; diff --git a/src/controller/utils.ts b/src/controller/utils.ts index 7f74744d2..bc0572f9a 100644 --- a/src/controller/utils.ts +++ b/src/controller/utils.ts @@ -33,4 +33,8 @@ const removeChildNodes = (element: Element | null) => { } }; -export { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes }; +const makeDelay = async (ms: number) => { + return new Promise((r) => setTimeout(r, ms)); +}; + +export { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes, makeDelay }; diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index f22112af2..45de5214a 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -49,6 +49,6 @@ const checkTryCount = (tryCountInput: HTMLInputElement): boolean => { return false; } return true; -} +}; export { checkCarNames, checkTryCount }; diff --git a/src/index.ts b/src/index.ts index 353c138d7..984c3d83e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,9 @@ -import { setEventListener } from './controller/observer.js'; import { renderInputSection } from './view/renderer.js'; +import { setInputButtonsEventListener } from './controller/event.js'; const app = (): void => { renderInputSection(); - setEventListener(); + setInputButtonsEventListener(); }; app(); diff --git a/src/model/car.ts b/src/model/car.ts index 1ef2c0dc2..a3f6da704 100644 --- a/src/model/car.ts +++ b/src/model/car.ts @@ -14,4 +14,4 @@ class Car { } } -export { Car }; \ No newline at end of file +export { Car }; diff --git a/src/model/game.ts b/src/model/game.ts index 7ae280d02..8cab3e116 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -32,7 +32,7 @@ class Game { initRoundWinnersIndex = (): void => { this.roundWinnersIndex = []; - } + }; getWinners = (): Array => { this.cars.forEach((car) => { diff --git a/src/model/index.ts b/src/model/index.ts index 8ef7e4324..b7af6d7f6 100644 --- a/src/model/index.ts +++ b/src/model/index.ts @@ -1,3 +1,2 @@ export { Car } from './car.js'; - export { Game } from './game.js'; \ No newline at end of file diff --git a/src/view/renderer.ts b/src/view/renderer.ts index d35967bf9..17b83f242 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,11 +1,12 @@ +import { ID } from '../constants/index.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { - document.getElementById('app')!.innerHTML = inputSection(); + document.getElementById(ID.APP_DIV)!.innerHTML = inputSection(); }; const renderProgressSection = (): void => { - document.getElementById('app')!.insertAdjacentHTML(`beforeend`, progressSection()); + document.getElementById(ID.APP_DIV)!.insertAdjacentHTML(`beforeend`, progressSection()); }; const renderCarNameDiv = (element: Element, carName: string): void => { @@ -21,7 +22,7 @@ const renderArrowDiv = (element: Element): void => { }; const renderResultSection = (winners: string): void => { - document.getElementById('app')!.insertAdjacentHTML(`beforeend`, resultSection(winners)); + document.getElementById(ID.APP_DIV)!.insertAdjacentHTML(`beforeend`, resultSection(winners)); }; export { diff --git a/src/view/templates/index.ts b/src/view/templates/index.ts index 5f459f4e4..485004e86 100644 --- a/src/view/templates/index.ts +++ b/src/view/templates/index.ts @@ -1,5 +1,3 @@ export { inputSection } from './input-section.js'; - export { progressSection, carNameDiv, spinnerDiv, arrowDiv } from './progress-section.js'; - export { resultSection } from './result-section.js'; \ No newline at end of file diff --git a/src/view/templates/input-section.ts b/src/view/templates/input-section.ts index c07b33cd2..b7c65782c 100644 --- a/src/view/templates/input-section.ts +++ b/src/view/templates/input-section.ts @@ -9,20 +9,20 @@ const inputSection = (): string => { μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH

- +

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

- - + +
`; -} +}; export { inputSection }; diff --git a/src/view/templates/progress-section.ts b/src/view/templates/progress-section.ts index e046aebbf..d026bf652 100644 --- a/src/view/templates/progress-section.ts +++ b/src/view/templates/progress-section.ts @@ -5,15 +5,15 @@ const progressSection = (): string => {
`; -} +}; const carNameDiv = (carName: string): string => { return `
${carName}
- ` -} + `; +}; const spinnerDiv = (): string => { return ` @@ -22,13 +22,13 @@ const spinnerDiv = (): string => { - ` -} + `; +}; const arrowDiv = (): string => { return `
⬇️️
- ` -} + `; +}; export { progressSection, carNameDiv, spinnerDiv, arrowDiv }; diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts index 00697ac01..6e3571e68 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/templates/result-section.ts @@ -9,6 +9,6 @@ const resultSection = (winners: string): string => { `; -} +}; export { resultSection }; From feb759bc87d61f729e42c1e58a895831f73453f4 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 18:22:17 +0900 Subject: [PATCH 34/70] =?UTF-8?q?feat:=20git=20page=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20=EC=9C=84=ED=95=9C=20dist=20=EC=97=85=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- dist/constants/alert.js | 11 +++ dist/constants/elements.js | 10 +++ dist/constants/index.js | 2 + dist/controller/event.js | 9 ++ dist/controller/linstener.js | 52 ++++++++++++ dist/controller/observer.js | 58 +++++++++++++ dist/controller/player.js | 48 +++++++++++ dist/controller/utils.js | 44 ++++++++++ dist/controller/validtor.js | 51 +++++++++++ dist/css/index.css | 37 ++++++++ dist/css/shared/button.css | 18 ++++ dist/css/shared/layout.css | 108 ++++++++++++++++++++++++ dist/css/shared/sizing.css | 4 + dist/css/shared/typhography.css | 15 ++++ dist/css/ui/spinner.css | 29 +++++++ dist/index.js | 7 ++ dist/model/car.js | 11 +++ dist/model/game.js | 36 ++++++++ dist/model/index.js | 2 + dist/view/renderer.js | 21 +++++ dist/view/templates/index.js | 3 + dist/view/templates/input-section.js | 27 ++++++ dist/view/templates/progress-section.js | 30 +++++++ dist/view/templates/result-section.js | 13 +++ 25 files changed, 647 insertions(+), 1 deletion(-) create mode 100644 dist/constants/alert.js create mode 100644 dist/constants/elements.js create mode 100644 dist/constants/index.js create mode 100644 dist/controller/event.js create mode 100644 dist/controller/linstener.js create mode 100644 dist/controller/observer.js create mode 100644 dist/controller/player.js create mode 100644 dist/controller/utils.js create mode 100644 dist/controller/validtor.js create mode 100644 dist/css/index.css create mode 100644 dist/css/shared/button.css create mode 100644 dist/css/shared/layout.css create mode 100644 dist/css/shared/sizing.css create mode 100644 dist/css/shared/typhography.css create mode 100644 dist/css/ui/spinner.css create mode 100644 dist/index.js create mode 100644 dist/model/car.js create mode 100644 dist/model/game.js create mode 100644 dist/model/index.js create mode 100644 dist/view/renderer.js create mode 100644 dist/view/templates/index.js create mode 100644 dist/view/templates/input-section.js create mode 100644 dist/view/templates/progress-section.js create mode 100644 dist/view/templates/result-section.js diff --git a/.gitignore b/.gitignore index 6ac8f096f..97b818cef 100644 --- a/.gitignore +++ b/.gitignore @@ -195,7 +195,7 @@ typings/ # Nuxt.js build / generate output .nuxt -dist +# dist # Gatsby files .cache/ diff --git a/dist/constants/alert.js b/dist/constants/alert.js new file mode 100644 index 000000000..2c3f61c72 --- /dev/null +++ b/dist/constants/alert.js @@ -0,0 +1,11 @@ +const ALERT = { + CAR_INPUT_EMPTY: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”', + CAR_INPUT_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•˜μ„Έμš”', + CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', + CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', + TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', + TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', + CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘' +}; +export { ALERT }; diff --git a/dist/constants/elements.js b/dist/constants/elements.js new file mode 100644 index 000000000..8902342df --- /dev/null +++ b/dist/constants/elements.js @@ -0,0 +1,10 @@ +const ID = { + APP_DIV: 'app', + CAR_NAME_DIV: '.mt-4.d-flex', + SPINNER_DIV: 'div.mr-2', + CAR_NAME_INPUT: 'car-names-input', + CAR_NAME_SUBMIT: 'car-names-submit', + RACING_COUNT_INPUT: 'racing-count-input', + RACING_COUNT_SUBMIT: 'racing-count-submit', +}; +export { ID }; diff --git a/dist/constants/index.js b/dist/constants/index.js new file mode 100644 index 000000000..f57281eaf --- /dev/null +++ b/dist/constants/index.js @@ -0,0 +1,2 @@ +export { ALERT } from './alert.js'; +export { ID } from './elements.js'; diff --git a/dist/controller/event.js b/dist/controller/event.js new file mode 100644 index 000000000..0a8f19316 --- /dev/null +++ b/dist/controller/event.js @@ -0,0 +1,9 @@ +import { getCarNames, getTryCount, initGame } from './linstener.js'; +const setInputButtonsEventListener = () => { + document.getElementById('car-names-submit').addEventListener('click', () => getCarNames()); + document.getElementById('racing-count-submit').addEventListener('click', () => getTryCount()); +}; +const setRetryButtonEventListener = () => { + document.getElementById('retry-button').addEventListener('click', () => initGame()); +}; +export { setInputButtonsEventListener, setRetryButtonEventListener }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js new file mode 100644 index 000000000..950a13795 --- /dev/null +++ b/dist/controller/linstener.js @@ -0,0 +1,52 @@ +import { startGame } from './player.js'; +import { ID } from '../constants/index.js'; +import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; +import { setInputButtonsEventListener } from './event.js'; +import { checkCarNames, checkTryCount } from './validtor.js'; +import { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; +const getCarNames = () => { + const carNameInput = document.getElementById(ID.CAR_NAME_INPUT); + const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); + if (checkCarNames(carNameInput, carNameArray)) { + const carNameSubmitButton = document.getElementById(ID.CAR_NAME_SUBMIT); + const tryCountInput = document.getElementById(ID.RACING_COUNT_INPUT); + const tryCountSubmitButton = document.getElementById(ID.RACING_COUNT_SUBMIT); + toggleInputValueDisabled(carNameInput); + toggleClickButtonDisabled(carNameSubmitButton); + toggleInputValueDisabled(tryCountInput); + toggleClickButtonDisabled(tryCountSubmitButton); + tryCountInput.focus(); + return; + } + clearInput(carNameInput); +}; +const getTryCount = () => { + const tryCountInput = document.getElementById(ID.RACING_COUNT_INPUT); + const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); + if (checkTryCount(tryCountInput)) { + const carNameInput = document.getElementById(ID.CAR_NAME_INPUT); + const tryCountSubmitButton = document.getElementById(ID.RACING_COUNT_SUBMIT); + const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); + toggleInputValueDisabled(tryCountInput); + toggleClickButtonDisabled(tryCountSubmitButton); + setupProgressSection(carNameArray); + startGame(carNameArray, tryCount); + return; + } + clearInput(tryCountInput); +}; +const setupProgressSection = (carNameArray) => { + renderProgressSection(); + carNameArray.forEach((carName) => { + renderCarNameDiv($(ID.CAR_NAME_DIV), carName); + }); // 이름 div 생성 + $$(ID.SPINNER_DIV).forEach((element) => { + renderSpinnerDiv(element); + }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 +}; +const initGame = () => { + removeChildNodes(document.getElementById(ID.APP_DIV)); + renderInputSection(); + setInputButtonsEventListener(); +}; +export { getCarNames, getTryCount, initGame }; diff --git a/dist/controller/observer.js b/dist/controller/observer.js new file mode 100644 index 000000000..19833d9b0 --- /dev/null +++ b/dist/controller/observer.js @@ -0,0 +1,58 @@ +import { checkCarNames, checkTryCount } from './validtor.js'; +import { clearInput, toggleInputValueDisabled, toggleClickButtonDisabled } from './utils.js'; +import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; +import { startGame } from './player.js'; +import { $, $$, removeChildNodes } from './utils.js'; +const initProgressSection = (carNameArray) => { + renderProgressSection(); + carNameArray.forEach((carName) => { + renderCarNameDiv($('.mt-4.d-flex'), carName); + }); // 이름 div 생성 + $$('div.mr-2').forEach((element) => { + renderSpinnerDiv(element); + }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 +}; +const getCarNames = () => { + const carNameInput = document.getElementById('car-names-input'); + const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); + if (checkCarNames(carNameInput, carNameArray)) { + const carNameSubmitButton = document.getElementById('car-names-submit'); + const tryCountInput = document.getElementById('racing-count-input'); + const tryCountSubmitButton = document.getElementById('racing-count-submit'); + toggleInputValueDisabled(carNameInput); + toggleClickButtonDisabled(carNameSubmitButton); + toggleInputValueDisabled(tryCountInput); + toggleClickButtonDisabled(tryCountSubmitButton); + tryCountInput.focus(); + return; + } + clearInput(carNameInput); +}; +const getTryCount = () => { + const tryCountInput = document.getElementById('racing-count-input'); + const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); + if (checkTryCount(tryCountInput)) { + const carNameInput = document.getElementById('car-names-input'); + const tryCountSubmitButton = document.getElementById('racing-count-submit'); + const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); + toggleInputValueDisabled(tryCountInput); + toggleClickButtonDisabled(tryCountSubmitButton); + initProgressSection(carNameArray); + startGame(carNameArray, tryCount); + return; + } + clearInput(tryCountInput); +}; +function initGame() { + removeChildNodes(document.getElementById('app')); + renderInputSection(); + setInputButtonsEventListener(); +} +const setInputButtonsEventListener = () => { + document.getElementById('car-names-submit').addEventListener('click', () => getCarNames()); + document.getElementById('racing-count-submit').addEventListener('click', () => getTryCount()); +}; +const setReytyButtonEventListener = () => { + document.getElementById('retry-button').addEventListener('click', () => initGame()); +}; +export { setInputButtonsEventListener, setReytyButtonEventListener }; diff --git a/dist/controller/player.js b/dist/controller/player.js new file mode 100644 index 000000000..4fb94ddc5 --- /dev/null +++ b/dist/controller/player.js @@ -0,0 +1,48 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { ALERT } from '../constants/alert.js'; +import { Car, Game } from '../model/index.js'; +import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; +import { setRetryButtonEventListener } from './event.js'; +import { $$, makeDelay } from './utils.js'; +const createCarsObject = (carNameArray) => { + let cars = []; + carNameArray.forEach((car, index) => { + cars.push(new Car(car, index)); + }); + return cars; +}; +const playGameOnce = (racingGame) => { + racingGame.play(); + $$('div.car-player').forEach((element, index) => { + racingGame.cars.forEach((car) => { + racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { + if (car.index === index && car.index === roundWinnerIndex) { + renderArrowDiv(element); + } + }); + }); + }); + racingGame.initRoundWinnersIndex(); +}; +const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { + const racingGame = new Game(createCarsObject(carNameArray)); + for (let index = 0; index < tryCount; index += 1) { + yield makeDelay(1000).then(() => playGameOnce(racingGame)); + } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ + $$('div.d-flex.justify-center.mt-3').forEach((element) => { + element.remove(); + }); // κ²Œμž„ λλ‚˜λ©΄ spinner 제거 + const racingWinners = racingGame.getWinners(); + renderResultSection(racingWinners.join(', ').toLowerCase()); + yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + setRetryButtonEventListener(); +}); +export { startGame }; diff --git a/dist/controller/utils.js b/dist/controller/utils.js new file mode 100644 index 000000000..3ee61a684 --- /dev/null +++ b/dist/controller/utils.js @@ -0,0 +1,44 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +const $ = (selector) => document.querySelector(selector); +const $$ = (selector) => document.querySelectorAll(selector); +const clearInput = (element) => { + element.value = ''; + element.focus(); +}; +const toggleInputValueDisabled = (element) => { + if (element.disabled) { + element.disabled = false; + } + else { + element.disabled = true; + } +}; +const toggleClickButtonDisabled = (element) => { + if (element.disabled) { + element.disabled = false; + } + else { + element.disabled = true; + } +}; +const removeChildNodes = (element) => { + if (element) { + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } + } +}; +const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { + return new Promise((r) => setTimeout(r, ms)); +}); +export { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes, makeDelay }; diff --git a/dist/controller/validtor.js b/dist/controller/validtor.js new file mode 100644 index 000000000..c66344275 --- /dev/null +++ b/dist/controller/validtor.js @@ -0,0 +1,51 @@ +import { ALERT } from '../constants/index.js'; +const checkEmptyInput = (input) => { + return input.value.trim() === ''; +}; +const checkElementsAlone = (array) => { + return array.length < 2; +}; +const checkElementsDouble = (array) => { + return array.some((x) => { + return array.indexOf(x) !== array.lastIndexOf(x); + }); +}; +const checkElementsLength = (array) => { + for (let index = 0; index < array.length; index += 1) { + if (array[index].length > 5) { + return true; + } + } + return false; +}; +const checkCarNames = (carNameInput, carNameArray) => { + if (checkEmptyInput(carNameInput)) { + alert(ALERT.CAR_INPUT_EMPTY); + return false; + } + else if (checkElementsAlone(carNameArray)) { + alert(ALERT.CAR_INPUT_ALONE); + return false; + } + else if (checkElementsDouble(carNameArray)) { + alert(ALERT.CAR_INPUT_DOUBLE); + return false; + } + else if (checkElementsLength(carNameArray)) { + alert(ALERT.CAR_INPUT_LENGTH); + return false; + } + return true; +}; +const checkTryCount = (tryCountInput) => { + if (checkEmptyInput(tryCountInput)) { + alert(ALERT.TRY_INPUT_EMPTY); + return false; + } + else if (Number(tryCountInput.value) > 20) { + alert(ALERT.TRY_INPUT_TOO_BIG); + return false; + } + return true; +}; +export { checkCarNames, checkTryCount }; diff --git a/dist/css/index.css b/dist/css/index.css new file mode 100644 index 000000000..4b1abf762 --- /dev/null +++ b/dist/css/index.css @@ -0,0 +1,37 @@ +@import './shared/button.css'; +@import './shared/layout.css'; +@import './shared/sizing.css'; +@import './shared/typhography.css'; +@import './ui/spinner.css'; + +html, +body { + margin: 0; + height: 100%; +} + +.car-player { + height: 36px; + min-width: 64px; + padding: 0 16px; + border-radius: 4px; + outline: 0; + border-style: none; + background-color: #f5f5f5; + display: inline-flex; + font-weight: bold; + align-items: center; + justify-content: center; + position: relative; +} + +.forward-icon { + font-size: 32px; + display: flex; + justify-content: center; +} + +fieldset { + border: none; + padding: 0; +} diff --git a/dist/css/shared/button.css b/dist/css/shared/button.css new file mode 100644 index 000000000..8ac62188f --- /dev/null +++ b/dist/css/shared/button.css @@ -0,0 +1,18 @@ +.btn { + height: 36px; + min-width: 64px; + padding: 0 16px; + border-radius: 4px; + outline: 0; + border-style: none; + cursor: pointer; +} + +.btn-cyan { + background-color: #00bcd4 !important; + border-color: #00bcd4 !important; +} + +.btn.btn-cyan:hover { + background-color: #018c9e !important; +} diff --git a/dist/css/shared/layout.css b/dist/css/shared/layout.css new file mode 100644 index 000000000..fd606258c --- /dev/null +++ b/dist/css/shared/layout.css @@ -0,0 +1,108 @@ +/* Layout - Position */ +.relative { + position: relative; +} + +.absolute { + position: absolute; +} + +.fixed { + position: fixed; +} + +/* Layout - Display */ +.d-flex { + display: flex; +} + +.d-block { + display: block; +} + +.d-inline { + display: inline; +} + +.d-inline-block { + display: inline-block; +} + +/* Layout - Top / Right / Bottom / Left */ + +.mt-2 { + margin-top: 8px; +} + +.mt-3 { + margin-top: 12px; +} + +.mt-4 { + margin-top: 16px; +} + +.mt-5 { + margin-top: 20px; +} + +.mr-2 { + margin-right: 8px; +} + +/* Box Alignment - Justify Content*/ +.justify-start { + justify-content: flex-start; +} +.justify-end { + justify-content: flex-end; +} +.justify-center { + justify-content: center; +} +.justify-between { + justify-content: space-between; +} +.justify-around { + justify-content: space-around; +} +.justify-evenly { + justify-content: space-evenly; +} + +/* Box Alignment - Align Items*/ +.items-start { + align-items: flex-start; +} +.items-end { + align-items: flex-end; +} +.items-center { + align-items: center; +} +.items-baseline { + align-items: baseline; +} +.items-stretch { + align-items: stretch; +} + +/* Box Alignment - Align Content*/ +.content-center { + align-content: center; +} +.content-start { + align-content: flex-start; +} +.content-end { + align-content: flex-end; +} +.content-between { + align-content: space-between; +} +.content-around { + align-content: space-around; +} +.content-evenly { + align-content: space-around; +} diff --git a/dist/css/shared/sizing.css b/dist/css/shared/sizing.css new file mode 100644 index 000000000..f54111a87 --- /dev/null +++ b/dist/css/shared/sizing.css @@ -0,0 +1,4 @@ +/* Sizing - Width */ +.w-100 { + width: 100%; +} diff --git a/dist/css/shared/typhography.css b/dist/css/shared/typhography.css new file mode 100644 index 000000000..2fd678db5 --- /dev/null +++ b/dist/css/shared/typhography.css @@ -0,0 +1,15 @@ +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-justify { + text-align: justify; +} diff --git a/dist/css/ui/spinner.css b/dist/css/ui/spinner.css new file mode 100644 index 000000000..f3d4909b2 --- /dev/null +++ b/dist/css/ui/spinner.css @@ -0,0 +1,29 @@ +.spinner-container { + width: 25px; + height: 25px; +} + +.spinner::after { + content: ''; + box-sizing: border-box; + width: 25px; + height: 25px; + left: 0; + top: 0; + position: absolute; + border-radius: 50%; +} + +.spinner.material::after { + border-top: 4px solid rgba(0, 191, 215, 1); + border-left: 4px solid rgba(0, 191, 215, 1); + border-bottom: 4px solid rgba(0, 191, 215, 1); + border-right: 4px solid rgba(0, 191, 215, 0); + animation: spinner 0.6s linear infinite; +} + +@keyframes spinner { + to { + transform: rotate(360deg); + } +} diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 000000000..aa684612e --- /dev/null +++ b/dist/index.js @@ -0,0 +1,7 @@ +import { renderInputSection } from './view/renderer.js'; +import { setInputButtonsEventListener } from './controller/event.js'; +const app = () => { + renderInputSection(); + setInputButtonsEventListener(); +}; +app(); diff --git a/dist/model/car.js b/dist/model/car.js new file mode 100644 index 000000000..ab30135a0 --- /dev/null +++ b/dist/model/car.js @@ -0,0 +1,11 @@ +class Car { + constructor(name, index) { + this.name = name; + this.position = 0; + this.index = index; + } + moveForward() { + this.position += 1; + } +} +export { Car }; diff --git a/dist/model/game.js b/dist/model/game.js new file mode 100644 index 000000000..c080b0638 --- /dev/null +++ b/dist/model/game.js @@ -0,0 +1,36 @@ +class Game { + constructor(cars) { + this.play = () => { + this.cars.forEach((car) => { + if (Math.floor(Math.random() * 9) + 1 >= 4) { + car.moveForward(); + this.roundWinnersIndex.push(car.index); + this.updateMaxPosition(); + } + }); + }; + this.updateMaxPosition = () => { + this.cars.forEach((car) => { + if (car.position > this.maxPosition) { + this.maxPosition = car.position; + } + }); + }; + this.initRoundWinnersIndex = () => { + this.roundWinnersIndex = []; + }; + this.getWinners = () => { + this.cars.forEach((car) => { + if (car.position === this.maxPosition) { + this.finalWinners.push(car.name); + } + }); + return this.finalWinners; + }; + this.cars = cars; + this.finalWinners = []; + this.roundWinnersIndex = []; + this.maxPosition = 0; + } +} +export { Game }; diff --git a/dist/model/index.js b/dist/model/index.js new file mode 100644 index 000000000..313573f01 --- /dev/null +++ b/dist/model/index.js @@ -0,0 +1,2 @@ +export { Car } from './car.js'; +export { Game } from './game.js'; diff --git a/dist/view/renderer.js b/dist/view/renderer.js new file mode 100644 index 000000000..c0253dbdd --- /dev/null +++ b/dist/view/renderer.js @@ -0,0 +1,21 @@ +import { ID } from '../constants/index.js'; +import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; +const renderInputSection = () => { + document.getElementById(ID.APP_DIV).innerHTML = inputSection(); +}; +const renderProgressSection = () => { + document.getElementById(ID.APP_DIV).insertAdjacentHTML(`beforeend`, progressSection()); +}; +const renderCarNameDiv = (element, carName) => { + element.insertAdjacentHTML(`beforeend`, carNameDiv(carName)); +}; +const renderSpinnerDiv = (element) => { + element.insertAdjacentHTML(`beforeend`, spinnerDiv()); +}; +const renderArrowDiv = (element) => { + element.insertAdjacentHTML(`afterend`, arrowDiv()); +}; +const renderResultSection = (winners) => { + document.getElementById(ID.APP_DIV).insertAdjacentHTML(`beforeend`, resultSection(winners)); +}; +export { renderInputSection, renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderArrowDiv, renderResultSection, }; diff --git a/dist/view/templates/index.js b/dist/view/templates/index.js new file mode 100644 index 000000000..bbce73e91 --- /dev/null +++ b/dist/view/templates/index.js @@ -0,0 +1,3 @@ +export { inputSection } from './input-section.js'; +export { progressSection, carNameDiv, spinnerDiv, arrowDiv } from './progress-section.js'; +export { resultSection } from './result-section.js'; diff --git a/dist/view/templates/input-section.js b/dist/view/templates/input-section.js new file mode 100644 index 000000000..b071372fd --- /dev/null +++ b/dist/view/templates/input-section.js @@ -0,0 +1,27 @@ +const inputSection = () => { + return ` +
+
+
+

🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„

+

+ 5자 μ΄ν•˜μ˜ μžλ™μ°¨ 이름을 콀마둜 κ΅¬λΆ„ν•˜μ—¬ μž…λ ₯ν•΄μ£Όμ„Έμš”.
+ μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH +

+
+ + +
+
+
+

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

+
+ + +
+
+
+
+ `; +}; +export { inputSection }; diff --git a/dist/view/templates/progress-section.js b/dist/view/templates/progress-section.js new file mode 100644 index 000000000..355284e6c --- /dev/null +++ b/dist/view/templates/progress-section.js @@ -0,0 +1,30 @@ +const progressSection = () => { + return ` +
+
+
+
+ `; +}; +const carNameDiv = (carName) => { + return ` +
+
${carName}
+
+ `; +}; +const spinnerDiv = () => { + return ` +
+
+ +
+
+ `; +}; +const arrowDiv = () => { + return ` +
⬇️️
+ `; +}; +export { progressSection, carNameDiv, spinnerDiv, arrowDiv }; diff --git a/dist/view/templates/result-section.js b/dist/view/templates/result-section.js new file mode 100644 index 000000000..cadcecdd5 --- /dev/null +++ b/dist/view/templates/result-section.js @@ -0,0 +1,13 @@ +const resultSection = (winners) => { + return ` +
+
+

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

+
+ +
+
+
+ `; +}; +export { resultSection }; From 7fb9c40334031fce10f4c9701c4d6247004f8d0b Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 18:25:08 +0900 Subject: [PATCH 35/70] =?UTF-8?q?feat:=20import=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controller/player.ts b/src/controller/player.ts index 2ef41cd7e..fa6febd42 100644 --- a/src/controller/player.ts +++ b/src/controller/player.ts @@ -1,4 +1,4 @@ -import { ALERT } from '../constants/alert.js'; +import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRetryButtonEventListener } from './event.js'; From d8f41902b43658f975c327153df244da10a019c3 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 18:29:35 +0900 Subject: [PATCH 36/70] =?UTF-8?q?refactor:=20=ED=95=A8=EC=88=98=EB=AA=85,?= =?UTF-8?q?=20=EB=B3=80=EC=88=98=EB=AA=85=20=EC=9D=BC=EB=B6=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/event.ts | 6 +++--- src/controller/linstener.ts | 6 +++--- src/controller/{player.ts => play.ts} | 8 ++++---- src/index.ts | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) rename src/controller/{player.ts => play.ts} (87%) diff --git a/src/controller/event.ts b/src/controller/event.ts index 8450cb293..b8022980e 100644 --- a/src/controller/event.ts +++ b/src/controller/event.ts @@ -1,12 +1,12 @@ import { getCarNames, getTryCount, initGame } from './linstener.js'; -const setInputButtonsEventListener = (): void => { +const setInputButtonsEvent = (): void => { document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); document.getElementById('racing-count-submit')!.addEventListener('click', () => getTryCount()); }; -const setRetryButtonEventListener = (): void => { +const setRetryButtonEvent = (): void => { document.getElementById('retry-button')!.addEventListener('click', () => initGame()); }; -export { setInputButtonsEventListener, setRetryButtonEventListener }; +export { setInputButtonsEvent, setRetryButtonEvent }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index ae34aa7bb..e28e8df2c 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -1,7 +1,7 @@ -import { startGame } from './player.js'; +import { startGame } from './play.js'; import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; -import { setInputButtonsEventListener } from './event.js'; +import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; import { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; @@ -59,7 +59,7 @@ const setupProgressSection = (carNameArray: Array) => { const initGame = (): void => { removeChildNodes(document.getElementById(ID.APP_DIV)); renderInputSection(); - setInputButtonsEventListener(); + setInputButtonsEvent(); }; export { getCarNames, getTryCount, initGame }; diff --git a/src/controller/player.ts b/src/controller/play.ts similarity index 87% rename from src/controller/player.ts rename to src/controller/play.ts index fa6febd42..06cbf4f8d 100644 --- a/src/controller/player.ts +++ b/src/controller/play.ts @@ -1,7 +1,7 @@ import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRetryButtonEventListener } from './event.js'; +import { setRetryButtonEvent } from './event.js'; import { $$, makeDelay } from './utils.js'; const createCarsObject = (carNameArray: Array) => { @@ -13,7 +13,7 @@ const createCarsObject = (carNameArray: Array) => { return cars; }; -const playGameOnce = (racingGame: Game) => { +const playOnce = (racingGame: Game) => { racingGame.play(); $$('div.car-player').forEach((element, index) => { racingGame.cars.forEach((car) => { @@ -31,7 +31,7 @@ const startGame = async (carNameArray: Array, tryCount: number) => { const racingGame: Game = new Game(createCarsObject(carNameArray)); for (let index = 0; index < tryCount; index += 1) { - await makeDelay(1000).then(() => playGameOnce(racingGame)); + await makeDelay(1000).then(() => playOnce(racingGame)); } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ $$('div.d-flex.justify-center.mt-3').forEach((element) => { element.remove(); @@ -39,7 +39,7 @@ const startGame = async (carNameArray: Array, tryCount: number) => { const racingWinners: Array = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); await makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - setRetryButtonEventListener(); + setRetryButtonEvent(); }; export { startGame }; diff --git a/src/index.ts b/src/index.ts index 984c3d83e..cc20e8b6c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,9 @@ import { renderInputSection } from './view/renderer.js'; -import { setInputButtonsEventListener } from './controller/event.js'; +import { setInputButtonsEvent } from './controller/event.js'; const app = (): void => { renderInputSection(); - setInputButtonsEventListener(); + setInputButtonsEvent(); }; app(); From 94b5eaee8504be1c516364550c4e1fc713ff725a Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 18:39:21 +0900 Subject: [PATCH 37/70] =?UTF-8?q?feat:=20=EC=8B=9C=EB=8F=84=20=ED=9A=9F?= =?UTF-8?q?=EC=88=98=EC=97=90=20=EC=9D=8C=EC=88=98=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/alert.ts | 1 + src/controller/validtor.ts | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/constants/alert.ts b/src/constants/alert.ts index 5460fb075..3b8a6452c 100644 --- a/src/constants/alert.ts +++ b/src/constants/alert.ts @@ -6,6 +6,7 @@ const ALERT = { CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', + TRY_INPUT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (20 μ΄ν•˜ ꢌμž₯)', TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index 45de5214a..69c4a0e22 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -44,6 +44,9 @@ const checkTryCount = (tryCountInput: HTMLInputElement): boolean => { if (checkEmptyInput(tryCountInput)) { alert(ALERT.TRY_INPUT_EMPTY); return false; + } else if (Number(tryCountInput.value) < 1) { + alert(ALERT.TRY_INPUT_UINT); + return false; } else if (Number(tryCountInput.value) > 20) { alert(ALERT.TRY_INPUT_TOO_BIG); return false; From 14ced3d5b0429cde40b1737c269138bbd231cbfe Mon Sep 17 00:00:00 2001 From: jwon42 Date: Sat, 5 Jun 2021 18:41:33 +0900 Subject: [PATCH 38/70] =?UTF-8?q?feat:=20=EC=BB=B4=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=90=9C=20dist=ED=8F=B4=EB=8D=94=20=EA=B0=B1=EC=8B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/alert.js | 3 +- dist/constants/index.js | 2 +- dist/controller/event.js | 6 +- dist/controller/linstener.js | 6 +- dist/controller/observer.js | 58 ------------- dist/controller/{player.js => play.js} | 10 +-- dist/controller/validtor.js | 4 + dist/index.js | 4 +- src/css/index.css | 37 --------- src/css/shared/button.css | 18 ----- src/css/shared/layout.css | 108 ------------------------- src/css/shared/sizing.css | 4 - src/css/shared/typhography.css | 15 ---- src/css/ui/spinner.css | 29 ------- 14 files changed, 20 insertions(+), 284 deletions(-) delete mode 100644 dist/controller/observer.js rename dist/controller/{player.js => play.js} (89%) delete mode 100644 src/css/index.css delete mode 100644 src/css/shared/button.css delete mode 100644 src/css/shared/layout.css delete mode 100644 src/css/shared/sizing.css delete mode 100644 src/css/shared/typhography.css delete mode 100644 src/css/ui/spinner.css diff --git a/dist/constants/alert.js b/dist/constants/alert.js index 2c3f61c72..110072a82 100644 --- a/dist/constants/alert.js +++ b/dist/constants/alert.js @@ -5,7 +5,8 @@ const ALERT = { CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', + TRY_INPUT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (20 μ΄ν•˜ ꢌμž₯)', TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', - CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘' + CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', }; export { ALERT }; diff --git a/dist/constants/index.js b/dist/constants/index.js index f57281eaf..430e88113 100644 --- a/dist/constants/index.js +++ b/dist/constants/index.js @@ -1,2 +1,2 @@ -export { ALERT } from './alert.js'; export { ID } from './elements.js'; +export { ALERT } from './alert.js'; diff --git a/dist/controller/event.js b/dist/controller/event.js index 0a8f19316..a47604932 100644 --- a/dist/controller/event.js +++ b/dist/controller/event.js @@ -1,9 +1,9 @@ import { getCarNames, getTryCount, initGame } from './linstener.js'; -const setInputButtonsEventListener = () => { +const setInputButtonsEvent = () => { document.getElementById('car-names-submit').addEventListener('click', () => getCarNames()); document.getElementById('racing-count-submit').addEventListener('click', () => getTryCount()); }; -const setRetryButtonEventListener = () => { +const setRetryButtonEvent = () => { document.getElementById('retry-button').addEventListener('click', () => initGame()); }; -export { setInputButtonsEventListener, setRetryButtonEventListener }; +export { setInputButtonsEvent, setRetryButtonEvent }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 950a13795..3f0153e38 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -1,7 +1,7 @@ -import { startGame } from './player.js'; +import { startGame } from './play.js'; import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; -import { setInputButtonsEventListener } from './event.js'; +import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; import { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; const getCarNames = () => { @@ -47,6 +47,6 @@ const setupProgressSection = (carNameArray) => { const initGame = () => { removeChildNodes(document.getElementById(ID.APP_DIV)); renderInputSection(); - setInputButtonsEventListener(); + setInputButtonsEvent(); }; export { getCarNames, getTryCount, initGame }; diff --git a/dist/controller/observer.js b/dist/controller/observer.js deleted file mode 100644 index 19833d9b0..000000000 --- a/dist/controller/observer.js +++ /dev/null @@ -1,58 +0,0 @@ -import { checkCarNames, checkTryCount } from './validtor.js'; -import { clearInput, toggleInputValueDisabled, toggleClickButtonDisabled } from './utils.js'; -import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; -import { startGame } from './player.js'; -import { $, $$, removeChildNodes } from './utils.js'; -const initProgressSection = (carNameArray) => { - renderProgressSection(); - carNameArray.forEach((carName) => { - renderCarNameDiv($('.mt-4.d-flex'), carName); - }); // 이름 div 생성 - $$('div.mr-2').forEach((element) => { - renderSpinnerDiv(element); - }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 -}; -const getCarNames = () => { - const carNameInput = document.getElementById('car-names-input'); - const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton = document.getElementById('car-names-submit'); - const tryCountInput = document.getElementById('racing-count-input'); - const tryCountSubmitButton = document.getElementById('racing-count-submit'); - toggleInputValueDisabled(carNameInput); - toggleClickButtonDisabled(carNameSubmitButton); - toggleInputValueDisabled(tryCountInput); - toggleClickButtonDisabled(tryCountSubmitButton); - tryCountInput.focus(); - return; - } - clearInput(carNameInput); -}; -const getTryCount = () => { - const tryCountInput = document.getElementById('racing-count-input'); - const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); - if (checkTryCount(tryCountInput)) { - const carNameInput = document.getElementById('car-names-input'); - const tryCountSubmitButton = document.getElementById('racing-count-submit'); - const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - toggleInputValueDisabled(tryCountInput); - toggleClickButtonDisabled(tryCountSubmitButton); - initProgressSection(carNameArray); - startGame(carNameArray, tryCount); - return; - } - clearInput(tryCountInput); -}; -function initGame() { - removeChildNodes(document.getElementById('app')); - renderInputSection(); - setInputButtonsEventListener(); -} -const setInputButtonsEventListener = () => { - document.getElementById('car-names-submit').addEventListener('click', () => getCarNames()); - document.getElementById('racing-count-submit').addEventListener('click', () => getTryCount()); -}; -const setReytyButtonEventListener = () => { - document.getElementById('retry-button').addEventListener('click', () => initGame()); -}; -export { setInputButtonsEventListener, setReytyButtonEventListener }; diff --git a/dist/controller/player.js b/dist/controller/play.js similarity index 89% rename from dist/controller/player.js rename to dist/controller/play.js index 4fb94ddc5..02acf07ec 100644 --- a/dist/controller/player.js +++ b/dist/controller/play.js @@ -7,10 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -import { ALERT } from '../constants/alert.js'; +import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRetryButtonEventListener } from './event.js'; +import { setRetryButtonEvent } from './event.js'; import { $$, makeDelay } from './utils.js'; const createCarsObject = (carNameArray) => { let cars = []; @@ -19,7 +19,7 @@ const createCarsObject = (carNameArray) => { }); return cars; }; -const playGameOnce = (racingGame) => { +const playOnce = (racingGame) => { racingGame.play(); $$('div.car-player').forEach((element, index) => { racingGame.cars.forEach((car) => { @@ -35,7 +35,7 @@ const playGameOnce = (racingGame) => { const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { const racingGame = new Game(createCarsObject(carNameArray)); for (let index = 0; index < tryCount; index += 1) { - yield makeDelay(1000).then(() => playGameOnce(racingGame)); + yield makeDelay(1000).then(() => playOnce(racingGame)); } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ $$('div.d-flex.justify-center.mt-3').forEach((element) => { element.remove(); @@ -43,6 +43,6 @@ const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, const racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - setRetryButtonEventListener(); + setRetryButtonEvent(); }); export { startGame }; diff --git a/dist/controller/validtor.js b/dist/controller/validtor.js index c66344275..ad0599e81 100644 --- a/dist/controller/validtor.js +++ b/dist/controller/validtor.js @@ -42,6 +42,10 @@ const checkTryCount = (tryCountInput) => { alert(ALERT.TRY_INPUT_EMPTY); return false; } + else if (Number(tryCountInput.value) < 1) { + alert(ALERT.TRY_INPUT_UINT); + return false; + } else if (Number(tryCountInput.value) > 20) { alert(ALERT.TRY_INPUT_TOO_BIG); return false; diff --git a/dist/index.js b/dist/index.js index aa684612e..0d4d0962d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,7 +1,7 @@ import { renderInputSection } from './view/renderer.js'; -import { setInputButtonsEventListener } from './controller/event.js'; +import { setInputButtonsEvent } from './controller/event.js'; const app = () => { renderInputSection(); - setInputButtonsEventListener(); + setInputButtonsEvent(); }; app(); diff --git a/src/css/index.css b/src/css/index.css deleted file mode 100644 index 4b1abf762..000000000 --- a/src/css/index.css +++ /dev/null @@ -1,37 +0,0 @@ -@import './shared/button.css'; -@import './shared/layout.css'; -@import './shared/sizing.css'; -@import './shared/typhography.css'; -@import './ui/spinner.css'; - -html, -body { - margin: 0; - height: 100%; -} - -.car-player { - height: 36px; - min-width: 64px; - padding: 0 16px; - border-radius: 4px; - outline: 0; - border-style: none; - background-color: #f5f5f5; - display: inline-flex; - font-weight: bold; - align-items: center; - justify-content: center; - position: relative; -} - -.forward-icon { - font-size: 32px; - display: flex; - justify-content: center; -} - -fieldset { - border: none; - padding: 0; -} diff --git a/src/css/shared/button.css b/src/css/shared/button.css deleted file mode 100644 index 8ac62188f..000000000 --- a/src/css/shared/button.css +++ /dev/null @@ -1,18 +0,0 @@ -.btn { - height: 36px; - min-width: 64px; - padding: 0 16px; - border-radius: 4px; - outline: 0; - border-style: none; - cursor: pointer; -} - -.btn-cyan { - background-color: #00bcd4 !important; - border-color: #00bcd4 !important; -} - -.btn.btn-cyan:hover { - background-color: #018c9e !important; -} diff --git a/src/css/shared/layout.css b/src/css/shared/layout.css deleted file mode 100644 index fd606258c..000000000 --- a/src/css/shared/layout.css +++ /dev/null @@ -1,108 +0,0 @@ -/* Layout - Position */ -.relative { - position: relative; -} - -.absolute { - position: absolute; -} - -.fixed { - position: fixed; -} - -/* Layout - Display */ -.d-flex { - display: flex; -} - -.d-block { - display: block; -} - -.d-inline { - display: inline; -} - -.d-inline-block { - display: inline-block; -} - -/* Layout - Top / Right / Bottom / Left */ - -.mt-2 { - margin-top: 8px; -} - -.mt-3 { - margin-top: 12px; -} - -.mt-4 { - margin-top: 16px; -} - -.mt-5 { - margin-top: 20px; -} - -.mr-2 { - margin-right: 8px; -} - -/* Box Alignment - Justify Content*/ -.justify-start { - justify-content: flex-start; -} -.justify-end { - justify-content: flex-end; -} -.justify-center { - justify-content: center; -} -.justify-between { - justify-content: space-between; -} -.justify-around { - justify-content: space-around; -} -.justify-evenly { - justify-content: space-evenly; -} - -/* Box Alignment - Align Items*/ -.items-start { - align-items: flex-start; -} -.items-end { - align-items: flex-end; -} -.items-center { - align-items: center; -} -.items-baseline { - align-items: baseline; -} -.items-stretch { - align-items: stretch; -} - -/* Box Alignment - Align Content*/ -.content-center { - align-content: center; -} -.content-start { - align-content: flex-start; -} -.content-end { - align-content: flex-end; -} -.content-between { - align-content: space-between; -} -.content-around { - align-content: space-around; -} -.content-evenly { - align-content: space-around; -} diff --git a/src/css/shared/sizing.css b/src/css/shared/sizing.css deleted file mode 100644 index f54111a87..000000000 --- a/src/css/shared/sizing.css +++ /dev/null @@ -1,4 +0,0 @@ -/* Sizing - Width */ -.w-100 { - width: 100%; -} diff --git a/src/css/shared/typhography.css b/src/css/shared/typhography.css deleted file mode 100644 index 2fd678db5..000000000 --- a/src/css/shared/typhography.css +++ /dev/null @@ -1,15 +0,0 @@ -.text-left { - text-align: left; -} - -.text-center { - text-align: center; -} - -.text-right { - text-align: right; -} - -.text-justify { - text-align: justify; -} diff --git a/src/css/ui/spinner.css b/src/css/ui/spinner.css deleted file mode 100644 index f3d4909b2..000000000 --- a/src/css/ui/spinner.css +++ /dev/null @@ -1,29 +0,0 @@ -.spinner-container { - width: 25px; - height: 25px; -} - -.spinner::after { - content: ''; - box-sizing: border-box; - width: 25px; - height: 25px; - left: 0; - top: 0; - position: absolute; - border-radius: 50%; -} - -.spinner.material::after { - border-top: 4px solid rgba(0, 191, 215, 1); - border-left: 4px solid rgba(0, 191, 215, 1); - border-bottom: 4px solid rgba(0, 191, 215, 1); - border-right: 4px solid rgba(0, 191, 215, 0); - animation: spinner 0.6s linear infinite; -} - -@keyframes spinner { - to { - transform: rotate(360deg); - } -} From 566a3b1515ff658f6559e25e3f0ced63ae652168 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 19:01:04 +0900 Subject: [PATCH 39/70] =?UTF-8?q?refactor:=20renderer=EC=97=90=EC=84=9C=20?= =?UTF-8?q?queryselector=EB=A7=8C=20=EC=82=AC=EC=9A=A9=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 20 ++++++++++++++++++++ dist/controller/linstener.js | 13 +++++++------ dist/view/renderer.js | 19 +++++++++++-------- package.json | 2 +- src/controller/linstener.ts | 8 +++----- src/view/renderer.ts | 17 ++++++++++------- 6 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..c5624c4e5 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,20 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": { + } +} diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 3f0153e38..80d86a4dc 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -3,7 +3,7 @@ import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; -import { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; +import { clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; const getCarNames = () => { const carNameInput = document.getElementById(ID.CAR_NAME_INPUT); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); @@ -15,6 +15,7 @@ const getCarNames = () => { toggleClickButtonDisabled(carNameSubmitButton); toggleInputValueDisabled(tryCountInput); toggleClickButtonDisabled(tryCountSubmitButton); + setupProgressSection(carNameArray); tryCountInput.focus(); return; } @@ -29,7 +30,6 @@ const getTryCount = () => { const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); toggleInputValueDisabled(tryCountInput); toggleClickButtonDisabled(tryCountSubmitButton); - setupProgressSection(carNameArray); startGame(carNameArray, tryCount); return; } @@ -38,11 +38,12 @@ const getTryCount = () => { const setupProgressSection = (carNameArray) => { renderProgressSection(); carNameArray.forEach((carName) => { - renderCarNameDiv($(ID.CAR_NAME_DIV), carName); + renderCarNameDiv(carName); }); // 이름 div 생성 - $$(ID.SPINNER_DIV).forEach((element) => { - renderSpinnerDiv(element); - }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 + // $$(ID.SPINNER_DIV).forEach((element) => { + // renderSpinnerDiv(element); + // }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 + renderSpinnerDiv(); }; const initGame = () => { removeChildNodes(document.getElementById(ID.APP_DIV)); diff --git a/dist/view/renderer.js b/dist/view/renderer.js index c0253dbdd..b6426beca 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -1,21 +1,24 @@ -import { ID } from '../constants/index.js'; +import { $, $$ } from '../controller/utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = () => { - document.getElementById(ID.APP_DIV).innerHTML = inputSection(); + $('#app').innerHTML = inputSection(); }; const renderProgressSection = () => { - document.getElementById(ID.APP_DIV).insertAdjacentHTML(`beforeend`, progressSection()); + $('#app').insertAdjacentHTML('beforeend', progressSection()); }; -const renderCarNameDiv = (element, carName) => { - element.insertAdjacentHTML(`beforeend`, carNameDiv(carName)); +const renderCarNameDiv = (carName) => { + $('#progress-section > div').insertAdjacentHTML('beforeend', carNameDiv(carName)); }; -const renderSpinnerDiv = (element) => { - element.insertAdjacentHTML(`beforeend`, spinnerDiv()); +const renderSpinnerDiv = () => { + $$('#progress-section > div > div').forEach((element) => { + element.insertAdjacentHTML(`beforeend`, spinnerDiv()); + }); + // element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }; const renderArrowDiv = (element) => { element.insertAdjacentHTML(`afterend`, arrowDiv()); }; const renderResultSection = (winners) => { - document.getElementById(ID.APP_DIV).insertAdjacentHTML(`beforeend`, resultSection(winners)); + $('#app').insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderInputSection, renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderArrowDiv, renderResultSection, }; diff --git a/package.json b/package.json index 98b705ac2..b21f60bce 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "devDependencies": { "@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/parser": "^4.26.0", - "eslint": "^7.27.0", + "eslint": "^7.28.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.23.4" } diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index e28e8df2c..cb3ccf635 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -20,6 +20,7 @@ const getCarNames = (): void => { toggleClickButtonDisabled(carNameSubmitButton); toggleInputValueDisabled(tryCountInput); toggleClickButtonDisabled(tryCountSubmitButton); + setupProgressSection(carNameArray); tryCountInput.focus(); return; } @@ -39,7 +40,6 @@ const getTryCount = (): void => { toggleInputValueDisabled(tryCountInput); toggleClickButtonDisabled(tryCountSubmitButton); - setupProgressSection(carNameArray); startGame(carNameArray, tryCount); return; } @@ -49,11 +49,9 @@ const getTryCount = (): void => { const setupProgressSection = (carNameArray: Array) => { renderProgressSection(); carNameArray.forEach((carName) => { - renderCarNameDiv($(ID.CAR_NAME_DIV) as Element, carName); + renderCarNameDiv(carName); }); // 이름 div 생성 - $$(ID.SPINNER_DIV).forEach((element) => { - renderSpinnerDiv(element); - }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 + renderSpinnerDiv(); }; const initGame = (): void => { diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 17b83f242..b567d8c9e 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,20 +1,23 @@ import { ID } from '../constants/index.js'; +import { $, $$ } from '../controller/utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { - document.getElementById(ID.APP_DIV)!.innerHTML = inputSection(); + $('#app')!.innerHTML = inputSection(); }; const renderProgressSection = (): void => { - document.getElementById(ID.APP_DIV)!.insertAdjacentHTML(`beforeend`, progressSection()); + $('#app')!.insertAdjacentHTML('beforeend', progressSection()); }; -const renderCarNameDiv = (element: Element, carName: string): void => { - element.insertAdjacentHTML(`beforeend`, carNameDiv(carName)); +const renderCarNameDiv = (carName: string): void => { + $('#progress-section > div')!.insertAdjacentHTML('beforeend', carNameDiv(carName)); }; -const renderSpinnerDiv = (element: Element): void => { - element.insertAdjacentHTML(`beforeend`, spinnerDiv()); +const renderSpinnerDiv = (): void => { + $$('#progress-section > div > div')!.forEach((element) => { + element.insertAdjacentHTML(`beforeend`, spinnerDiv()); + }); }; const renderArrowDiv = (element: Element): void => { @@ -22,7 +25,7 @@ const renderArrowDiv = (element: Element): void => { }; const renderResultSection = (winners: string): void => { - document.getElementById(ID.APP_DIV)!.insertAdjacentHTML(`beforeend`, resultSection(winners)); + $('#app')!.insertAdjacentHTML('beforeend', resultSection(winners)); }; export { From 694f14390b7f93f6f00d558a79e46813295a96b9 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 19:02:56 +0900 Subject: [PATCH 40/70] =?UTF-8?q?refactor:=20game=20class=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=99=94=EC=82=B4=ED=91=9C=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/model/game.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/model/game.ts b/src/model/game.ts index 8cab3e116..fdae9bc4f 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -12,7 +12,7 @@ class Game { this.maxPosition = 0; } - play = (): void => { + play(): void { this.cars.forEach((car) => { if (Math.floor(Math.random() * 9) + 1 >= 4) { car.moveForward(); @@ -22,7 +22,7 @@ class Game { }); }; - updateMaxPosition = (): void => { + updateMaxPosition(): void { this.cars.forEach((car) => { if (car.position > this.maxPosition) { this.maxPosition = car.position; @@ -30,11 +30,11 @@ class Game { }); }; - initRoundWinnersIndex = (): void => { + initRoundWinnersIndex(): void { this.roundWinnersIndex = []; }; - getWinners = (): Array => { + getWinners(): Array { this.cars.forEach((car) => { if (car.position === this.maxPosition) { this.finalWinners.push(car.name); From 9febf27afbd9e30b35957801d44d4cf7e9604e73 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 19:07:36 +0900 Subject: [PATCH 41/70] =?UTF-8?q?refactor:=20removeChildNodes=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EC=97=90=EC=84=9C=20=EB=84=90=EC=B2=B4=ED=81=AC?= =?UTF-8?q?=EB=A5=BC=20=EB=A8=BC=EC=A0=80=20=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/linstener.js | 3 -- dist/controller/utils.js | 11 +++---- dist/model/game.js | 58 +++++++++++++++++++----------------- dist/view/renderer.js | 1 - src/controller/utils.ts | 19 ++++++------ 5 files changed, 47 insertions(+), 45 deletions(-) diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 80d86a4dc..98d1caf10 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -40,9 +40,6 @@ const setupProgressSection = (carNameArray) => { carNameArray.forEach((carName) => { renderCarNameDiv(carName); }); // 이름 div 생성 - // $$(ID.SPINNER_DIV).forEach((element) => { - // renderSpinnerDiv(element); - // }); // κΈ°λ³Έ μŠ€ν”Όλ„ˆ 생성 파트 renderSpinnerDiv(); }; const initGame = () => { diff --git a/dist/controller/utils.js b/dist/controller/utils.js index 3ee61a684..1824f56d8 100644 --- a/dist/controller/utils.js +++ b/dist/controller/utils.js @@ -30,11 +30,12 @@ const toggleClickButtonDisabled = (element) => { } }; const removeChildNodes = (element) => { - if (element) { - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); } } }; diff --git a/dist/model/game.js b/dist/model/game.js index c080b0638..8319d2e57 100644 --- a/dist/model/game.js +++ b/dist/model/game.js @@ -1,36 +1,40 @@ class Game { constructor(cars) { - this.play = () => { - this.cars.forEach((car) => { - if (Math.floor(Math.random() * 9) + 1 >= 4) { - car.moveForward(); - this.roundWinnersIndex.push(car.index); - this.updateMaxPosition(); - } - }); - }; - this.updateMaxPosition = () => { - this.cars.forEach((car) => { - if (car.position > this.maxPosition) { - this.maxPosition = car.position; - } - }); - }; - this.initRoundWinnersIndex = () => { - this.roundWinnersIndex = []; - }; - this.getWinners = () => { - this.cars.forEach((car) => { - if (car.position === this.maxPosition) { - this.finalWinners.push(car.name); - } - }); - return this.finalWinners; - }; this.cars = cars; this.finalWinners = []; this.roundWinnersIndex = []; this.maxPosition = 0; } + play() { + this.cars.forEach((car) => { + if (Math.floor(Math.random() * 9) + 1 >= 4) { + car.moveForward(); + this.roundWinnersIndex.push(car.index); + this.updateMaxPosition(); + } + }); + } + ; + updateMaxPosition() { + this.cars.forEach((car) => { + if (car.position > this.maxPosition) { + this.maxPosition = car.position; + } + }); + } + ; + initRoundWinnersIndex() { + this.roundWinnersIndex = []; + } + ; + getWinners() { + this.cars.forEach((car) => { + if (car.position === this.maxPosition) { + this.finalWinners.push(car.name); + } + }); + return this.finalWinners; + } + ; } export { Game }; diff --git a/dist/view/renderer.js b/dist/view/renderer.js index b6426beca..5412bf2d5 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -13,7 +13,6 @@ const renderSpinnerDiv = () => { $$('#progress-section > div > div').forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); - // element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }; const renderArrowDiv = (element) => { element.insertAdjacentHTML(`afterend`, arrowDiv()); diff --git a/src/controller/utils.ts b/src/controller/utils.ts index bc0572f9a..07b756ba6 100644 --- a/src/controller/utils.ts +++ b/src/controller/utils.ts @@ -2,12 +2,12 @@ const $ = (selector: string): Element | null => document.querySelector(selector) const $$ = (selector: string): NodeListOf => document.querySelectorAll(selector); -const clearInput = (element: HTMLInputElement) => { +const clearInput = (element: HTMLInputElement): void => { element.value = ''; element.focus(); }; -const toggleInputValueDisabled = (element: HTMLInputElement) => { +const toggleInputValueDisabled = (element: HTMLInputElement): void => { if (element.disabled) { element.disabled = false; } else { @@ -15,7 +15,7 @@ const toggleInputValueDisabled = (element: HTMLInputElement) => { } }; -const toggleClickButtonDisabled = (element: HTMLButtonElement) => { +const toggleClickButtonDisabled = (element: HTMLButtonElement): void => { if (element.disabled) { element.disabled = false; } else { @@ -23,12 +23,13 @@ const toggleClickButtonDisabled = (element: HTMLButtonElement) => { } }; -const removeChildNodes = (element: Element | null) => { - if (element) { - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } +const removeChildNodes = (element: Element | null): void => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); } } }; From bed97ec064c4a3f621df0d32bf6fd4c7d61b2f34 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 19:09:07 +0900 Subject: [PATCH 42/70] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20alert=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/alert.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/constants/alert.ts b/src/constants/alert.ts index 3b8a6452c..d6fbe7200 100644 --- a/src/constants/alert.ts +++ b/src/constants/alert.ts @@ -3,7 +3,6 @@ const ALERT = { CAR_INPUT_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•˜μ„Έμš”', CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', - CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', TRY_INPUT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (20 μ΄ν•˜ ꢌμž₯)', From 771cbbcb85508cc8a829279a421d897841d6a254 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 19:27:42 +0900 Subject: [PATCH 43/70] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EC=88=98=EC=A0=95,=20toggle=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EB=B6=84=EB=A6=AC,=20queryselector=20?= =?UTF-8?q?=EB=AF=B8=EC=A0=81=EC=9A=A9=20=EB=B6=80=EB=B6=84=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/alert.js | 1 - dist/controller/event.js | 8 ++-- dist/controller/linstener.js | 38 +++++++++--------- dist/controller/play.js | 6 +-- dist/utils.js | 41 ++++++++++++++++++++ dist/view/renderer.js | 2 +- dist/view/templates/result-section.js | 2 +- src/controller/event.ts | 8 ++-- src/controller/linstener.ts | 55 +++++++++++++++------------ src/controller/play.ts | 6 +-- src/controller/utils.ts | 41 -------------------- src/utils.ts | 51 +++++++++++++++++++++++++ src/view/renderer.ts | 2 +- src/view/templates/result-section.ts | 2 +- 14 files changed, 159 insertions(+), 104 deletions(-) create mode 100644 dist/utils.js delete mode 100644 src/controller/utils.ts create mode 100644 src/utils.ts diff --git a/dist/constants/alert.js b/dist/constants/alert.js index 110072a82..4454fad17 100644 --- a/dist/constants/alert.js +++ b/dist/constants/alert.js @@ -3,7 +3,6 @@ const ALERT = { CAR_INPUT_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•˜μ„Έμš”', CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', - CAR_INPUT_COUNT: '1회 이상이어야 ν•©λ‹ˆλ‹€', TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', TRY_INPUT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (20 μ΄ν•˜ ꢌμž₯)', TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', diff --git a/dist/controller/event.js b/dist/controller/event.js index a47604932..30831adad 100644 --- a/dist/controller/event.js +++ b/dist/controller/event.js @@ -1,9 +1,9 @@ -import { getCarNames, getTryCount, initGame } from './linstener.js'; +import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = () => { document.getElementById('car-names-submit').addEventListener('click', () => getCarNames()); document.getElementById('racing-count-submit').addEventListener('click', () => getTryCount()); }; -const setRetryButtonEvent = () => { - document.getElementById('retry-button').addEventListener('click', () => initGame()); +const setRestartButtonEvent = () => { + document.getElementById('restart-button').addEventListener('click', () => restartApp()); }; -export { setInputButtonsEvent, setRetryButtonEvent }; +export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 98d1caf10..f6be35647 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -3,48 +3,48 @@ import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; -import { clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; +import { $, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, removeChildNodes, } from '../utils.js'; const getCarNames = () => { - const carNameInput = document.getElementById(ID.CAR_NAME_INPUT); + const carNameInput = $('#car-names-input'); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton = document.getElementById(ID.CAR_NAME_SUBMIT); - const tryCountInput = document.getElementById(ID.RACING_COUNT_INPUT); - const tryCountSubmitButton = document.getElementById(ID.RACING_COUNT_SUBMIT); - toggleInputValueDisabled(carNameInput); - toggleClickButtonDisabled(carNameSubmitButton); - toggleInputValueDisabled(tryCountInput); - toggleClickButtonDisabled(tryCountSubmitButton); + const carNameSubmitButton = $('#car-names-submit'); + const tryCountInput = $('#racing-count-input'); + const tryCountSubmitButton = $('#racing-count-submit'); + inputElementDisable(carNameInput); + buttonElementDisable(carNameSubmitButton); + inputElementEnable(tryCountInput); + buttonElementEnable(tryCountSubmitButton); setupProgressSection(carNameArray); tryCountInput.focus(); return; } - clearInput(carNameInput); + inputElementClear(carNameInput); }; const getTryCount = () => { - const tryCountInput = document.getElementById(ID.RACING_COUNT_INPUT); + const tryCountInput = $('#racing-count-input'); const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); if (checkTryCount(tryCountInput)) { - const carNameInput = document.getElementById(ID.CAR_NAME_INPUT); - const tryCountSubmitButton = document.getElementById(ID.RACING_COUNT_SUBMIT); + const carNameInput = $('#car-names-input'); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - toggleInputValueDisabled(tryCountInput); - toggleClickButtonDisabled(tryCountSubmitButton); + const tryCountSubmitButton = $('#racing-count-submit'); + inputElementDisable(tryCountInput); + buttonElementDisable(tryCountSubmitButton); startGame(carNameArray, tryCount); return; } - clearInput(tryCountInput); + inputElementClear(tryCountInput); }; const setupProgressSection = (carNameArray) => { renderProgressSection(); carNameArray.forEach((carName) => { renderCarNameDiv(carName); - }); // 이름 div 생성 + }); renderSpinnerDiv(); }; -const initGame = () => { +const restartApp = () => { removeChildNodes(document.getElementById(ID.APP_DIV)); renderInputSection(); setInputButtonsEvent(); }; -export { getCarNames, getTryCount, initGame }; +export { getCarNames, getTryCount, restartApp }; diff --git a/dist/controller/play.js b/dist/controller/play.js index 02acf07ec..69abb9b8d 100644 --- a/dist/controller/play.js +++ b/dist/controller/play.js @@ -10,8 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRetryButtonEvent } from './event.js'; -import { $$, makeDelay } from './utils.js'; +import { setRestartButtonEvent } from './event.js'; +import { $$, makeDelay } from '../utils.js'; const createCarsObject = (carNameArray) => { let cars = []; carNameArray.forEach((car, index) => { @@ -43,6 +43,6 @@ const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, const racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - setRetryButtonEvent(); + setRestartButtonEvent(); }); export { startGame }; diff --git a/dist/utils.js b/dist/utils.js new file mode 100644 index 000000000..8ac46cfe3 --- /dev/null +++ b/dist/utils.js @@ -0,0 +1,41 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +const $ = (selector) => document.querySelector(selector); +const $$ = (selector) => document.querySelectorAll(selector); +const inputElementClear = (element) => { + element.value = ''; + element.focus(); +}; +const inputElementEnable = (element) => { + element.disabled = false; +}; +const inputElementDisable = (element) => { + element.disabled = true; +}; +const buttonElementEnable = (element) => { + element.disabled = false; +}; +const buttonElementDisable = (element) => { + element.disabled = true; +}; +const removeChildNodes = (element) => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } +}; +const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { + return new Promise((r) => setTimeout(r, ms)); +}); +export { $, $$, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, removeChildNodes, makeDelay, }; diff --git a/dist/view/renderer.js b/dist/view/renderer.js index 5412bf2d5..bdcbae105 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -1,4 +1,4 @@ -import { $, $$ } from '../controller/utils.js'; +import { $, $$ } from '../utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = () => { $('#app').innerHTML = inputSection(); diff --git a/dist/view/templates/result-section.js b/dist/view/templates/result-section.js index cadcecdd5..925f1d1d2 100644 --- a/dist/view/templates/result-section.js +++ b/dist/view/templates/result-section.js @@ -4,7 +4,7 @@ const resultSection = (winners) => {

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

- +
diff --git a/src/controller/event.ts b/src/controller/event.ts index b8022980e..debc528a1 100644 --- a/src/controller/event.ts +++ b/src/controller/event.ts @@ -1,12 +1,12 @@ -import { getCarNames, getTryCount, initGame } from './linstener.js'; +import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = (): void => { document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); document.getElementById('racing-count-submit')!.addEventListener('click', () => getTryCount()); }; -const setRetryButtonEvent = (): void => { - document.getElementById('retry-button')!.addEventListener('click', () => initGame()); +const setRestartButtonEvent = (): void => { + document.getElementById('restart-button')!.addEventListener('click', () => restartApp()); }; -export { setInputButtonsEvent, setRetryButtonEvent }; +export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index cb3ccf635..ad1ba149b 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -3,61 +3,66 @@ import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; -import { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes } from './utils.js'; +import { + $, + $$, + inputElementClear, + inputElementEnable, + inputElementDisable, + buttonElementEnable, + buttonElementDisable, + removeChildNodes, +} from '../utils.js'; const getCarNames = (): void => { - const carNameInput: HTMLInputElement = document.getElementById(ID.CAR_NAME_INPUT) as HTMLInputElement; + const carNameInput: HTMLInputElement = $('#car-names-input') as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton: HTMLButtonElement = document.getElementById(ID.CAR_NAME_SUBMIT) as HTMLButtonElement; - const tryCountInput: HTMLInputElement = document.getElementById(ID.RACING_COUNT_INPUT) as HTMLInputElement; - const tryCountSubmitButton: HTMLButtonElement = document.getElementById( - ID.RACING_COUNT_SUBMIT, - ) as HTMLButtonElement; - - toggleInputValueDisabled(carNameInput); - toggleClickButtonDisabled(carNameSubmitButton); - toggleInputValueDisabled(tryCountInput); - toggleClickButtonDisabled(tryCountSubmitButton); + const carNameSubmitButton: HTMLButtonElement = $('#car-names-submit') as HTMLButtonElement; + const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; + const tryCountSubmitButton: HTMLButtonElement = $('#racing-count-submit') as HTMLButtonElement; + + inputElementDisable(carNameInput); + buttonElementDisable(carNameSubmitButton); + inputElementEnable(tryCountInput); + buttonElementEnable(tryCountSubmitButton); setupProgressSection(carNameArray); tryCountInput.focus(); return; } - clearInput(carNameInput); + inputElementClear(carNameInput); }; const getTryCount = (): void => { - const tryCountInput: HTMLInputElement = document.getElementById(ID.RACING_COUNT_INPUT) as HTMLInputElement; + const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; const tryCount: number = Number(tryCountInput?.value); if (checkTryCount(tryCountInput)) { - const carNameInput: HTMLInputElement = document.getElementById(ID.CAR_NAME_INPUT) as HTMLInputElement; - const tryCountSubmitButton: HTMLButtonElement = document.getElementById( - ID.RACING_COUNT_SUBMIT, - ) as HTMLButtonElement; + const carNameInput: HTMLInputElement = $('#car-names-input') as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); + const tryCountSubmitButton: HTMLButtonElement = $('#racing-count-submit') as HTMLButtonElement; - toggleInputValueDisabled(tryCountInput); - toggleClickButtonDisabled(tryCountSubmitButton); + inputElementDisable(tryCountInput); + buttonElementDisable(tryCountSubmitButton); startGame(carNameArray, tryCount); return; } - clearInput(tryCountInput); + inputElementClear(tryCountInput); }; const setupProgressSection = (carNameArray: Array) => { renderProgressSection(); carNameArray.forEach((carName) => { renderCarNameDiv(carName); - }); // 이름 div 생성 + }); renderSpinnerDiv(); }; -const initGame = (): void => { - removeChildNodes(document.getElementById(ID.APP_DIV)); +const restartApp = (): void => { + removeChildNodes($('#app')); renderInputSection(); setInputButtonsEvent(); }; -export { getCarNames, getTryCount, initGame }; +export { getCarNames, getTryCount, restartApp }; diff --git a/src/controller/play.ts b/src/controller/play.ts index 06cbf4f8d..0dea87c7e 100644 --- a/src/controller/play.ts +++ b/src/controller/play.ts @@ -1,8 +1,8 @@ import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRetryButtonEvent } from './event.js'; -import { $$, makeDelay } from './utils.js'; +import { setRestartButtonEvent } from './event.js'; +import { $$, makeDelay } from '../utils.js'; const createCarsObject = (carNameArray: Array) => { let cars: Array = []; @@ -39,7 +39,7 @@ const startGame = async (carNameArray: Array, tryCount: number) => { const racingWinners: Array = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); await makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - setRetryButtonEvent(); + setRestartButtonEvent(); }; export { startGame }; diff --git a/src/controller/utils.ts b/src/controller/utils.ts deleted file mode 100644 index 07b756ba6..000000000 --- a/src/controller/utils.ts +++ /dev/null @@ -1,41 +0,0 @@ -const $ = (selector: string): Element | null => document.querySelector(selector); - -const $$ = (selector: string): NodeListOf => document.querySelectorAll(selector); - -const clearInput = (element: HTMLInputElement): void => { - element.value = ''; - element.focus(); -}; - -const toggleInputValueDisabled = (element: HTMLInputElement): void => { - if (element.disabled) { - element.disabled = false; - } else { - element.disabled = true; - } -}; - -const toggleClickButtonDisabled = (element: HTMLButtonElement): void => { - if (element.disabled) { - element.disabled = false; - } else { - element.disabled = true; - } -}; - -const removeChildNodes = (element: Element | null): void => { - if (!element) { - return; - } - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } - } -}; - -const makeDelay = async (ms: number) => { - return new Promise((r) => setTimeout(r, ms)); -}; - -export { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes, makeDelay }; diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 000000000..04a355b67 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,51 @@ +const $ = (selector: string): Element | null => document.querySelector(selector); + +const $$ = (selector: string): NodeListOf => document.querySelectorAll(selector); + +const inputElementClear = (element: HTMLInputElement): void => { + element.value = ''; + element.focus(); +}; + +const inputElementEnable = (element: HTMLInputElement): void => { + element.disabled = false; +}; + +const inputElementDisable = (element: HTMLInputElement): void => { + element.disabled = true; +}; + +const buttonElementEnable = (element: HTMLButtonElement): void => { + element.disabled = false; +}; + +const buttonElementDisable = (element: HTMLButtonElement): void => { + element.disabled = true; +}; + +const removeChildNodes = (element: Element | null): void => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } +}; + +const makeDelay = async (ms: number) => { + return new Promise((r) => setTimeout(r, ms)); +}; + +export { + $, + $$, + inputElementClear, + inputElementEnable, + inputElementDisable, + buttonElementEnable, + buttonElementDisable, + removeChildNodes, + makeDelay, +}; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index b567d8c9e..04bb3fdc3 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,5 +1,5 @@ import { ID } from '../constants/index.js'; -import { $, $$ } from '../controller/utils.js'; +import { $, $$ } from '../utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts index 6e3571e68..f8992884b 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/templates/result-section.ts @@ -4,7 +4,7 @@ const resultSection = (winners: string): string => {

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

- +
From 3842968bf78b46abc503965a97b3331b125be00b Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 19:44:22 +0900 Subject: [PATCH 44/70] =?UTF-8?q?refactor:=20=EA=B2=8C=EC=9E=84=20?= =?UTF-8?q?=EC=9E=AC=EC=8B=9C=EC=9E=91=20=EC=8B=9C=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EC=B9=B8=EC=97=90=20=ED=8F=AC=EC=BB=A4?= =?UTF-8?q?=EC=8B=B1,=20remove=ED=95=A8=EC=88=98=20view=EC=97=90=20?= =?UTF-8?q?=EB=AA=A8=EC=95=84=EB=91=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/linstener.js | 9 ++++++--- dist/controller/play.js | 8 ++++---- dist/utils.js | 12 +----------- dist/view/remover.js | 17 +++++++++++++++++ src/controller/linstener.ts | 7 +++++-- src/controller/play.ts | 8 ++++---- src/utils.ts | 12 ------------ src/view/remover.ts | 20 ++++++++++++++++++++ 8 files changed, 57 insertions(+), 36 deletions(-) create mode 100644 dist/view/remover.js create mode 100644 src/view/remover.ts diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index f6be35647..44818461f 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -1,9 +1,9 @@ import { startGame } from './play.js'; -import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; -import { $, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, removeChildNodes, } from '../utils.js'; +import { removeChildNodes } from '../view/remover.js'; +import { $, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, } from '../utils.js'; const getCarNames = () => { const carNameInput = $('#car-names-input'); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); @@ -43,8 +43,11 @@ const setupProgressSection = (carNameArray) => { renderSpinnerDiv(); }; const restartApp = () => { - removeChildNodes(document.getElementById(ID.APP_DIV)); + let carNameInput; + removeChildNodes($('#app')); renderInputSection(); setInputButtonsEvent(); + carNameInput = $('#car-names-input'); + carNameInput.focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/dist/controller/play.js b/dist/controller/play.js index 69abb9b8d..a018c74f9 100644 --- a/dist/controller/play.js +++ b/dist/controller/play.js @@ -12,6 +12,7 @@ import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; import { $$, makeDelay } from '../utils.js'; +import { removeSpinners } from '../view/remover.js'; const createCarsObject = (carNameArray) => { let cars = []; carNameArray.forEach((car, index) => { @@ -34,13 +35,12 @@ const playOnce = (racingGame) => { }; const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { const racingGame = new Game(createCarsObject(carNameArray)); + let racingWinners = []; for (let index = 0; index < tryCount; index += 1) { yield makeDelay(1000).then(() => playOnce(racingGame)); } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ - $$('div.d-flex.justify-center.mt-3').forEach((element) => { - element.remove(); - }); // κ²Œμž„ λλ‚˜λ©΄ spinner 제거 - const racingWinners = racingGame.getWinners(); + removeSpinners(); + racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); setRestartButtonEvent(); diff --git a/dist/utils.js b/dist/utils.js index 8ac46cfe3..4dedb9873 100644 --- a/dist/utils.js +++ b/dist/utils.js @@ -25,17 +25,7 @@ const buttonElementEnable = (element) => { const buttonElementDisable = (element) => { element.disabled = true; }; -const removeChildNodes = (element) => { - if (!element) { - return; - } - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } - } -}; const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { return new Promise((r) => setTimeout(r, ms)); }); -export { $, $$, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, removeChildNodes, makeDelay, }; +export { $, $$, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, makeDelay, }; diff --git a/dist/view/remover.js b/dist/view/remover.js new file mode 100644 index 000000000..ab037e96c --- /dev/null +++ b/dist/view/remover.js @@ -0,0 +1,17 @@ +import { $$ } from '../utils.js'; +const removeSpinners = () => { + $$('div.d-flex.justify-center.mt-3').forEach((element) => { + element.remove(); + }); +}; +const removeChildNodes = (element) => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } +}; +export { removeSpinners, removeChildNodes }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index ad1ba149b..b3da42057 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -1,8 +1,8 @@ import { startGame } from './play.js'; -import { ID } from '../constants/index.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; +import { removeChildNodes } from '../view/remover.js'; import { $, $$, @@ -11,7 +11,6 @@ import { inputElementDisable, buttonElementEnable, buttonElementDisable, - removeChildNodes, } from '../utils.js'; const getCarNames = (): void => { @@ -60,9 +59,13 @@ const setupProgressSection = (carNameArray: Array) => { }; const restartApp = (): void => { + let carNameInput: HTMLInputElement; + removeChildNodes($('#app')); renderInputSection(); setInputButtonsEvent(); + carNameInput = $('#car-names-input') as HTMLInputElement; + carNameInput.focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/src/controller/play.ts b/src/controller/play.ts index 0dea87c7e..093899837 100644 --- a/src/controller/play.ts +++ b/src/controller/play.ts @@ -3,6 +3,7 @@ import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; import { $$, makeDelay } from '../utils.js'; +import { removeSpinners } from '../view/remover.js'; const createCarsObject = (carNameArray: Array) => { let cars: Array = []; @@ -29,14 +30,13 @@ const playOnce = (racingGame: Game) => { const startGame = async (carNameArray: Array, tryCount: number) => { const racingGame: Game = new Game(createCarsObject(carNameArray)); + let racingWinners: Array = []; for (let index = 0; index < tryCount; index += 1) { await makeDelay(1000).then(() => playOnce(racingGame)); } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ - $$('div.d-flex.justify-center.mt-3').forEach((element) => { - element.remove(); - }); // κ²Œμž„ λλ‚˜λ©΄ spinner 제거 - const racingWinners: Array = racingGame.getWinners(); + removeSpinners(); + racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); await makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); setRestartButtonEvent(); diff --git a/src/utils.ts b/src/utils.ts index 04a355b67..1d2f02c59 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -23,17 +23,6 @@ const buttonElementDisable = (element: HTMLButtonElement): void => { element.disabled = true; }; -const removeChildNodes = (element: Element | null): void => { - if (!element) { - return; - } - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } - } -}; - const makeDelay = async (ms: number) => { return new Promise((r) => setTimeout(r, ms)); }; @@ -46,6 +35,5 @@ export { inputElementDisable, buttonElementEnable, buttonElementDisable, - removeChildNodes, makeDelay, }; diff --git a/src/view/remover.ts b/src/view/remover.ts new file mode 100644 index 000000000..5ccf05a2a --- /dev/null +++ b/src/view/remover.ts @@ -0,0 +1,20 @@ +import { $$ } from '../utils.js'; + +const removeSpinners = () => { + $$('div.d-flex.justify-center.mt-3').forEach((element) => { + element.remove(); + }); +}; + +const removeChildNodes = (element: Element | null): void => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } +}; + +export { removeSpinners, removeChildNodes }; From 695210543b2f7a403ff2e63a8d78c4cd7e730708 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 20:17:01 +0900 Subject: [PATCH 45/70] =?UTF-8?q?refactor:=20=ED=95=9C=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B4=EB=93=9C=20=EC=8A=B9=EC=9E=90=20=ED=99=94=EC=82=B4?= =?UTF-8?q?=ED=91=9C=20=EA=B7=B8=EB=A6=AC=EB=8A=94=20=ED=95=A8=EC=88=98(pl?= =?UTF-8?q?ayOnce)=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95(thanks=20yech?= =?UTF-8?q?oi)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/elements.js | 1 - dist/controller/game-control.js | 59 +++++++++++++++++++++++++++++ dist/controller/game.js | 44 +++++++++++++++++++++ dist/controller/linstener.js | 2 +- src/constants/elements.ts | 2 - src/controller/{play.ts => game.ts} | 14 +++---- src/controller/linstener.ts | 2 +- src/view/renderer.ts | 1 - 8 files changed, 110 insertions(+), 15 deletions(-) create mode 100644 dist/controller/game-control.js create mode 100644 dist/controller/game.js rename src/controller/{play.ts => game.ts} (74%) diff --git a/dist/constants/elements.js b/dist/constants/elements.js index 8902342df..4168e2e73 100644 --- a/dist/constants/elements.js +++ b/dist/constants/elements.js @@ -1,5 +1,4 @@ const ID = { - APP_DIV: 'app', CAR_NAME_DIV: '.mt-4.d-flex', SPINNER_DIV: 'div.mr-2', CAR_NAME_INPUT: 'car-names-input', diff --git a/dist/controller/game-control.js b/dist/controller/game-control.js new file mode 100644 index 000000000..6d67d8495 --- /dev/null +++ b/dist/controller/game-control.js @@ -0,0 +1,59 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { ALERT } from '../constants/index.js'; +import { Car, Game } from '../model/index.js'; +import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; +import { setRestartButtonEvent } from './event.js'; +import { $$, makeDelay } from '../utils.js'; +import { removeSpinners } from '../view/remover.js'; +const createCarsObject = (carNameArray) => { + let cars = []; + carNameArray.forEach((car, index) => { + cars.push(new Car(car, index)); + }); + return cars; +}; +const checkRoundWinner = (racingGame, car, index) => { + racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { + if (car.index === index && car.index === roundWinnerIndex) { + return true; + } + }); + return false; +}; +const playOnce = (racingGame) => { + racingGame.play(); + $$('div.car-player').forEach((element, index) => { + racingGame.cars.forEach((car) => { + if (checkRoundWinner(racingGame, car, index)) { + renderArrowDiv(element); + } + // racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { + // if (car.index === index && car.index === roundWinnerIndex) { + // renderArrowDiv(element); + // } + // }); + }); + }); + racingGame.initRoundWinnersIndex(); +}; +const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { + const racingGame = new Game(createCarsObject(carNameArray)); + let racingWinners = []; + for (let index = 0; index < tryCount; index += 1) { + yield makeDelay(1000).then(() => playOnce(racingGame)); + } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ + removeSpinners(); + racingWinners = racingGame.getWinners(); + renderResultSection(racingWinners.join(', ').toLowerCase()); + yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + setRestartButtonEvent(); +}); +export { startGame }; diff --git a/dist/controller/game.js b/dist/controller/game.js new file mode 100644 index 000000000..a4a5308e5 --- /dev/null +++ b/dist/controller/game.js @@ -0,0 +1,44 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { ALERT } from '../constants/index.js'; +import { Car, Game } from '../model/index.js'; +import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; +import { setRestartButtonEvent } from './event.js'; +import { $$, makeDelay } from '../utils.js'; +import { removeSpinners } from '../view/remover.js'; +const createCarsObject = (carNameArray) => { + let cars = []; + carNameArray.forEach((car, index) => { + cars.push(new Car(car, index)); + }); + return cars; +}; +const playOnce = (racingGame) => { + racingGame.play(); + racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { + $$('div.car-player').forEach((item, index) => { + index === roundWinnerIndex ? renderArrowDiv(item) : null; + }); + }); + racingGame.initRoundWinnersIndex(); +}; +const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { + const racingGame = new Game(createCarsObject(carNameArray)); + let racingWinners = []; + for (let index = 0; index < tryCount; index += 1) { + yield makeDelay(1000).then(() => playOnce(racingGame)); + } + removeSpinners(); + racingWinners = racingGame.getWinners(); + renderResultSection(racingWinners.join(', ').toLowerCase()); + yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + setRestartButtonEvent(); +}); +export { startGame }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 44818461f..9a12c361b 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -1,4 +1,4 @@ -import { startGame } from './play.js'; +import { startGame } from './game.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; diff --git a/src/constants/elements.ts b/src/constants/elements.ts index 165b82612..af0f60cb4 100644 --- a/src/constants/elements.ts +++ b/src/constants/elements.ts @@ -1,6 +1,4 @@ const ID = { - APP_DIV: 'app', - CAR_NAME_DIV: '.mt-4.d-flex', SPINNER_DIV: 'div.mr-2', diff --git a/src/controller/play.ts b/src/controller/game.ts similarity index 74% rename from src/controller/play.ts rename to src/controller/game.ts index 093899837..8ab6b66d7 100644 --- a/src/controller/play.ts +++ b/src/controller/game.ts @@ -1,6 +1,6 @@ import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; -import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; +import { renderArrowDiv, renderResultSection, renderSpinnerDiv } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; import { $$, makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; @@ -16,13 +16,9 @@ const createCarsObject = (carNameArray: Array) => { const playOnce = (racingGame: Game) => { racingGame.play(); - $$('div.car-player').forEach((element, index) => { - racingGame.cars.forEach((car) => { - racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - if (car.index === index && car.index === roundWinnerIndex) { - renderArrowDiv(element); - } - }); + racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { + $$('div.car-player').forEach((item, index) => { + index === roundWinnerIndex ? renderArrowDiv(item) : null; }); }); racingGame.initRoundWinnersIndex(); @@ -34,7 +30,7 @@ const startGame = async (carNameArray: Array, tryCount: number) => { for (let index = 0; index < tryCount; index += 1) { await makeDelay(1000).then(() => playOnce(racingGame)); - } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ + } removeSpinners(); racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index b3da42057..204065f82 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -1,4 +1,4 @@ -import { startGame } from './play.js'; +import { startGame } from './game.js'; import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 04bb3fdc3..9827a6e50 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,4 +1,3 @@ -import { ID } from '../constants/index.js'; import { $, $$ } from '../utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; From 8bcbcee440a3c18a484ddcd57f7eddef9f91f217 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 20:28:28 +0900 Subject: [PATCH 46/70] =?UTF-8?q?refactor:=20=EB=A0=8C=EB=8D=94=EB=A7=81,?= =?UTF-8?q?=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EB=8D=94=20=ED=99=95?= =?UTF-8?q?=EC=8B=A4=ED=95=98=EA=B2=8C=20=EB=B6=84=EB=A5=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/game.js | 9 +++++---- dist/controller/linstener.js | 18 +++++++++--------- dist/view/renderer.js | 21 ++++++++++++--------- src/controller/game.ts | 6 ++---- src/controller/linstener.ts | 20 ++++++++++---------- src/view/renderer.ts | 22 +++++++++------------- 6 files changed, 47 insertions(+), 49 deletions(-) diff --git a/dist/controller/game.js b/dist/controller/game.js index a4a5308e5..87c5608b8 100644 --- a/dist/controller/game.js +++ b/dist/controller/game.js @@ -11,7 +11,7 @@ import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; -import { $$, makeDelay } from '../utils.js'; +import { makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; const createCarsObject = (carNameArray) => { let cars = []; @@ -23,9 +23,10 @@ const createCarsObject = (carNameArray) => { const playOnce = (racingGame) => { racingGame.play(); racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - $$('div.car-player').forEach((item, index) => { - index === roundWinnerIndex ? renderArrowDiv(item) : null; - }); + // $$('div.car-player').forEach((item, index) => { + // index === roundWinnerIndex ? renderArrowDiv(item) : null; + // }); + renderArrowDiv(roundWinnerIndex); }); racingGame.initRoundWinnersIndex(); }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 9a12c361b..d00282bd6 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -1,5 +1,5 @@ import { startGame } from './game.js'; -import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; +import { renderProgressSection, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; import { removeChildNodes } from '../view/remover.js'; @@ -15,7 +15,7 @@ const getCarNames = () => { buttonElementDisable(carNameSubmitButton); inputElementEnable(tryCountInput); buttonElementEnable(tryCountSubmitButton); - setupProgressSection(carNameArray); + renderProgressSection(carNameArray); tryCountInput.focus(); return; } @@ -35,13 +35,13 @@ const getTryCount = () => { } inputElementClear(tryCountInput); }; -const setupProgressSection = (carNameArray) => { - renderProgressSection(); - carNameArray.forEach((carName) => { - renderCarNameDiv(carName); - }); - renderSpinnerDiv(); -}; +// const setupProgressSection = (carNameArray: Array) => { +// renderProgressSection(); +// carNameArray.forEach((carName) => { +// renderCarNameDiv(carName); +// }); +// renderSpinnerDiv(); +// }; const restartApp = () => { let carNameInput; removeChildNodes($('#app')); diff --git a/dist/view/renderer.js b/dist/view/renderer.js index bdcbae105..4cece2587 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -3,21 +3,24 @@ import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, result const renderInputSection = () => { $('#app').innerHTML = inputSection(); }; -const renderProgressSection = () => { +const renderProgressSection = (carNameArray) => { $('#app').insertAdjacentHTML('beforeend', progressSection()); -}; -const renderCarNameDiv = (carName) => { - $('#progress-section > div').insertAdjacentHTML('beforeend', carNameDiv(carName)); -}; -const renderSpinnerDiv = () => { + carNameArray.forEach((carName) => { + $('#progress-section > div').insertAdjacentHTML('beforeend', carNameDiv(carName)); + }); $$('#progress-section > div > div').forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; -const renderArrowDiv = (element) => { - element.insertAdjacentHTML(`afterend`, arrowDiv()); +// const renderArrowDiv = (element: Element): void => { +// element.insertAdjacentHTML(`afterend`, arrowDiv()); +// }; +const renderArrowDiv = (roundWinnerIndex) => { + $$('div.car-player').forEach((element, index) => { + index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; + }); }; const renderResultSection = (winners) => { $('#app').insertAdjacentHTML('beforeend', resultSection(winners)); }; -export { renderInputSection, renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderArrowDiv, renderResultSection, }; +export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection, }; diff --git a/src/controller/game.ts b/src/controller/game.ts index 8ab6b66d7..502b13cef 100644 --- a/src/controller/game.ts +++ b/src/controller/game.ts @@ -1,6 +1,6 @@ import { ALERT } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; -import { renderArrowDiv, renderResultSection, renderSpinnerDiv } from '../view/renderer.js'; +import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; import { $$, makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; @@ -17,9 +17,7 @@ const createCarsObject = (carNameArray: Array) => { const playOnce = (racingGame: Game) => { racingGame.play(); racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - $$('div.car-player').forEach((item, index) => { - index === roundWinnerIndex ? renderArrowDiv(item) : null; - }); + renderArrowDiv(roundWinnerIndex); }); racingGame.initRoundWinnersIndex(); }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index 204065f82..3ca5157fb 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -1,5 +1,5 @@ import { startGame } from './game.js'; -import { renderProgressSection, renderCarNameDiv, renderSpinnerDiv, renderInputSection } from '../view/renderer.js'; +import { renderProgressSection, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; import { checkCarNames, checkTryCount } from './validtor.js'; import { removeChildNodes } from '../view/remover.js'; @@ -26,7 +26,7 @@ const getCarNames = (): void => { buttonElementDisable(carNameSubmitButton); inputElementEnable(tryCountInput); buttonElementEnable(tryCountSubmitButton); - setupProgressSection(carNameArray); + renderProgressSection(carNameArray); tryCountInput.focus(); return; } @@ -34,7 +34,7 @@ const getCarNames = (): void => { }; const getTryCount = (): void => { - const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; + const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; const tryCount: number = Number(tryCountInput?.value); if (checkTryCount(tryCountInput)) { @@ -50,13 +50,13 @@ const getTryCount = (): void => { inputElementClear(tryCountInput); }; -const setupProgressSection = (carNameArray: Array) => { - renderProgressSection(); - carNameArray.forEach((carName) => { - renderCarNameDiv(carName); - }); - renderSpinnerDiv(); -}; +// const setupProgressSection = (carNameArray: Array) => { +// renderProgressSection(); +// carNameArray.forEach((carName) => { +// renderCarNameDiv(carName); +// }); +// renderSpinnerDiv(); +// }; const restartApp = (): void => { let carNameInput: HTMLInputElement; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 9827a6e50..1ef68965b 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -5,23 +5,21 @@ const renderInputSection = (): void => { $('#app')!.innerHTML = inputSection(); }; -const renderProgressSection = (): void => { +const renderProgressSection = (carNameArray: Array): void => { $('#app')!.insertAdjacentHTML('beforeend', progressSection()); -}; - -const renderCarNameDiv = (carName: string): void => { - $('#progress-section > div')!.insertAdjacentHTML('beforeend', carNameDiv(carName)); -}; - -const renderSpinnerDiv = (): void => { + carNameArray.forEach((carName) => { + $('#progress-section > div')!.insertAdjacentHTML('beforeend', carNameDiv(carName)); + }); $$('#progress-section > div > div')!.forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; -const renderArrowDiv = (element: Element): void => { - element.insertAdjacentHTML(`afterend`, arrowDiv()); -}; +const renderArrowDiv = (roundWinnerIndex: number): void => { + $$('div.car-player').forEach((element, index) => { + index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; + }); +} const renderResultSection = (winners: string): void => { $('#app')!.insertAdjacentHTML('beforeend', resultSection(winners)); @@ -30,8 +28,6 @@ const renderResultSection = (winners: string): void => { export { renderInputSection, renderProgressSection, - renderCarNameDiv, - renderSpinnerDiv, renderArrowDiv, renderResultSection, }; From 2ded7d1581d71804e9855a61dc3c220c98f8734e Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 20:46:59 +0900 Subject: [PATCH 47/70] =?UTF-8?q?refactor:=20=EC=9E=85=EB=A0=A5=EB=B6=80?= =?UTF-8?q?=20=EC=97=90=EB=9F=AC=EC=B2=B4=ED=81=AC=20=EC=B6=94=EA=B0=80(?= =?UTF-8?q?=EB=B9=88=20=EC=9D=B4=EB=A6=84=20=EC=9E=85=EB=A0=A5)=20?= =?UTF-8?q?=EB=B0=8F=20alert=20=EC=83=81=EC=88=98=20=EB=AC=B8=EA=B5=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/game.js | 3 --- dist/controller/validtor.js | 20 ++++++++++++++------ dist/view/renderer.js | 5 +---- src/constants/alert.ts | 15 ++++++++------- src/controller/validtor.ts | 36 ++++++++++++++++++++++-------------- src/view/renderer.ts | 11 +++-------- 6 files changed, 48 insertions(+), 42 deletions(-) diff --git a/dist/controller/game.js b/dist/controller/game.js index 87c5608b8..7592a3108 100644 --- a/dist/controller/game.js +++ b/dist/controller/game.js @@ -23,9 +23,6 @@ const createCarsObject = (carNameArray) => { const playOnce = (racingGame) => { racingGame.play(); racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - // $$('div.car-player').forEach((item, index) => { - // index === roundWinnerIndex ? renderArrowDiv(item) : null; - // }); renderArrowDiv(roundWinnerIndex); }); racingGame.initRoundWinnersIndex(); diff --git a/dist/controller/validtor.js b/dist/controller/validtor.js index ad0599e81..ef16d1605 100644 --- a/dist/controller/validtor.js +++ b/dist/controller/validtor.js @@ -2,15 +2,19 @@ import { ALERT } from '../constants/index.js'; const checkEmptyInput = (input) => { return input.value.trim() === ''; }; -const checkElementsAlone = (array) => { +const checkArrayHasEmptyElement = (array) => { + console.log(array); + return array.some((x) => x === ''); +}; +const checkArrayHasOneElement = (array) => { return array.length < 2; }; -const checkElementsDouble = (array) => { +const checkArrayDupElements = (array) => { return array.some((x) => { return array.indexOf(x) !== array.lastIndexOf(x); }); }; -const checkElementsLength = (array) => { +const checkArrayElementsLength = (array) => { for (let index = 0; index < array.length; index += 1) { if (array[index].length > 5) { return true; @@ -23,15 +27,19 @@ const checkCarNames = (carNameInput, carNameArray) => { alert(ALERT.CAR_INPUT_EMPTY); return false; } - else if (checkElementsAlone(carNameArray)) { + else if (checkArrayHasEmptyElement(carNameArray)) { + alert('빈 이름 있음'); + return false; + } + else if (checkArrayHasOneElement(carNameArray)) { alert(ALERT.CAR_INPUT_ALONE); return false; } - else if (checkElementsDouble(carNameArray)) { + else if (checkArrayDupElements(carNameArray)) { alert(ALERT.CAR_INPUT_DOUBLE); return false; } - else if (checkElementsLength(carNameArray)) { + else if (checkArrayElementsLength(carNameArray)) { alert(ALERT.CAR_INPUT_LENGTH); return false; } diff --git a/dist/view/renderer.js b/dist/view/renderer.js index 4cece2587..ef2840ade 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -12,9 +12,6 @@ const renderProgressSection = (carNameArray) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; -// const renderArrowDiv = (element: Element): void => { -// element.insertAdjacentHTML(`afterend`, arrowDiv()); -// }; const renderArrowDiv = (roundWinnerIndex) => { $$('div.car-player').forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; @@ -23,4 +20,4 @@ const renderArrowDiv = (roundWinnerIndex) => { const renderResultSection = (winners) => { $('#app').insertAdjacentHTML('beforeend', resultSection(winners)); }; -export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection, }; +export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; diff --git a/src/constants/alert.ts b/src/constants/alert.ts index d6fbe7200..2697b9cf4 100644 --- a/src/constants/alert.ts +++ b/src/constants/alert.ts @@ -1,12 +1,13 @@ const ALERT = { - CAR_INPUT_EMPTY: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”', - CAR_INPUT_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•˜μ„Έμš”', - CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', - CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', + CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_EMPTY: 'μžλ™μ°¨ 이름은 1개의 콀마둜 κ΅¬λΆ„ν•΄μ„œ μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', - TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', - TRY_INPUT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (20 μ΄ν•˜ ꢌμž₯)', - TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', + TRYCOUNT_NOTHING: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”', + TRYCOUNT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (50 μ΄ν•˜)', + TRYCOUNT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (50 μ΄ν•˜)', CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', }; diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index 69c4a0e22..77fa086ef 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -4,17 +4,22 @@ const checkEmptyInput = (input: HTMLInputElement) => { return input.value.trim() === ''; }; -const checkElementsAlone = (array: Array) => { +const checkArrayHasEmptyElement = (array: Array) => { + console.log(array); + return array.some((x) => x === ''); +} + +const checkArrayHasOneElement = (array: Array) => { return array.length < 2; }; -const checkElementsDouble = (array: Array) => { +const checkArrayDupElements = (array: Array) => { return array.some((x) => { return array.indexOf(x) !== array.lastIndexOf(x); }); }; -const checkElementsLength = (array: Array) => { +const checkArrayElementsLength = (array: Array) => { for (let index = 0; index < array.length; index += 1) { if (array[index].length > 5) { return true; @@ -25,16 +30,19 @@ const checkElementsLength = (array: Array) => { const checkCarNames = (carNameInput: HTMLInputElement, carNameArray: Array): boolean => { if (checkEmptyInput(carNameInput)) { - alert(ALERT.CAR_INPUT_EMPTY); + alert(ALERT.CARNAME_NOTHING); + return false; + } else if (checkArrayHasEmptyElement(carNameArray)) { + alert(ALERT.CARNAME_EMPTY); return false; - } else if (checkElementsAlone(carNameArray)) { - alert(ALERT.CAR_INPUT_ALONE); + } else if (checkArrayHasOneElement(carNameArray)) { + alert(ALERT.CARNAME_ALONE); return false; - } else if (checkElementsDouble(carNameArray)) { - alert(ALERT.CAR_INPUT_DOUBLE); + } else if (checkArrayDupElements(carNameArray)) { + alert(ALERT.CARNAME_DOUBLE); return false; - } else if (checkElementsLength(carNameArray)) { - alert(ALERT.CAR_INPUT_LENGTH); + } else if (checkArrayElementsLength(carNameArray)) { + alert(ALERT.CARNAME_LENGTH); return false; } return true; @@ -42,13 +50,13 @@ const checkCarNames = (carNameInput: HTMLInputElement, carNameArray: Array { if (checkEmptyInput(tryCountInput)) { - alert(ALERT.TRY_INPUT_EMPTY); + alert(ALERT.TRYCOUNT_NOTHING); return false; } else if (Number(tryCountInput.value) < 1) { - alert(ALERT.TRY_INPUT_UINT); + alert(ALERT.TRYCOUNT_UINT); return false; - } else if (Number(tryCountInput.value) > 20) { - alert(ALERT.TRY_INPUT_TOO_BIG); + } else if (Number(tryCountInput.value) > 50) { + alert(ALERT.TRYCOUNT_TOO_BIG); return false; } return true; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 1ef68965b..61c01018f 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -17,17 +17,12 @@ const renderProgressSection = (carNameArray: Array): void => { const renderArrowDiv = (roundWinnerIndex: number): void => { $$('div.car-player').forEach((element, index) => { - index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; + index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); -} +}; const renderResultSection = (winners: string): void => { $('#app')!.insertAdjacentHTML('beforeend', resultSection(winners)); }; -export { - renderInputSection, - renderProgressSection, - renderArrowDiv, - renderResultSection, -}; +export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; From 4df00776e5e058d52499d47a02b718a38122b078 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 20:48:39 +0900 Subject: [PATCH 48/70] =?UTF-8?q?refactor:=20alert=20=EC=83=81=EC=88=98=20?= =?UTF-8?q?=EB=AC=B8=EA=B5=AC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/alert.js | 15 ++++++++------- dist/controller/validtor.js | 22 +++++++++++----------- src/constants/alert.ts | 2 +- src/controller/validtor.ts | 6 +++--- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/dist/constants/alert.js b/dist/constants/alert.js index 4454fad17..e888e94e6 100644 --- a/dist/constants/alert.js +++ b/dist/constants/alert.js @@ -1,11 +1,12 @@ const ALERT = { - CAR_INPUT_EMPTY: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ„Έμš”', - CAR_INPUT_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•˜μ„Έμš”', - CAR_INPUT_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', - CAR_INPUT_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', - TRY_INPUT_EMPTY: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•˜μ„Έμš”', - TRY_INPUT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (20 μ΄ν•˜ ꢌμž₯)', - TRY_INPUT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (20 μ΄ν•˜ ꢌμž₯)', + CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_EMPTY: 'λΉ„μ–΄ μžˆλŠ” μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', + TRYCOUNT_NOTHING: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”', + TRYCOUNT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (50 μ΄ν•˜)', + TRYCOUNT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (50 μ΄ν•˜)', CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', }; export { ALERT }; diff --git a/dist/controller/validtor.js b/dist/controller/validtor.js index ef16d1605..26069ae32 100644 --- a/dist/controller/validtor.js +++ b/dist/controller/validtor.js @@ -24,38 +24,38 @@ const checkArrayElementsLength = (array) => { }; const checkCarNames = (carNameInput, carNameArray) => { if (checkEmptyInput(carNameInput)) { - alert(ALERT.CAR_INPUT_EMPTY); + alert(ALERT.CARNAME_NOTHING); return false; } - else if (checkArrayHasEmptyElement(carNameArray)) { - alert('빈 이름 있음'); + else if (checkArrayHasOneElement(carNameArray)) { + alert(ALERT.CARNAME_ALONE); return false; } - else if (checkArrayHasOneElement(carNameArray)) { - alert(ALERT.CAR_INPUT_ALONE); + else if (checkArrayHasEmptyElement(carNameArray)) { + alert(ALERT.CARNAME_EMPTY); return false; } else if (checkArrayDupElements(carNameArray)) { - alert(ALERT.CAR_INPUT_DOUBLE); + alert(ALERT.CARNAME_DOUBLE); return false; } else if (checkArrayElementsLength(carNameArray)) { - alert(ALERT.CAR_INPUT_LENGTH); + alert(ALERT.CARNAME_LENGTH); return false; } return true; }; const checkTryCount = (tryCountInput) => { if (checkEmptyInput(tryCountInput)) { - alert(ALERT.TRY_INPUT_EMPTY); + alert(ALERT.TRYCOUNT_NOTHING); return false; } else if (Number(tryCountInput.value) < 1) { - alert(ALERT.TRY_INPUT_UINT); + alert(ALERT.TRYCOUNT_UINT); return false; } - else if (Number(tryCountInput.value) > 20) { - alert(ALERT.TRY_INPUT_TOO_BIG); + else if (Number(tryCountInput.value) > 50) { + alert(ALERT.TRYCOUNT_TOO_BIG); return false; } return true; diff --git a/src/constants/alert.ts b/src/constants/alert.ts index 2697b9cf4..7283e5e21 100644 --- a/src/constants/alert.ts +++ b/src/constants/alert.ts @@ -1,7 +1,7 @@ const ALERT = { CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', - CARNAME_EMPTY: 'μžλ™μ°¨ 이름은 1개의 콀마둜 κ΅¬λΆ„ν•΄μ„œ μž…λ ₯ν•΄μ£Όμ„Έμš”', CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_EMPTY: 'λΉ„μ–΄ μžˆλŠ” μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index 77fa086ef..ed8de281f 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -32,12 +32,12 @@ const checkCarNames = (carNameInput: HTMLInputElement, carNameArray: Array Date: Mon, 7 Jun 2021 21:03:27 +0900 Subject: [PATCH 49/70] =?UTF-8?q?refactor:=20queryselector,=20queryselecto?= =?UTF-8?q?rall=20=EC=97=90=20=ED=95=84=EC=9A=94=ED=95=9C=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=A0=95=EC=9D=98,=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/elements.js | 15 +++++++++------ dist/controller/event.js | 8 +++++--- dist/view/renderer.js | 13 +++++++------ src/constants/elements.ts | 17 +++++++++++------ src/controller/event.ts | 8 +++++--- src/controller/linstener.ts | 28 ++++++++++------------------ src/view/renderer.ts | 13 +++++++------ 7 files changed, 54 insertions(+), 48 deletions(-) diff --git a/dist/constants/elements.js b/dist/constants/elements.js index 4168e2e73..5825096cd 100644 --- a/dist/constants/elements.js +++ b/dist/constants/elements.js @@ -1,9 +1,12 @@ const ID = { - CAR_NAME_DIV: '.mt-4.d-flex', - SPINNER_DIV: 'div.mr-2', - CAR_NAME_INPUT: 'car-names-input', - CAR_NAME_SUBMIT: 'car-names-submit', - RACING_COUNT_INPUT: 'racing-count-input', - RACING_COUNT_SUBMIT: 'racing-count-submit', + APP_DIV: '#app', + CAR_DIV_LIST: '#progress-section > div > div', + CARNAMES_DIV: '#progress-section > div', + CARNAME_DIV_LIST: 'div.car-player', + CARNAME_INPUT: '#car-names-input', + CARNAME_SUBMIT: '#car-names-submit', + TRYCOUNT_INPUT: '#racing-count-input', + TRYCOUNT_SUBMIT: '#racing-count-submit', + RESTART_SUBMIT: '#restart-button', }; export { ID }; diff --git a/dist/controller/event.js b/dist/controller/event.js index 30831adad..cccaae888 100644 --- a/dist/controller/event.js +++ b/dist/controller/event.js @@ -1,9 +1,11 @@ +import { $ } from '../utils.js'; +import { ID } from '../constants/index.js'; import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = () => { - document.getElementById('car-names-submit').addEventListener('click', () => getCarNames()); - document.getElementById('racing-count-submit').addEventListener('click', () => getTryCount()); + $(ID.CARNAME_SUBMIT).addEventListener('click', () => getCarNames()); + $(ID.TRYCOUNT_SUBMIT).addEventListener('click', () => getTryCount()); }; const setRestartButtonEvent = () => { - document.getElementById('restart-button').addEventListener('click', () => restartApp()); + $(ID.RESTART_SUBMIT).addEventListener('click', () => restartApp()); }; export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/dist/view/renderer.js b/dist/view/renderer.js index ef2840ade..07fa9071d 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -1,23 +1,24 @@ +import { ID } from '../constants/index.js'; import { $, $$ } from '../utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = () => { - $('#app').innerHTML = inputSection(); + $(ID.APP_DIV).innerHTML = inputSection(); }; const renderProgressSection = (carNameArray) => { - $('#app').insertAdjacentHTML('beforeend', progressSection()); + $(ID.APP_DIV).insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - $('#progress-section > div').insertAdjacentHTML('beforeend', carNameDiv(carName)); + $(ID.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - $$('#progress-section > div > div').forEach((element) => { + $$(ID.CAR_DIV_LIST).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex) => { - $$('div.car-player').forEach((element, index) => { + $$(ID.CARNAME_DIV_LIST).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const renderResultSection = (winners) => { - $('#app').insertAdjacentHTML('beforeend', resultSection(winners)); + $(ID.APP_DIV).insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; diff --git a/src/constants/elements.ts b/src/constants/elements.ts index af0f60cb4..7616beb72 100644 --- a/src/constants/elements.ts +++ b/src/constants/elements.ts @@ -1,12 +1,17 @@ const ID = { - CAR_NAME_DIV: '.mt-4.d-flex', - SPINNER_DIV: 'div.mr-2', + APP_DIV: '#app', - CAR_NAME_INPUT: 'car-names-input', - CAR_NAME_SUBMIT: 'car-names-submit', + CAR_DIV_LIST: '#progress-section > div > div', + CARNAMES_DIV: '#progress-section > div', + CARNAME_DIV_LIST: 'div.car-player', - RACING_COUNT_INPUT: 'racing-count-input', - RACING_COUNT_SUBMIT: 'racing-count-submit', + CARNAME_INPUT: '#car-names-input', + CARNAME_SUBMIT: '#car-names-submit', + + TRYCOUNT_INPUT: '#racing-count-input', + TRYCOUNT_SUBMIT: '#racing-count-submit', + + RESTART_SUBMIT: '#restart-button', }; export { ID }; diff --git a/src/controller/event.ts b/src/controller/event.ts index debc528a1..60c0f8ecc 100644 --- a/src/controller/event.ts +++ b/src/controller/event.ts @@ -1,12 +1,14 @@ +import { $ } from '../utils.js'; +import { ID } from '../constants/index.js'; import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = (): void => { - document.getElementById('car-names-submit')!.addEventListener('click', () => getCarNames()); - document.getElementById('racing-count-submit')!.addEventListener('click', () => getTryCount()); + $(ID.CARNAME_SUBMIT)!.addEventListener('click', () => getCarNames()); + $(ID.TRYCOUNT_SUBMIT)!.addEventListener('click', () => getTryCount()); }; const setRestartButtonEvent = (): void => { - document.getElementById('restart-button')!.addEventListener('click', () => restartApp()); + $(ID.RESTART_SUBMIT)!.addEventListener('click', () => restartApp()); }; export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index 3ca5157fb..7fd0077cf 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -1,3 +1,4 @@ +import { ID } from '../constants/index.js'; import { startGame } from './game.js'; import { renderProgressSection, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; @@ -5,7 +6,6 @@ import { checkCarNames, checkTryCount } from './validtor.js'; import { removeChildNodes } from '../view/remover.js'; import { $, - $$, inputElementClear, inputElementEnable, inputElementDisable, @@ -14,13 +14,13 @@ import { } from '../utils.js'; const getCarNames = (): void => { - const carNameInput: HTMLInputElement = $('#car-names-input') as HTMLInputElement; + const carNameInput: HTMLInputElement = $(ID.CARNAME_INPUT) as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton: HTMLButtonElement = $('#car-names-submit') as HTMLButtonElement; - const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; - const tryCountSubmitButton: HTMLButtonElement = $('#racing-count-submit') as HTMLButtonElement; + const carNameSubmitButton: HTMLButtonElement = $(ID.CARNAME_SUBMIT) as HTMLButtonElement; + const tryCountInput: HTMLInputElement = $(ID.TRYCOUNT_INPUT) as HTMLInputElement; + const tryCountSubmitButton: HTMLButtonElement = $(ID.TRYCOUNT_SUBMIT) as HTMLButtonElement; inputElementDisable(carNameInput); buttonElementDisable(carNameSubmitButton); @@ -34,13 +34,13 @@ const getCarNames = (): void => { }; const getTryCount = (): void => { - const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; + const tryCountInput: HTMLInputElement = $(ID.TRYCOUNT_INPUT) as HTMLInputElement; const tryCount: number = Number(tryCountInput?.value); if (checkTryCount(tryCountInput)) { - const carNameInput: HTMLInputElement = $('#car-names-input') as HTMLInputElement; + const carNameInput: HTMLInputElement = $(ID.CARNAME_INPUT) as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - const tryCountSubmitButton: HTMLButtonElement = $('#racing-count-submit') as HTMLButtonElement; + const tryCountSubmitButton: HTMLButtonElement = $(ID.TRYCOUNT_SUBMIT) as HTMLButtonElement; inputElementDisable(tryCountInput); buttonElementDisable(tryCountSubmitButton); @@ -50,21 +50,13 @@ const getTryCount = (): void => { inputElementClear(tryCountInput); }; -// const setupProgressSection = (carNameArray: Array) => { -// renderProgressSection(); -// carNameArray.forEach((carName) => { -// renderCarNameDiv(carName); -// }); -// renderSpinnerDiv(); -// }; - const restartApp = (): void => { let carNameInput: HTMLInputElement; - removeChildNodes($('#app')); + removeChildNodes($(ID.APP_DIV)); renderInputSection(); setInputButtonsEvent(); - carNameInput = $('#car-names-input') as HTMLInputElement; + carNameInput = $(ID.CARNAME_INPUT) as HTMLInputElement; carNameInput.focus(); }; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 61c01018f..4f8078ee3 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,28 +1,29 @@ +import { ID } from '../constants/index.js'; import { $, $$ } from '../utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { - $('#app')!.innerHTML = inputSection(); + $(ID.APP_DIV)!.innerHTML = inputSection(); }; const renderProgressSection = (carNameArray: Array): void => { - $('#app')!.insertAdjacentHTML('beforeend', progressSection()); + $(ID.APP_DIV)!.insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - $('#progress-section > div')!.insertAdjacentHTML('beforeend', carNameDiv(carName)); + $(ID.CARNAMES_DIV)!.insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - $$('#progress-section > div > div')!.forEach((element) => { + $$(ID.CAR_DIV_LIST)!.forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex: number): void => { - $$('div.car-player').forEach((element, index) => { + $$(ID.CARNAME_DIV_LIST).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const renderResultSection = (winners: string): void => { - $('#app')!.insertAdjacentHTML('beforeend', resultSection(winners)); + $(ID.APP_DIV)!.insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; From e6fe29f1185b50432f6816767aba1f13128dee41 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 21:11:12 +0900 Subject: [PATCH 50/70] =?UTF-8?q?feat:=20rule,=20delay=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/delay.js | 5 +++++ dist/constants/index.js | 2 ++ dist/constants/rule.js | 6 ++++++ dist/controller/game.js | 6 +++--- dist/controller/linstener.js | 26 ++++++++++---------------- dist/controller/validtor.js | 1 - dist/model/game.js | 3 ++- src/constants/delay.ts | 6 ++++++ src/constants/index.ts | 2 ++ src/constants/rule.ts | 7 +++++++ src/controller/game.ts | 8 ++++---- src/controller/validtor.ts | 1 - src/model/game.ts | 5 +++-- 13 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 dist/constants/delay.js create mode 100644 dist/constants/rule.js create mode 100644 src/constants/delay.ts create mode 100644 src/constants/rule.ts diff --git a/dist/constants/delay.js b/dist/constants/delay.js new file mode 100644 index 000000000..d1725dec1 --- /dev/null +++ b/dist/constants/delay.js @@ -0,0 +1,5 @@ +const DELAY = { + TURN: 1000, + END: 2000, +}; +export { DELAY }; diff --git a/dist/constants/index.js b/dist/constants/index.js index 430e88113..d53e2e66b 100644 --- a/dist/constants/index.js +++ b/dist/constants/index.js @@ -1,2 +1,4 @@ export { ID } from './elements.js'; export { ALERT } from './alert.js'; +export { RULE } from './rule.js'; +export { DELAY } from './delay.js'; diff --git a/dist/constants/rule.js b/dist/constants/rule.js new file mode 100644 index 000000000..ea9197932 --- /dev/null +++ b/dist/constants/rule.js @@ -0,0 +1,6 @@ +const RULE = { + MIN_SCORE: 0, + MAX_SCORE: 9, + THRESHOULD_SCORE: 4, +}; +export { RULE }; diff --git a/dist/controller/game.js b/dist/controller/game.js index 7592a3108..c1460f8dc 100644 --- a/dist/controller/game.js +++ b/dist/controller/game.js @@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -import { ALERT } from '../constants/index.js'; +import { ALERT, DELAY } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; @@ -31,12 +31,12 @@ const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, const racingGame = new Game(createCarsObject(carNameArray)); let racingWinners = []; for (let index = 0; index < tryCount; index += 1) { - yield makeDelay(1000).then(() => playOnce(racingGame)); + yield makeDelay(DELAY.TURN).then(() => playOnce(racingGame)); } removeSpinners(); racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); - yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + yield makeDelay(DELAY.END).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); setRestartButtonEvent(); }); export { startGame }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index d00282bd6..cdd340ecc 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -1,3 +1,4 @@ +import { ID } from '../constants/index.js'; import { startGame } from './game.js'; import { renderProgressSection, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; @@ -5,12 +6,12 @@ import { checkCarNames, checkTryCount } from './validtor.js'; import { removeChildNodes } from '../view/remover.js'; import { $, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, } from '../utils.js'; const getCarNames = () => { - const carNameInput = $('#car-names-input'); + const carNameInput = $(ID.CARNAME_INPUT); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton = $('#car-names-submit'); - const tryCountInput = $('#racing-count-input'); - const tryCountSubmitButton = $('#racing-count-submit'); + const carNameSubmitButton = $(ID.CARNAME_SUBMIT); + const tryCountInput = $(ID.TRYCOUNT_INPUT); + const tryCountSubmitButton = $(ID.TRYCOUNT_SUBMIT); inputElementDisable(carNameInput); buttonElementDisable(carNameSubmitButton); inputElementEnable(tryCountInput); @@ -22,12 +23,12 @@ const getCarNames = () => { inputElementClear(carNameInput); }; const getTryCount = () => { - const tryCountInput = $('#racing-count-input'); + const tryCountInput = $(ID.TRYCOUNT_INPUT); const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); if (checkTryCount(tryCountInput)) { - const carNameInput = $('#car-names-input'); + const carNameInput = $(ID.CARNAME_INPUT); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - const tryCountSubmitButton = $('#racing-count-submit'); + const tryCountSubmitButton = $(ID.TRYCOUNT_SUBMIT); inputElementDisable(tryCountInput); buttonElementDisable(tryCountSubmitButton); startGame(carNameArray, tryCount); @@ -35,19 +36,12 @@ const getTryCount = () => { } inputElementClear(tryCountInput); }; -// const setupProgressSection = (carNameArray: Array) => { -// renderProgressSection(); -// carNameArray.forEach((carName) => { -// renderCarNameDiv(carName); -// }); -// renderSpinnerDiv(); -// }; const restartApp = () => { let carNameInput; - removeChildNodes($('#app')); + removeChildNodes($(ID.APP_DIV)); renderInputSection(); setInputButtonsEvent(); - carNameInput = $('#car-names-input'); + carNameInput = $(ID.CARNAME_INPUT); carNameInput.focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/dist/controller/validtor.js b/dist/controller/validtor.js index 26069ae32..b2798e259 100644 --- a/dist/controller/validtor.js +++ b/dist/controller/validtor.js @@ -3,7 +3,6 @@ const checkEmptyInput = (input) => { return input.value.trim() === ''; }; const checkArrayHasEmptyElement = (array) => { - console.log(array); return array.some((x) => x === ''); }; const checkArrayHasOneElement = (array) => { diff --git a/dist/model/game.js b/dist/model/game.js index 8319d2e57..f5e42566c 100644 --- a/dist/model/game.js +++ b/dist/model/game.js @@ -1,3 +1,4 @@ +import { RULE } from '../constants/index.js'; class Game { constructor(cars) { this.cars = cars; @@ -7,7 +8,7 @@ class Game { } play() { this.cars.forEach((car) => { - if (Math.floor(Math.random() * 9) + 1 >= 4) { + if (Math.floor(Math.random() * RULE.MAX_SCORE) + RULE.MIN_SCORE >= RULE.THRESHOULD_SCORE) { car.moveForward(); this.roundWinnersIndex.push(car.index); this.updateMaxPosition(); diff --git a/src/constants/delay.ts b/src/constants/delay.ts new file mode 100644 index 000000000..e0cf9b333 --- /dev/null +++ b/src/constants/delay.ts @@ -0,0 +1,6 @@ +const DELAY = { + TURN: 1000, + END: 2000, +}; + +export { DELAY }; diff --git a/src/constants/index.ts b/src/constants/index.ts index 430e88113..d53e2e66b 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,2 +1,4 @@ export { ID } from './elements.js'; export { ALERT } from './alert.js'; +export { RULE } from './rule.js'; +export { DELAY } from './delay.js'; diff --git a/src/constants/rule.ts b/src/constants/rule.ts new file mode 100644 index 000000000..cb50eaaee --- /dev/null +++ b/src/constants/rule.ts @@ -0,0 +1,7 @@ +const RULE = { + MIN_SCORE: 0, + MAX_SCORE: 9, + THRESHOULD_SCORE: 4, +}; + +export { RULE }; diff --git a/src/controller/game.ts b/src/controller/game.ts index 502b13cef..41fdd5a72 100644 --- a/src/controller/game.ts +++ b/src/controller/game.ts @@ -1,8 +1,8 @@ -import { ALERT } from '../constants/index.js'; +import { ALERT, DELAY } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; -import { $$, makeDelay } from '../utils.js'; +import { makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; const createCarsObject = (carNameArray: Array) => { @@ -27,12 +27,12 @@ const startGame = async (carNameArray: Array, tryCount: number) => { let racingWinners: Array = []; for (let index = 0; index < tryCount; index += 1) { - await makeDelay(1000).then(() => playOnce(racingGame)); + await makeDelay(DELAY.TURN).then(() => playOnce(racingGame)); } removeSpinners(); racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); - await makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + await makeDelay(DELAY.END).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); setRestartButtonEvent(); }; diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts index ed8de281f..e8929835a 100644 --- a/src/controller/validtor.ts +++ b/src/controller/validtor.ts @@ -5,7 +5,6 @@ const checkEmptyInput = (input: HTMLInputElement) => { }; const checkArrayHasEmptyElement = (array: Array) => { - console.log(array); return array.some((x) => x === ''); } diff --git a/src/model/game.ts b/src/model/game.ts index fdae9bc4f..e0a967996 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -1,4 +1,5 @@ -import { Car } from './car'; +import { Car } from './index.js'; +import { RULE } from '../constants/index.js' class Game { cars: Array; finalWinners: Array; @@ -14,7 +15,7 @@ class Game { play(): void { this.cars.forEach((car) => { - if (Math.floor(Math.random() * 9) + 1 >= 4) { + if (Math.floor(Math.random() * RULE.MAX_SCORE) + RULE.MIN_SCORE >= RULE.THRESHOULD_SCORE) { car.moveForward(); this.roundWinnersIndex.push(car.index); this.updateMaxPosition(); From 223862e2515eaee5c755a78213281786895d20ec Mon Sep 17 00:00:00 2001 From: jwon42 Date: Mon, 7 Jun 2021 22:42:17 +0900 Subject: [PATCH 51/70] =?UTF-8?q?test:=20cypress=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/fixtures/example.json | 5 + cypress/integration/racingcar.spec.js | 139 ++++++++++++++++++++++++++ cypress/plugins/index.js | 22 ++++ cypress/support/commands.js | 25 +++++ cypress/support/index.js | 20 ++++ dist/constants/elements.js | 9 +- package.json | 6 ++ src/constants/elements.ts | 12 ++- src/utils.ts | 2 +- 9 files changed, 232 insertions(+), 8 deletions(-) create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/integration/racingcar.spec.js create mode 100644 cypress/plugins/index.js create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/index.js diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 000000000..02e425437 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/integration/racingcar.spec.js b/cypress/integration/racingcar.spec.js new file mode 100644 index 000000000..5a119a654 --- /dev/null +++ b/cypress/integration/racingcar.spec.js @@ -0,0 +1,139 @@ +import { ID, ALERT, DELAY } from '../../dist/constants/index.js'; + +let carNamesSample = 'jwon, yeji, holee, yshin'; +let tryCountSample = 3; + +const carNameInputAndSubmit = (carNames) => { + if (carNames) { + cy.get(ID.CARNAME_INPUT).type(carNames); + } + cy.get(ID.CARNAME_SUBMIT).click(); +}; + +const tryCountInputAndSubmit = (tryCount) => { + if (tryCount) { + cy.get(ID.TRYCOUNT_INPUT).type(tryCount); + } + cy.get(ID.TRYCOUNT_SUBMIT).click(); +}; + +const catchAlertMessage = (alertMessage) => { + cy.on('window:alert', txt => { + expect(txt).to.contains(alertMessage); + }); +}; + +describe('0. μ΄ˆκΈ°ν™”λ©΄ λ‘œλ”© ν…ŒμŠ€νŠΈ', () => { + beforeEach(() => { + cy.visit('http://localhost:5500'); + }); + + it('μžλ™μ°¨ κ²½μ£Ό κ²Œμž„μ„ μ‹€ν–‰ν•˜λ©΄, 인풋 μ„Ήμ…˜μ΄ 보이고 μžλ™μ°¨ μž…λ ₯창이 ν™œμ„±ν™”λœλ‹€.=', () => { + cy.get(ID.INPUT_SECTION).should('be.visible'); + cy.get(ID.CARNAME_INPUT).should('not.be.disabled'); + cy.get(ID.CARNAME_SUBMIT).should('not.be.disabled'); + }); +}); + +describe('1. μžλ™μ°¨ 이름 μž…λ ₯ ν…ŒμŠ€νŠΈ', () => { + beforeEach(() => { + cy.visit('http://localhost:5500'); + }); + + it('μžλ™μ°¨ 이름을 μž…λ ₯ν•˜μ§€ μ•Šκ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit(''); + catchAlertMessage(ALERT.CARNAME_NOTHING); + }); + + it('μžλ™μ°¨ 이름을 1개만 μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit('jwon'); + catchAlertMessage(ALERT.CARNAME_ALONE); + }); + + it('λΉ„μ–΄μžˆλŠ” μžλ™μ°¨ 이름을 μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit('jwon, , holee'); + catchAlertMessage(ALERT.CARNAME_EMPTY); + }); + + it('μ€‘λ³΅λœ μžλ™μ°¨ 이름을 μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit('jwon, jwon, yechoi, holee, yshin'); + catchAlertMessage(ALERT.CARNAME_DOUBLE); + }); + + it('5κΈ€μž λ„˜λŠ” μžλ™μ°¨ 이름을 μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit('jwon, yechoi'); + catchAlertMessage(ALERT.CARNAME_LENGTH); + }); + + it('μžλ™μ°¨ 이름을 μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, μžλ™μ°¨ 이름 μž…λ ₯μΉΈκ³Ό 클릭 λ²„νŠΌμ„ λΉ„ν™œμ„±ν™” ν•˜κ³  μ‹œλ„ 횟수 μž…λ ₯μΉΈκ³Ό μ‹œλ„ 횟수 λ²„νŠΌμ„ ν™œμ„±ν™”ν•œλ‹€', () => { + carNameInputAndSubmit(carNamesSample); + cy.get(ID.CARNAME_INPUT).should('be.disabled'); + cy.get(ID.CARNAME_SUBMIT).should('be.disabled'); + cy.get(ID.TRYCOUNT_INPUT).should('not.be.disabled'); + cy.get(ID.TRYCOUNT_SUBMIT).should('not.be.disabled'); + }); + + it('μžλ™μ°¨ 이름을 μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 진행상황 μ„Ήμ…˜μ΄ λ‘œλ”©λœλ‹€. ', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(tryCountSample); + cy.get(ID.PROGRESS_SECTION).should('be.visible'); + }); +}); + +describe('2. μ‹œλ„ 횟수 μž…λ ₯ ν…ŒμŠ€νŠΈ', () => { + beforeEach(() => { + cy.visit('http://localhost:5500'); + }); + + it('횟수λ₯Ό μž…λ ₯ν•˜μ§€ μ•Šκ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(); + catchAlertMessage(ALERT.TRYCOUNT_NOTHING); + }); + + it('음수λ₯Ό μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(-5); + catchAlertMessage(ALERT.TRYCOUNT_UINT); + }); + + it('50 이상을 μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 경고창을 λ„μš΄λ‹€', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(51); + catchAlertMessage(ALERT.TRYCOUNT_TOO_BIG); + }); +}); + +describe('3. 진행 상황 좜λ ₯ ν…ŒμŠ€νŠΈ', () => { + beforeEach(() => { + cy.visit('http://localhost:5500'); + }); + + it('μžλ™μ°¨ 이름과 μ‹œλ„ 횟수λ₯Ό μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, κ²Œμž„ 진행 ν›„ κ²°κ³Ό μ„Ήμ…˜μ΄ λ‘œλ”©λœλ‹€', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(tryCountSample); + }); + + it('κ²Œμž„μ΄ λλ‚˜λ©΄, κ²°κ³Όλ₯Ό 좜λ ₯ν•˜κ³  μΆ•ν•˜ 메세지λ₯Ό λ„μš΄λ‹€', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(tryCountSample); + cy.wait(2000); + catchAlertMessage(ALERT.CONGRATULATION); + }); +}); + +describe('4. κ²Œμž„ μž¬μ‹œμž‘ ν…ŒμŠ€νŠΈ', () => { + beforeEach(() => { + cy.visit('http://localhost:5500'); + }); + + it('λ‹€μ‹œ μ‹œμž‘ν•˜κΈ° λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 진행 μ„Ήμ…˜κ³Ό κ²°κ³Ό μ„Ήμ…˜μ΄ 사라지고, μžλ™μ°¨ 이름 μž…λ ₯칸이 빈 μƒνƒœλ‘œ κ²Œμž„ μ‹œμž‘ λŒ€κΈ°μƒνƒœκ°€ λœλ‹€', () => { + carNameInputAndSubmit(carNamesSample); + tryCountInputAndSubmit(tryCountSample); + cy.wait(tryCountSample * DELAY.TURN + DELAY.END); + cy.get(ID.RESTART_SUBMIT).click(); + cy.get(ID.PROGRESS_SECTION).should('not.exist'); + cy.get(ID.RESULT_SECTION).should('not.exist'); + cy.get(ID.CARNAME_INPUT).should('have.value', ''); + }); +}); diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 000000000..59b2bab6e --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,22 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 000000000..119ab03f7 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 000000000..d68db96df --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/dist/constants/elements.js b/dist/constants/elements.js index 5825096cd..ed3050ca9 100644 --- a/dist/constants/elements.js +++ b/dist/constants/elements.js @@ -1,12 +1,15 @@ const ID = { APP_DIV: '#app', - CAR_DIV_LIST: '#progress-section > div > div', - CARNAMES_DIV: '#progress-section > div', - CARNAME_DIV_LIST: 'div.car-player', CARNAME_INPUT: '#car-names-input', CARNAME_SUBMIT: '#car-names-submit', TRYCOUNT_INPUT: '#racing-count-input', TRYCOUNT_SUBMIT: '#racing-count-submit', + CAR_DIV_LIST: '#progress-section > div > div', + CARNAMES_DIV: '#progress-section > div', + CARNAME_DIV_LIST: 'div.car-player', RESTART_SUBMIT: '#restart-button', + INPUT_SECTION: '#input-section', + PROGRESS_SECTION: '#progress-section', + RESULT_SECTION: '#result-section', }; export { ID }; diff --git a/package.json b/package.json index b21f60bce..c9ff4f41c 100644 --- a/package.json +++ b/package.json @@ -15,5 +15,11 @@ "eslint": "^7.28.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.23.4" + }, + "scripts": { + "cypress:open": "./node_modules/.bin/cypress open", + "cypress:run": "./node_modules/.bin/cypress run", + "tsc": "tsc", + "lint": "eslint ." } } diff --git a/src/constants/elements.ts b/src/constants/elements.ts index 7616beb72..faf53bd35 100644 --- a/src/constants/elements.ts +++ b/src/constants/elements.ts @@ -1,17 +1,21 @@ const ID = { APP_DIV: '#app', - CAR_DIV_LIST: '#progress-section > div > div', - CARNAMES_DIV: '#progress-section > div', - CARNAME_DIV_LIST: 'div.car-player', - CARNAME_INPUT: '#car-names-input', CARNAME_SUBMIT: '#car-names-submit', TRYCOUNT_INPUT: '#racing-count-input', TRYCOUNT_SUBMIT: '#racing-count-submit', + CAR_DIV_LIST: '#progress-section > div > div', + CARNAMES_DIV: '#progress-section > div', + CARNAME_DIV_LIST: 'div.car-player', + RESTART_SUBMIT: '#restart-button', + + INPUT_SECTION: '#input-section', + PROGRESS_SECTION: '#progress-section', + RESULT_SECTION: '#result-section', }; export { ID }; diff --git a/src/utils.ts b/src/utils.ts index 1d2f02c59..15c6c42d4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -23,7 +23,7 @@ const buttonElementDisable = (element: HTMLButtonElement): void => { element.disabled = true; }; -const makeDelay = async (ms: number) => { +const makeDelay = async (ms: number): Promise => { return new Promise((r) => setTimeout(r, ms)); }; From dc4eb40631078be6de03e08ecb4a0867e193af8b Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:48:09 +0900 Subject: [PATCH 52/70] Delete game-control.js --- dist/controller/game-control.js | 59 --------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 dist/controller/game-control.js diff --git a/dist/controller/game-control.js b/dist/controller/game-control.js deleted file mode 100644 index 6d67d8495..000000000 --- a/dist/controller/game-control.js +++ /dev/null @@ -1,59 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import { ALERT } from '../constants/index.js'; -import { Car, Game } from '../model/index.js'; -import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRestartButtonEvent } from './event.js'; -import { $$, makeDelay } from '../utils.js'; -import { removeSpinners } from '../view/remover.js'; -const createCarsObject = (carNameArray) => { - let cars = []; - carNameArray.forEach((car, index) => { - cars.push(new Car(car, index)); - }); - return cars; -}; -const checkRoundWinner = (racingGame, car, index) => { - racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - if (car.index === index && car.index === roundWinnerIndex) { - return true; - } - }); - return false; -}; -const playOnce = (racingGame) => { - racingGame.play(); - $$('div.car-player').forEach((element, index) => { - racingGame.cars.forEach((car) => { - if (checkRoundWinner(racingGame, car, index)) { - renderArrowDiv(element); - } - // racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - // if (car.index === index && car.index === roundWinnerIndex) { - // renderArrowDiv(element); - // } - // }); - }); - }); - racingGame.initRoundWinnersIndex(); -}; -const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { - const racingGame = new Game(createCarsObject(carNameArray)); - let racingWinners = []; - for (let index = 0; index < tryCount; index += 1) { - yield makeDelay(1000).then(() => playOnce(racingGame)); - } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ - removeSpinners(); - racingWinners = racingGame.getWinners(); - renderResultSection(racingWinners.join(', ').toLowerCase()); - yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - setRestartButtonEvent(); -}); -export { startGame }; From 23cabd7c69fd09471f6279a4a6915052590c1b50 Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:50:19 +0900 Subject: [PATCH 53/70] =?UTF-8?q?feat:=20delete=20utils.js=20(dist?= =?UTF-8?q?=EC=97=90=20=EC=9C=84=EC=B9=98=ED=95=98=EB=8A=94=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/utils.js | 45 ---------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 dist/controller/utils.js diff --git a/dist/controller/utils.js b/dist/controller/utils.js deleted file mode 100644 index 1824f56d8..000000000 --- a/dist/controller/utils.js +++ /dev/null @@ -1,45 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -const $ = (selector) => document.querySelector(selector); -const $$ = (selector) => document.querySelectorAll(selector); -const clearInput = (element) => { - element.value = ''; - element.focus(); -}; -const toggleInputValueDisabled = (element) => { - if (element.disabled) { - element.disabled = false; - } - else { - element.disabled = true; - } -}; -const toggleClickButtonDisabled = (element) => { - if (element.disabled) { - element.disabled = false; - } - else { - element.disabled = true; - } -}; -const removeChildNodes = (element) => { - if (!element) { - return; - } - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } - } -}; -const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { - return new Promise((r) => setTimeout(r, ms)); -}); -export { $, $$, clearInput, toggleInputValueDisabled, toggleClickButtonDisabled, removeChildNodes, makeDelay }; From ee9c3422c98b34fd38672ecd28dc87ed2b6e85d7 Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:51:05 +0900 Subject: [PATCH 54/70] =?UTF-8?q?feat:=20delete=20play.js=20(dist=EC=97=90?= =?UTF-8?q?=20=EC=9C=84=EC=B9=98=ED=95=98=EB=8A=94=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=8C=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/play.js | 48 ----------------------------------------- 1 file changed, 48 deletions(-) delete mode 100644 dist/controller/play.js diff --git a/dist/controller/play.js b/dist/controller/play.js deleted file mode 100644 index a018c74f9..000000000 --- a/dist/controller/play.js +++ /dev/null @@ -1,48 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import { ALERT } from '../constants/index.js'; -import { Car, Game } from '../model/index.js'; -import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRestartButtonEvent } from './event.js'; -import { $$, makeDelay } from '../utils.js'; -import { removeSpinners } from '../view/remover.js'; -const createCarsObject = (carNameArray) => { - let cars = []; - carNameArray.forEach((car, index) => { - cars.push(new Car(car, index)); - }); - return cars; -}; -const playOnce = (racingGame) => { - racingGame.play(); - $$('div.car-player').forEach((element, index) => { - racingGame.cars.forEach((car) => { - racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - if (car.index === index && car.index === roundWinnerIndex) { - renderArrowDiv(element); - } - }); - }); - }); - racingGame.initRoundWinnersIndex(); -}; -const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { - const racingGame = new Game(createCarsObject(carNameArray)); - let racingWinners = []; - for (let index = 0; index < tryCount; index += 1) { - yield makeDelay(1000).then(() => playOnce(racingGame)); - } // μ‹œλ„ 횟수만큼 ν”Œλ ˆμ΄ - removeSpinners(); - racingWinners = racingGame.getWinners(); - renderResultSection(racingWinners.join(', ').toLowerCase()); - yield makeDelay(2000).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - setRestartButtonEvent(); -}); -export { startGame }; From b0c63172291baade10f9dd7ed3fe158a383f4885 Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:51:57 +0900 Subject: [PATCH 55/70] =?UTF-8?q?feat:=20delete=20cypress/support/commands?= =?UTF-8?q?.js=20(=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/support/commands.js | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 cypress/support/commands.js diff --git a/cypress/support/commands.js b/cypress/support/commands.js deleted file mode 100644 index 119ab03f7..000000000 --- a/cypress/support/commands.js +++ /dev/null @@ -1,25 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) From b2468a8392590b6607054261c54122b7060cedcc Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:52:18 +0900 Subject: [PATCH 56/70] =?UTF-8?q?feat:=20delete=20cypress/support/index.js?= =?UTF-8?q?=20(=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/support/index.js | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 cypress/support/index.js diff --git a/cypress/support/index.js b/cypress/support/index.js deleted file mode 100644 index d68db96df..000000000 --- a/cypress/support/index.js +++ /dev/null @@ -1,20 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' - -// Alternatively you can use CommonJS syntax: -// require('./commands') From 9344a9ea42a19777d45e24cf78f01f8f563c8b9d Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:53:47 +0900 Subject: [PATCH 57/70] =?UTF-8?q?feat:=20delete=20cypress/fixtures/example?= =?UTF-8?q?.json=20(=EC=82=AC=EC=9A=A9=ED=95=98=EC=A7=80=20=EC=95=8A?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/fixtures/example.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 cypress/fixtures/example.json diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json deleted file mode 100644 index 02e425437..000000000 --- a/cypress/fixtures/example.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} From b62e122ea3c2a8e8b01696bca9fd5c79d4271d6b Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:55:16 +0900 Subject: [PATCH 58/70] feat: delete index.html.backup --- index.html.backup | 71 ----------------------------------------------- 1 file changed, 71 deletions(-) delete mode 100644 index.html.backup diff --git a/index.html.backup b/index.html.backup deleted file mode 100644 index ea5891942..000000000 --- a/index.html.backup +++ /dev/null @@ -1,71 +0,0 @@ - - - - - 🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„ - - - -
-
-
-
-

🏎️ μžλ™μ°¨ κ²½μ£Ό κ²Œμž„

-

- 5자 μ΄ν•˜μ˜ μžλ™μ°¨ 이름을 콀마둜 κ΅¬λΆ„ν•˜μ—¬ μž…λ ₯ν•΄μ£Όμ„Έμš”.
- μ˜ˆμ‹œ) EAST, WEST, SOUTH, NORTH -

-
- - -
-
-
-

μ‹œλ„ν•  횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.

-
- - -
-
-
-
-
-
-
-
EAST
-
⬇️️
-
⬇️️
-
-
-
WEST
-
⬇️️
-
-
-
SOUTH
-
-
- -
-
-
-
-
NORTH
-
-
- -
-
-
-
-
-
-
-

πŸ† μ΅œμ’… 우승자: EAST, WEST πŸ†

-
- -
-
-
-
- - From 6df563a06685229464c2969d31778876990cfd6e Mon Sep 17 00:00:00 2001 From: Junho Won <61400214+jwon42@users.noreply.github.com> Date: Tue, 8 Jun 2021 00:56:13 +0900 Subject: [PATCH 59/70] feat: delete .eslintrc.js --- .eslintrc.js | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index e431fdea7..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - env: { - browser: true, - es2021: true, - }, - extends: [ - 'airbnb-base', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 12, - sourceType: 'module', - }, - plugins: [ - '@typescript-eslint', - ], - rules: { - }, - ignorePattern: [ - 'dist/', - 'node_modules/', - ], -}; From a51a9b2ed87189fc77e4c58bc21e4a0d5f85aed9 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Tue, 8 Jun 2021 22:10:25 +0900 Subject: [PATCH 60/70] =?UTF-8?q?refactor:=20eslint=20=EC=A0=9C=EC=95=88?= =?UTF-8?q?=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/controller/event.js | 8 +++++--- dist/controller/game.js | 2 +- dist/controller/linstener.js | 4 +--- dist/model/game.js | 4 ---- src/controller/event.ts | 6 +++--- src/controller/game.ts | 4 ++-- src/controller/linstener.ts | 7 ++----- src/model/game.ts | 10 +++++----- src/view/remover.ts | 2 +- src/view/renderer.ts | 12 ++++++------ 10 files changed, 26 insertions(+), 33 deletions(-) diff --git a/dist/controller/event.js b/dist/controller/event.js index cccaae888..b3c5473fd 100644 --- a/dist/controller/event.js +++ b/dist/controller/event.js @@ -2,10 +2,12 @@ import { $ } from '../utils.js'; import { ID } from '../constants/index.js'; import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = () => { - $(ID.CARNAME_SUBMIT).addEventListener('click', () => getCarNames()); - $(ID.TRYCOUNT_SUBMIT).addEventListener('click', () => getTryCount()); + var _a, _b; + (_a = $(ID.CARNAME_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames()); + (_b = $(ID.TRYCOUNT_SUBMIT)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount()); }; const setRestartButtonEvent = () => { - $(ID.RESTART_SUBMIT).addEventListener('click', () => restartApp()); + var _a; + (_a = $(ID.RESTART_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => restartApp()); }; export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/dist/controller/game.js b/dist/controller/game.js index c1460f8dc..7395b77df 100644 --- a/dist/controller/game.js +++ b/dist/controller/game.js @@ -14,7 +14,7 @@ import { setRestartButtonEvent } from './event.js'; import { makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; const createCarsObject = (carNameArray) => { - let cars = []; + const cars = []; carNameArray.forEach((car, index) => { cars.push(new Car(car, index)); }); diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index cdd340ecc..458d4a8db 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -37,11 +37,9 @@ const getTryCount = () => { inputElementClear(tryCountInput); }; const restartApp = () => { - let carNameInput; removeChildNodes($(ID.APP_DIV)); renderInputSection(); setInputButtonsEvent(); - carNameInput = $(ID.CARNAME_INPUT); - carNameInput.focus(); + $(ID.CARNAME_INPUT).focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/dist/model/game.js b/dist/model/game.js index f5e42566c..642e31b20 100644 --- a/dist/model/game.js +++ b/dist/model/game.js @@ -15,7 +15,6 @@ class Game { } }); } - ; updateMaxPosition() { this.cars.forEach((car) => { if (car.position > this.maxPosition) { @@ -23,11 +22,9 @@ class Game { } }); } - ; initRoundWinnersIndex() { this.roundWinnersIndex = []; } - ; getWinners() { this.cars.forEach((car) => { if (car.position === this.maxPosition) { @@ -36,6 +33,5 @@ class Game { }); return this.finalWinners; } - ; } export { Game }; diff --git a/src/controller/event.ts b/src/controller/event.ts index 60c0f8ecc..3229d67b4 100644 --- a/src/controller/event.ts +++ b/src/controller/event.ts @@ -3,12 +3,12 @@ import { ID } from '../constants/index.js'; import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = (): void => { - $(ID.CARNAME_SUBMIT)!.addEventListener('click', () => getCarNames()); - $(ID.TRYCOUNT_SUBMIT)!.addEventListener('click', () => getTryCount()); + $(ID.CARNAME_SUBMIT)?.addEventListener('click', () => getCarNames()); + $(ID.TRYCOUNT_SUBMIT)?.addEventListener('click', () => getTryCount()); }; const setRestartButtonEvent = (): void => { - $(ID.RESTART_SUBMIT)!.addEventListener('click', () => restartApp()); + $(ID.RESTART_SUBMIT)?.addEventListener('click', () => restartApp()); }; export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/src/controller/game.ts b/src/controller/game.ts index 41fdd5a72..69ed04acc 100644 --- a/src/controller/game.ts +++ b/src/controller/game.ts @@ -6,7 +6,7 @@ import { makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; const createCarsObject = (carNameArray: Array) => { - let cars: Array = []; + const cars: Array = []; carNameArray.forEach((car, index) => { cars.push(new Car(car, index)); @@ -22,7 +22,7 @@ const playOnce = (racingGame: Game) => { racingGame.initRoundWinnersIndex(); }; -const startGame = async (carNameArray: Array, tryCount: number) => { +const startGame = async (carNameArray: Array, tryCount: number): Promise => { const racingGame: Game = new Game(createCarsObject(carNameArray)); let racingWinners: Array = []; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index 7fd0077cf..9d27e31d9 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -35,7 +35,7 @@ const getCarNames = (): void => { const getTryCount = (): void => { const tryCountInput: HTMLInputElement = $(ID.TRYCOUNT_INPUT) as HTMLInputElement; - const tryCount: number = Number(tryCountInput?.value); + const tryCount = Number(tryCountInput?.value); if (checkTryCount(tryCountInput)) { const carNameInput: HTMLInputElement = $(ID.CARNAME_INPUT) as HTMLInputElement; @@ -51,13 +51,10 @@ const getTryCount = (): void => { }; const restartApp = (): void => { - let carNameInput: HTMLInputElement; - removeChildNodes($(ID.APP_DIV)); renderInputSection(); setInputButtonsEvent(); - carNameInput = $(ID.CARNAME_INPUT) as HTMLInputElement; - carNameInput.focus(); + ($(ID.CARNAME_INPUT) as HTMLInputElement).focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/src/model/game.ts b/src/model/game.ts index e0a967996..0c8b524a1 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -1,5 +1,5 @@ import { Car } from './index.js'; -import { RULE } from '../constants/index.js' +import { RULE } from '../constants/index.js'; class Game { cars: Array; finalWinners: Array; @@ -21,7 +21,7 @@ class Game { this.updateMaxPosition(); } }); - }; + } updateMaxPosition(): void { this.cars.forEach((car) => { @@ -29,11 +29,11 @@ class Game { this.maxPosition = car.position; } }); - }; + } initRoundWinnersIndex(): void { this.roundWinnersIndex = []; - }; + } getWinners(): Array { this.cars.forEach((car) => { @@ -42,7 +42,7 @@ class Game { } }); return this.finalWinners; - }; + } } export { Game }; diff --git a/src/view/remover.ts b/src/view/remover.ts index 5ccf05a2a..00a209a6b 100644 --- a/src/view/remover.ts +++ b/src/view/remover.ts @@ -1,6 +1,6 @@ import { $$ } from '../utils.js'; -const removeSpinners = () => { +const removeSpinners = (): void => { $$('div.d-flex.justify-center.mt-3').forEach((element) => { element.remove(); }); diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 4f8078ee3..25eb8e8f6 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -3,27 +3,27 @@ import { $, $$ } from '../utils.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { - $(ID.APP_DIV)!.innerHTML = inputSection(); + ($(ID.APP_DIV) as HTMLDivElement).innerHTML = inputSection(); }; const renderProgressSection = (carNameArray: Array): void => { - $(ID.APP_DIV)!.insertAdjacentHTML('beforeend', progressSection()); + ($(ID.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - $(ID.CARNAMES_DIV)!.insertAdjacentHTML('beforeend', carNameDiv(carName)); + ($(ID.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - $$(ID.CAR_DIV_LIST)!.forEach((element) => { + ($$(ID.CAR_DIV_LIST) as NodeListOf).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex: number): void => { - $$(ID.CARNAME_DIV_LIST).forEach((element, index) => { + ($$(ID.CARNAME_DIV_LIST) as NodeListOf).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const renderResultSection = (winners: string): void => { - $(ID.APP_DIV)!.insertAdjacentHTML('beforeend', resultSection(winners)); + ($(ID.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; From efef57b1b96ec7550c069cda8f4e2d37fc004df5 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Tue, 8 Jun 2021 22:35:33 +0900 Subject: [PATCH 61/70] =?UTF-8?q?refactor:=20elementsID=20constants=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/elements.js | 14 +++++++++----- dist/view/renderer.js | 4 ++-- src/constants/elements.ts | 18 ++++++++++-------- src/view/remover.ts | 3 ++- src/view/renderer.ts | 4 ++-- 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/dist/constants/elements.js b/dist/constants/elements.js index ed3050ca9..703ddc32c 100644 --- a/dist/constants/elements.js +++ b/dist/constants/elements.js @@ -1,15 +1,19 @@ const ID = { APP_DIV: '#app', + // input-section + INPUT_SECTION: '#input-section', CARNAME_INPUT: '#car-names-input', CARNAME_SUBMIT: '#car-names-submit', TRYCOUNT_INPUT: '#racing-count-input', TRYCOUNT_SUBMIT: '#racing-count-submit', - CAR_DIV_LIST: '#progress-section > div > div', - CARNAMES_DIV: '#progress-section > div', - CARNAME_DIV_LIST: 'div.car-player', - RESTART_SUBMIT: '#restart-button', - INPUT_SECTION: '#input-section', + // progress-section PROGRESS_SECTION: '#progress-section', + CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', + CARNAMES_DIV: '#progress-section .mt-4', + CARNAME_DIVS: '#progress-section .car-player', + SPINNER_DIVS: '#progress-section .mt-3', + // result-section RESULT_SECTION: '#result-section', + RESTART_SUBMIT: '#restart-button', }; export { ID }; diff --git a/dist/view/renderer.js b/dist/view/renderer.js index 07fa9071d..288597283 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -9,12 +9,12 @@ const renderProgressSection = (carNameArray) => { carNameArray.forEach((carName) => { $(ID.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - $$(ID.CAR_DIV_LIST).forEach((element) => { + $$(ID.CAR_RACE_TRACK_DIVS).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex) => { - $$(ID.CARNAME_DIV_LIST).forEach((element, index) => { + $$(ID.CARNAME_DIVS).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; diff --git a/src/constants/elements.ts b/src/constants/elements.ts index faf53bd35..7b5fa1c36 100644 --- a/src/constants/elements.ts +++ b/src/constants/elements.ts @@ -1,21 +1,23 @@ const ID = { APP_DIV: '#app', + // input-section + INPUT_SECTION: '#input-section', CARNAME_INPUT: '#car-names-input', CARNAME_SUBMIT: '#car-names-submit', - TRYCOUNT_INPUT: '#racing-count-input', TRYCOUNT_SUBMIT: '#racing-count-submit', - CAR_DIV_LIST: '#progress-section > div > div', - CARNAMES_DIV: '#progress-section > div', - CARNAME_DIV_LIST: 'div.car-player', - - RESTART_SUBMIT: '#restart-button', - - INPUT_SECTION: '#input-section', + // progress-section PROGRESS_SECTION: '#progress-section', + CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', + CARNAMES_DIV: '#progress-section .mt-4', + CARNAME_DIVS: '#progress-section .car-player', + SPINNER_DIVS: '#progress-section .mt-3', + + // result-section RESULT_SECTION: '#result-section', + RESTART_SUBMIT: '#restart-button', }; export { ID }; diff --git a/src/view/remover.ts b/src/view/remover.ts index 00a209a6b..2dc52bffd 100644 --- a/src/view/remover.ts +++ b/src/view/remover.ts @@ -1,7 +1,8 @@ import { $$ } from '../utils.js'; +import { ID } from '../constants/elements.js'; const removeSpinners = (): void => { - $$('div.d-flex.justify-center.mt-3').forEach((element) => { + $$(ID.SPINNER_DIVS).forEach((element) => { element.remove(); }); }; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index 25eb8e8f6..bd0e74592 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -11,13 +11,13 @@ const renderProgressSection = (carNameArray: Array): void => { carNameArray.forEach((carName) => { ($(ID.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - ($$(ID.CAR_DIV_LIST) as NodeListOf).forEach((element) => { + ($$(ID.CAR_RACE_TRACK_DIVS) as NodeListOf).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex: number): void => { - ($$(ID.CARNAME_DIV_LIST) as NodeListOf).forEach((element, index) => { + ($$(ID.CARNAME_DIVS) as NodeListOf).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; From b16496fe1dc0fd11ce4329c4016719c74210ac37 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Tue, 8 Jun 2021 22:48:20 +0900 Subject: [PATCH 62/70] =?UTF-8?q?refactor:=20makeDelay=ED=95=A8=EC=88=98?= =?UTF-8?q?=20game=ED=8C=8C=EC=9D=BC=EC=97=90=EC=84=9C=EB=A7=8C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=EB=90=98=EB=AF=80=EB=A1=9C=20utils=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/game.ts | 5 ++++- src/utils.ts | 7 +------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/controller/game.ts b/src/controller/game.ts index 69ed04acc..5882ef26c 100644 --- a/src/controller/game.ts +++ b/src/controller/game.ts @@ -2,9 +2,12 @@ import { ALERT, DELAY } from '../constants/index.js'; import { Car, Game } from '../model/index.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; -import { makeDelay } from '../utils.js'; import { removeSpinners } from '../view/remover.js'; +const makeDelay = async (ms: number): Promise => { + return new Promise((r) => setTimeout(r, ms)); +}; + const createCarsObject = (carNameArray: Array) => { const cars: Array = []; diff --git a/src/utils.ts b/src/utils.ts index 15c6c42d4..10ffc9764 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -23,10 +23,6 @@ const buttonElementDisable = (element: HTMLButtonElement): void => { element.disabled = true; }; -const makeDelay = async (ms: number): Promise => { - return new Promise((r) => setTimeout(r, ms)); -}; - export { $, $$, @@ -34,6 +30,5 @@ export { inputElementEnable, inputElementDisable, buttonElementEnable, - buttonElementDisable, - makeDelay, + buttonElementDisable }; From 9ad005b4c9d40cff8c4990451119273c6fbd5cde Mon Sep 17 00:00:00 2001 From: jwon42 Date: Tue, 8 Jun 2021 23:12:17 +0900 Subject: [PATCH 63/70] =?UTF-8?q?refactor:=20=EC=B6=95=ED=95=98=20?= =?UTF-8?q?=ED=8C=9D=EC=97=85=20=EC=9D=B4=ED=9B=84=20=EB=8B=A4=EC=8B=9C?= =?UTF-8?q?=EC=8B=9C=EC=9E=91=20=EB=B2=84=ED=8A=BC=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dist/constants/index.js | 2 +- dist/constants/selector.js | 19 +++++++++++++++++++ dist/controller/event.js | 8 ++++---- dist/controller/game.js | 10 +++++++--- dist/controller/linstener.js | 20 ++++++++++---------- dist/utils.js | 14 +------------- dist/view/remover.js | 3 ++- dist/view/renderer.js | 14 +++++++------- dist/view/templates/result-section.js | 2 +- src/constants/index.ts | 2 +- src/constants/{elements.ts => selector.ts} | 4 ++-- src/controller/event.ts | 8 ++++---- src/controller/game.ts | 7 +++++-- src/controller/linstener.ts | 20 ++++++++++---------- src/model/game.ts | 1 + src/view/remover.ts | 4 ++-- src/view/renderer.ts | 14 +++++++------- src/view/templates/result-section.ts | 2 +- 18 files changed, 85 insertions(+), 69 deletions(-) create mode 100644 dist/constants/selector.js rename src/constants/{elements.ts => selector.ts} (93%) diff --git a/dist/constants/index.js b/dist/constants/index.js index d53e2e66b..a3f677f02 100644 --- a/dist/constants/index.js +++ b/dist/constants/index.js @@ -1,4 +1,4 @@ -export { ID } from './elements.js'; +export { SELECTOR } from './selector.js'; export { ALERT } from './alert.js'; export { RULE } from './rule.js'; export { DELAY } from './delay.js'; diff --git a/dist/constants/selector.js b/dist/constants/selector.js new file mode 100644 index 000000000..8e30a9fa5 --- /dev/null +++ b/dist/constants/selector.js @@ -0,0 +1,19 @@ +const SELECTOR = { + APP_DIV: '#app', + // input-section + INPUT_SECTION: '#input-section', + CARNAME_INPUT: '#car-names-input', + CARNAME_SUBMIT: '#car-names-submit', + TRYCOUNT_INPUT: '#racing-count-input', + TRYCOUNT_SUBMIT: '#racing-count-submit', + // progress-section + PROGRESS_SECTION: '#progress-section', + CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', + CARNAMES_DIV: '#progress-section .mt-4', + CARNAME_DIVS: '#progress-section .car-player', + SPINNER_DIVS: '#progress-section .mt-3', + // result-section + RESULT_SECTION: '#result-section', + RESTART_SUBMIT: '#restart-button', +}; +export { SELECTOR }; diff --git a/dist/controller/event.js b/dist/controller/event.js index b3c5473fd..f74f67713 100644 --- a/dist/controller/event.js +++ b/dist/controller/event.js @@ -1,13 +1,13 @@ import { $ } from '../utils.js'; -import { ID } from '../constants/index.js'; +import { SELECTOR } from '../constants/index.js'; import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = () => { var _a, _b; - (_a = $(ID.CARNAME_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames()); - (_b = $(ID.TRYCOUNT_SUBMIT)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount()); + (_a = $(SELECTOR.CARNAME_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames()); + (_b = $(SELECTOR.TRYCOUNT_SUBMIT)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount()); }; const setRestartButtonEvent = () => { var _a; - (_a = $(ID.RESTART_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => restartApp()); + (_a = $(SELECTOR.RESTART_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => restartApp()); }; export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/dist/controller/game.js b/dist/controller/game.js index 7395b77df..570bff56b 100644 --- a/dist/controller/game.js +++ b/dist/controller/game.js @@ -7,12 +7,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -import { ALERT, DELAY } from '../constants/index.js'; +import { ALERT, DELAY, SELECTOR } from '../constants/index.js'; +import { $, buttonElementEnable } from '../utils.js'; import { Car, Game } from '../model/index.js'; +import { removeSpinners } from '../view/remover.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; -import { makeDelay } from '../utils.js'; -import { removeSpinners } from '../view/remover.js'; +const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { + return new Promise((r) => setTimeout(r, ms)); +}); const createCarsObject = (carNameArray) => { const cars = []; carNameArray.forEach((car, index) => { @@ -37,6 +40,7 @@ const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); yield makeDelay(DELAY.END).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + buttonElementEnable($(SELECTOR.RESTART_SUBMIT)); setRestartButtonEvent(); }); export { startGame }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js index 458d4a8db..658f34bb2 100644 --- a/dist/controller/linstener.js +++ b/dist/controller/linstener.js @@ -1,4 +1,4 @@ -import { ID } from '../constants/index.js'; +import { SELECTOR } from '../constants/index.js'; import { startGame } from './game.js'; import { renderProgressSection, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; @@ -6,12 +6,12 @@ import { checkCarNames, checkTryCount } from './validtor.js'; import { removeChildNodes } from '../view/remover.js'; import { $, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, } from '../utils.js'; const getCarNames = () => { - const carNameInput = $(ID.CARNAME_INPUT); + const carNameInput = $(SELECTOR.CARNAME_INPUT); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton = $(ID.CARNAME_SUBMIT); - const tryCountInput = $(ID.TRYCOUNT_INPUT); - const tryCountSubmitButton = $(ID.TRYCOUNT_SUBMIT); + const carNameSubmitButton = $(SELECTOR.CARNAME_SUBMIT); + const tryCountInput = $(SELECTOR.TRYCOUNT_INPUT); + const tryCountSubmitButton = $(SELECTOR.TRYCOUNT_SUBMIT); inputElementDisable(carNameInput); buttonElementDisable(carNameSubmitButton); inputElementEnable(tryCountInput); @@ -23,12 +23,12 @@ const getCarNames = () => { inputElementClear(carNameInput); }; const getTryCount = () => { - const tryCountInput = $(ID.TRYCOUNT_INPUT); + const tryCountInput = $(SELECTOR.TRYCOUNT_INPUT); const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); if (checkTryCount(tryCountInput)) { - const carNameInput = $(ID.CARNAME_INPUT); + const carNameInput = $(SELECTOR.CARNAME_INPUT); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - const tryCountSubmitButton = $(ID.TRYCOUNT_SUBMIT); + const tryCountSubmitButton = $(SELECTOR.TRYCOUNT_SUBMIT); inputElementDisable(tryCountInput); buttonElementDisable(tryCountSubmitButton); startGame(carNameArray, tryCount); @@ -37,9 +37,9 @@ const getTryCount = () => { inputElementClear(tryCountInput); }; const restartApp = () => { - removeChildNodes($(ID.APP_DIV)); + removeChildNodes($(SELECTOR.APP_DIV)); renderInputSection(); setInputButtonsEvent(); - $(ID.CARNAME_INPUT).focus(); + $(SELECTOR.CARNAME_INPUT).focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/dist/utils.js b/dist/utils.js index 4dedb9873..625922527 100644 --- a/dist/utils.js +++ b/dist/utils.js @@ -1,12 +1,3 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; const $ = (selector) => document.querySelector(selector); const $$ = (selector) => document.querySelectorAll(selector); const inputElementClear = (element) => { @@ -25,7 +16,4 @@ const buttonElementEnable = (element) => { const buttonElementDisable = (element) => { element.disabled = true; }; -const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { - return new Promise((r) => setTimeout(r, ms)); -}); -export { $, $$, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, makeDelay, }; +export { $, $$, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable }; diff --git a/dist/view/remover.js b/dist/view/remover.js index ab037e96c..05320964c 100644 --- a/dist/view/remover.js +++ b/dist/view/remover.js @@ -1,6 +1,7 @@ import { $$ } from '../utils.js'; +import { SELECTOR } from '../constants/selector.js'; const removeSpinners = () => { - $$('div.d-flex.justify-center.mt-3').forEach((element) => { + $$(SELECTOR.SPINNER_DIVS).forEach((element) => { element.remove(); }); }; diff --git a/dist/view/renderer.js b/dist/view/renderer.js index 288597283..85046e459 100644 --- a/dist/view/renderer.js +++ b/dist/view/renderer.js @@ -1,24 +1,24 @@ -import { ID } from '../constants/index.js'; import { $, $$ } from '../utils.js'; +import { SELECTOR } from '../constants/index.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = () => { - $(ID.APP_DIV).innerHTML = inputSection(); + $(SELECTOR.APP_DIV).innerHTML = inputSection(); }; const renderProgressSection = (carNameArray) => { - $(ID.APP_DIV).insertAdjacentHTML('beforeend', progressSection()); + $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - $(ID.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); + $(SELECTOR.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - $$(ID.CAR_RACE_TRACK_DIVS).forEach((element) => { + $$(SELECTOR.CAR_RACE_TRACK_DIVS).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex) => { - $$(ID.CARNAME_DIVS).forEach((element, index) => { + $$(SELECTOR.CARNAME_DIVS).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const renderResultSection = (winners) => { - $(ID.APP_DIV).insertAdjacentHTML('beforeend', resultSection(winners)); + $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; diff --git a/dist/view/templates/result-section.js b/dist/view/templates/result-section.js index 925f1d1d2..7e07a6190 100644 --- a/dist/view/templates/result-section.js +++ b/dist/view/templates/result-section.js @@ -4,7 +4,7 @@ const resultSection = (winners) => {

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

- +
diff --git a/src/constants/index.ts b/src/constants/index.ts index d53e2e66b..a3f677f02 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,4 +1,4 @@ -export { ID } from './elements.js'; +export { SELECTOR } from './selector.js'; export { ALERT } from './alert.js'; export { RULE } from './rule.js'; export { DELAY } from './delay.js'; diff --git a/src/constants/elements.ts b/src/constants/selector.ts similarity index 93% rename from src/constants/elements.ts rename to src/constants/selector.ts index 7b5fa1c36..0b69dfd47 100644 --- a/src/constants/elements.ts +++ b/src/constants/selector.ts @@ -1,4 +1,4 @@ -const ID = { +const SELECTOR = { APP_DIV: '#app', // input-section @@ -20,4 +20,4 @@ const ID = { RESTART_SUBMIT: '#restart-button', }; -export { ID }; +export { SELECTOR }; diff --git a/src/controller/event.ts b/src/controller/event.ts index 3229d67b4..0f0c82622 100644 --- a/src/controller/event.ts +++ b/src/controller/event.ts @@ -1,14 +1,14 @@ import { $ } from '../utils.js'; -import { ID } from '../constants/index.js'; +import { SELECTOR } from '../constants/index.js'; import { getCarNames, getTryCount, restartApp } from './linstener.js'; const setInputButtonsEvent = (): void => { - $(ID.CARNAME_SUBMIT)?.addEventListener('click', () => getCarNames()); - $(ID.TRYCOUNT_SUBMIT)?.addEventListener('click', () => getTryCount()); + $(SELECTOR.CARNAME_SUBMIT)?.addEventListener('click', () => getCarNames()); + $(SELECTOR.TRYCOUNT_SUBMIT)?.addEventListener('click', () => getTryCount()); }; const setRestartButtonEvent = (): void => { - $(ID.RESTART_SUBMIT)?.addEventListener('click', () => restartApp()); + $(SELECTOR.RESTART_SUBMIT)?.addEventListener('click', () => restartApp()); }; export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/src/controller/game.ts b/src/controller/game.ts index 5882ef26c..177a14d23 100644 --- a/src/controller/game.ts +++ b/src/controller/game.ts @@ -1,8 +1,10 @@ -import { ALERT, DELAY } from '../constants/index.js'; +import { ALERT, DELAY, SELECTOR } from '../constants/index.js'; +import { $, buttonElementEnable } from '../utils.js'; import { Car, Game } from '../model/index.js'; +import { removeSpinners } from '../view/remover.js'; import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; import { setRestartButtonEvent } from './event.js'; -import { removeSpinners } from '../view/remover.js'; +import { buttonElementDisable } from '../utils.js'; const makeDelay = async (ms: number): Promise => { return new Promise((r) => setTimeout(r, ms)); @@ -36,6 +38,7 @@ const startGame = async (carNameArray: Array, tryCount: number): Promise racingWinners = racingGame.getWinners(); renderResultSection(racingWinners.join(', ').toLowerCase()); await makeDelay(DELAY.END).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); + buttonElementEnable($(SELECTOR.RESTART_SUBMIT) as HTMLButtonElement); setRestartButtonEvent(); }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts index 9d27e31d9..4e8833ebd 100644 --- a/src/controller/linstener.ts +++ b/src/controller/linstener.ts @@ -1,4 +1,4 @@ -import { ID } from '../constants/index.js'; +import { SELECTOR } from '../constants/index.js'; import { startGame } from './game.js'; import { renderProgressSection, renderInputSection } from '../view/renderer.js'; import { setInputButtonsEvent } from './event.js'; @@ -14,13 +14,13 @@ import { } from '../utils.js'; const getCarNames = (): void => { - const carNameInput: HTMLInputElement = $(ID.CARNAME_INPUT) as HTMLInputElement; + const carNameInput: HTMLInputElement = $(SELECTOR.CARNAME_INPUT) as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton: HTMLButtonElement = $(ID.CARNAME_SUBMIT) as HTMLButtonElement; - const tryCountInput: HTMLInputElement = $(ID.TRYCOUNT_INPUT) as HTMLInputElement; - const tryCountSubmitButton: HTMLButtonElement = $(ID.TRYCOUNT_SUBMIT) as HTMLButtonElement; + const carNameSubmitButton: HTMLButtonElement = $(SELECTOR.CARNAME_SUBMIT) as HTMLButtonElement; + const tryCountInput: HTMLInputElement = $(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement; + const tryCountSubmitButton: HTMLButtonElement = $(SELECTOR.TRYCOUNT_SUBMIT) as HTMLButtonElement; inputElementDisable(carNameInput); buttonElementDisable(carNameSubmitButton); @@ -34,13 +34,13 @@ const getCarNames = (): void => { }; const getTryCount = (): void => { - const tryCountInput: HTMLInputElement = $(ID.TRYCOUNT_INPUT) as HTMLInputElement; + const tryCountInput: HTMLInputElement = $(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement; const tryCount = Number(tryCountInput?.value); if (checkTryCount(tryCountInput)) { - const carNameInput: HTMLInputElement = $(ID.CARNAME_INPUT) as HTMLInputElement; + const carNameInput: HTMLInputElement = $(SELECTOR.CARNAME_INPUT) as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - const tryCountSubmitButton: HTMLButtonElement = $(ID.TRYCOUNT_SUBMIT) as HTMLButtonElement; + const tryCountSubmitButton: HTMLButtonElement = $(SELECTOR.TRYCOUNT_SUBMIT) as HTMLButtonElement; inputElementDisable(tryCountInput); buttonElementDisable(tryCountSubmitButton); @@ -51,10 +51,10 @@ const getTryCount = (): void => { }; const restartApp = (): void => { - removeChildNodes($(ID.APP_DIV)); + removeChildNodes($(SELECTOR.APP_DIV)); renderInputSection(); setInputButtonsEvent(); - ($(ID.CARNAME_INPUT) as HTMLInputElement).focus(); + ($(SELECTOR.CARNAME_INPUT) as HTMLInputElement).focus(); }; export { getCarNames, getTryCount, restartApp }; diff --git a/src/model/game.ts b/src/model/game.ts index 0c8b524a1..0ddc9b22e 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -1,5 +1,6 @@ import { Car } from './index.js'; import { RULE } from '../constants/index.js'; + class Game { cars: Array; finalWinners: Array; diff --git a/src/view/remover.ts b/src/view/remover.ts index 2dc52bffd..44af637f7 100644 --- a/src/view/remover.ts +++ b/src/view/remover.ts @@ -1,8 +1,8 @@ import { $$ } from '../utils.js'; -import { ID } from '../constants/elements.js'; +import { SELECTOR } from '../constants/selector.js'; const removeSpinners = (): void => { - $$(ID.SPINNER_DIVS).forEach((element) => { + $$(SELECTOR.SPINNER_DIVS).forEach((element) => { element.remove(); }); }; diff --git a/src/view/renderer.ts b/src/view/renderer.ts index bd0e74592..36b380e8a 100644 --- a/src/view/renderer.ts +++ b/src/view/renderer.ts @@ -1,29 +1,29 @@ -import { ID } from '../constants/index.js'; import { $, $$ } from '../utils.js'; +import { SELECTOR } from '../constants/index.js'; import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; const renderInputSection = (): void => { - ($(ID.APP_DIV) as HTMLDivElement).innerHTML = inputSection(); + ($(SELECTOR.APP_DIV) as HTMLDivElement).innerHTML = inputSection(); }; const renderProgressSection = (carNameArray: Array): void => { - ($(ID.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); + ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - ($(ID.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); + ($(SELECTOR.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - ($$(ID.CAR_RACE_TRACK_DIVS) as NodeListOf).forEach((element) => { + ($$(SELECTOR.CAR_RACE_TRACK_DIVS) as NodeListOf).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex: number): void => { - ($$(ID.CARNAME_DIVS) as NodeListOf).forEach((element, index) => { + ($$(SELECTOR.CARNAME_DIVS) as NodeListOf).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const renderResultSection = (winners: string): void => { - ($(ID.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); + ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; diff --git a/src/view/templates/result-section.ts b/src/view/templates/result-section.ts index f8992884b..16e923e1a 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/templates/result-section.ts @@ -4,7 +4,7 @@ const resultSection = (winners: string): string => {

πŸ† μ΅œμ’… 우승자: ${winners} πŸ†

- +
From 9a362f0e1e33ed9e034bdd2923bc503cef98db1f Mon Sep 17 00:00:00 2001 From: jwon42 Date: Tue, 8 Jun 2021 23:13:06 +0900 Subject: [PATCH 64/70] feat: delete elements.js --- dist/constants/elements.js | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 dist/constants/elements.js diff --git a/dist/constants/elements.js b/dist/constants/elements.js deleted file mode 100644 index 703ddc32c..000000000 --- a/dist/constants/elements.js +++ /dev/null @@ -1,19 +0,0 @@ -const ID = { - APP_DIV: '#app', - // input-section - INPUT_SECTION: '#input-section', - CARNAME_INPUT: '#car-names-input', - CARNAME_SUBMIT: '#car-names-submit', - TRYCOUNT_INPUT: '#racing-count-input', - TRYCOUNT_SUBMIT: '#racing-count-submit', - // progress-section - PROGRESS_SECTION: '#progress-section', - CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', - CARNAMES_DIV: '#progress-section .mt-4', - CARNAME_DIVS: '#progress-section .car-player', - SPINNER_DIVS: '#progress-section .mt-3', - // result-section - RESULT_SECTION: '#result-section', - RESTART_SUBMIT: '#restart-button', -}; -export { ID }; From bc933f08526056ddc408701608d4df88d55b751f Mon Sep 17 00:00:00 2001 From: jwon42 Date: Wed, 16 Jun 2021 16:25:17 +0900 Subject: [PATCH 65/70] refactor: for mvc --- cypress/fixtures/example.json | 5 ++ cypress/integration/racingcar.spec.js | 34 ++++----- cypress/support/commands.js | 25 +++++++ cypress/support/index.js | 20 +++++ dist/constants.js | 49 ++++++++++++ dist/constants/alert.js | 12 --- dist/constants/delay.js | 5 -- dist/constants/index.js | 4 - dist/constants/rule.js | 6 -- dist/constants/selector.js | 19 ----- dist/controller/event.js | 13 ---- dist/controller/game.js | 46 ------------ dist/controller/gameController.js | 36 +++++++++ dist/controller/inputController.js | 40 ++++++++++ dist/controller/linstener.js | 45 ----------- dist/controller/restartController.js | 15 ++++ dist/controller/validtor.js | 62 --------------- dist/index.js | 6 +- dist/model/InputData.js | 74 ++++++++++++++++++ dist/model/game.js | 42 ++++++++--- dist/model/index.js | 2 - dist/utils.js | 18 +---- ...put-section.js => inputSectionRenderer.js} | 7 +- dist/view/progressSectionRenderer.js | 51 +++++++++++++ dist/view/remover.js | 18 ----- dist/view/renderer.js | 24 ------ ...lt-section.js => resultSectionRenderer.js} | 7 +- dist/view/templates/index.js | 3 - dist/view/templates/progress-section.js | 30 -------- dist/view/utils.js | 27 +++++++ package.json | 2 +- src/constants.ts | 60 +++++++++++++++ src/constants/alert.ts | 15 ---- src/constants/delay.ts | 6 -- src/constants/index.ts | 4 - src/constants/rule.ts | 7 -- src/constants/selector.ts | 23 ------ src/controller/event.ts | 14 ---- src/controller/game.ts | 45 ----------- src/controller/gameController.ts | 32 ++++++++ src/controller/inputController.ts | 46 ++++++++++++ src/controller/linstener.ts | 60 --------------- src/controller/restartController.ts | 17 +++++ src/controller/validtor.ts | 64 ---------------- src/index.ts | 6 +- src/model/InputData.ts | 75 +++++++++++++++++++ src/model/game.ts | 34 ++++++--- src/model/index.ts | 2 - src/utils.ts | 32 +------- ...put-section.ts => inputSectionRenderer.ts} | 9 ++- src/view/progressSectionRenderer.ts | 59 +++++++++++++++ src/view/remover.ts | 21 ------ src/view/renderer.ts | 29 ------- ...lt-section.ts => resultSectionRenderer.ts} | 9 ++- src/view/templates/index.ts | 3 - src/view/templates/progress-section.ts | 34 --------- src/view/utils.ts | 33 ++++++++ 57 files changed, 772 insertions(+), 714 deletions(-) create mode 100644 cypress/fixtures/example.json create mode 100644 cypress/support/commands.js create mode 100644 cypress/support/index.js create mode 100644 dist/constants.js delete mode 100644 dist/constants/alert.js delete mode 100644 dist/constants/delay.js delete mode 100644 dist/constants/index.js delete mode 100644 dist/constants/rule.js delete mode 100644 dist/constants/selector.js delete mode 100644 dist/controller/event.js delete mode 100644 dist/controller/game.js create mode 100644 dist/controller/gameController.js create mode 100644 dist/controller/inputController.js delete mode 100644 dist/controller/linstener.js create mode 100644 dist/controller/restartController.js delete mode 100644 dist/controller/validtor.js create mode 100644 dist/model/InputData.js delete mode 100644 dist/model/index.js rename dist/view/{templates/input-section.js => inputSectionRenderer.js} (83%) create mode 100644 dist/view/progressSectionRenderer.js delete mode 100644 dist/view/remover.js delete mode 100644 dist/view/renderer.js rename dist/view/{templates/result-section.js => resultSectionRenderer.js} (61%) delete mode 100644 dist/view/templates/index.js delete mode 100644 dist/view/templates/progress-section.js create mode 100644 dist/view/utils.js create mode 100644 src/constants.ts delete mode 100644 src/constants/alert.ts delete mode 100644 src/constants/delay.ts delete mode 100644 src/constants/index.ts delete mode 100644 src/constants/rule.ts delete mode 100644 src/constants/selector.ts delete mode 100644 src/controller/event.ts delete mode 100644 src/controller/game.ts create mode 100644 src/controller/gameController.ts create mode 100644 src/controller/inputController.ts delete mode 100644 src/controller/linstener.ts create mode 100644 src/controller/restartController.ts delete mode 100644 src/controller/validtor.ts create mode 100644 src/model/InputData.ts delete mode 100644 src/model/index.ts rename src/view/{templates/input-section.ts => inputSectionRenderer.ts} (82%) create mode 100644 src/view/progressSectionRenderer.ts delete mode 100644 src/view/remover.ts delete mode 100644 src/view/renderer.ts rename src/view/{templates/result-section.ts => resultSectionRenderer.ts} (59%) delete mode 100644 src/view/templates/index.ts delete mode 100644 src/view/templates/progress-section.ts create mode 100644 src/view/utils.ts diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 000000000..02e425437 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/integration/racingcar.spec.js b/cypress/integration/racingcar.spec.js index 5a119a654..cf02ec81f 100644 --- a/cypress/integration/racingcar.spec.js +++ b/cypress/integration/racingcar.spec.js @@ -1,20 +1,20 @@ -import { ID, ALERT, DELAY } from '../../dist/constants/index.js'; +import { SELECTOR, ALERT, DELAY } from '../../dist/constants.js'; let carNamesSample = 'jwon, yeji, holee, yshin'; let tryCountSample = 3; const carNameInputAndSubmit = (carNames) => { if (carNames) { - cy.get(ID.CARNAME_INPUT).type(carNames); + cy.get(SELECTOR.CARNAME_INPUT).type(carNames); } - cy.get(ID.CARNAME_SUBMIT).click(); + cy.get(SELECTOR.CARNAME_SUBMIT).click(); }; const tryCountInputAndSubmit = (tryCount) => { if (tryCount) { - cy.get(ID.TRYCOUNT_INPUT).type(tryCount); + cy.get(SELECTOR.TRYCOUNT_INPUT).type(tryCount); } - cy.get(ID.TRYCOUNT_SUBMIT).click(); + cy.get(SELECTOR.TRYCOUNT_SUBMIT).click(); }; const catchAlertMessage = (alertMessage) => { @@ -29,9 +29,9 @@ describe('0. μ΄ˆκΈ°ν™”λ©΄ λ‘œλ”© ν…ŒμŠ€νŠΈ', () => { }); it('μžλ™μ°¨ κ²½μ£Ό κ²Œμž„μ„ μ‹€ν–‰ν•˜λ©΄, 인풋 μ„Ήμ…˜μ΄ 보이고 μžλ™μ°¨ μž…λ ₯창이 ν™œμ„±ν™”λœλ‹€.=', () => { - cy.get(ID.INPUT_SECTION).should('be.visible'); - cy.get(ID.CARNAME_INPUT).should('not.be.disabled'); - cy.get(ID.CARNAME_SUBMIT).should('not.be.disabled'); + cy.get(SELECTOR.INPUT_SECTION).should('be.visible'); + cy.get(SELECTOR.CARNAME_INPUT).should('not.be.disabled'); + cy.get(SELECTOR.CARNAME_SUBMIT).should('not.be.disabled'); }); }); @@ -67,16 +67,16 @@ describe('1. μžλ™μ°¨ 이름 μž…λ ₯ ν…ŒμŠ€νŠΈ', () => { it('μžλ™μ°¨ 이름을 μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, μžλ™μ°¨ 이름 μž…λ ₯μΉΈκ³Ό 클릭 λ²„νŠΌμ„ λΉ„ν™œμ„±ν™” ν•˜κ³  μ‹œλ„ 횟수 μž…λ ₯μΉΈκ³Ό μ‹œλ„ 횟수 λ²„νŠΌμ„ ν™œμ„±ν™”ν•œλ‹€', () => { carNameInputAndSubmit(carNamesSample); - cy.get(ID.CARNAME_INPUT).should('be.disabled'); - cy.get(ID.CARNAME_SUBMIT).should('be.disabled'); - cy.get(ID.TRYCOUNT_INPUT).should('not.be.disabled'); - cy.get(ID.TRYCOUNT_SUBMIT).should('not.be.disabled'); + cy.get(SELECTOR.CARNAME_INPUT).should('be.disabled'); + cy.get(SELECTOR.CARNAME_SUBMIT).should('be.disabled'); + cy.get(SELECTOR.TRYCOUNT_INPUT).should('not.be.disabled'); + cy.get(SELECTOR.TRYCOUNT_SUBMIT).should('not.be.disabled'); }); it('μžλ™μ°¨ 이름을 μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 진행상황 μ„Ήμ…˜μ΄ λ‘œλ”©λœλ‹€. ', () => { carNameInputAndSubmit(carNamesSample); tryCountInputAndSubmit(tryCountSample); - cy.get(ID.PROGRESS_SECTION).should('be.visible'); + cy.get(SELECTOR.PROGRESS_SECTION).should('be.visible'); }); }); @@ -131,9 +131,9 @@ describe('4. κ²Œμž„ μž¬μ‹œμž‘ ν…ŒμŠ€νŠΈ', () => { carNameInputAndSubmit(carNamesSample); tryCountInputAndSubmit(tryCountSample); cy.wait(tryCountSample * DELAY.TURN + DELAY.END); - cy.get(ID.RESTART_SUBMIT).click(); - cy.get(ID.PROGRESS_SECTION).should('not.exist'); - cy.get(ID.RESULT_SECTION).should('not.exist'); - cy.get(ID.CARNAME_INPUT).should('have.value', ''); + cy.get(SELECTOR.RESTART_SUBMIT).click(); + cy.get(SELECTOR.PROGRESS_SECTION).should('not.exist'); + cy.get(SELECTOR.RESULT_SECTION).should('not.exist'); + cy.get(SELECTOR.CARNAME_INPUT).should('have.value', ''); }); }); diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 000000000..119ab03f7 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 000000000..d68db96df --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') diff --git a/dist/constants.js b/dist/constants.js new file mode 100644 index 000000000..59415bd98 --- /dev/null +++ b/dist/constants.js @@ -0,0 +1,49 @@ +const DELAY = { + // millisecond(s) + GAME_TURN: 1000, + GAME_END: 2000, +}; +const RULE = { + // random(0~9) 값이 4 이상일 경우 전진, 3 μ΄ν•˜μ˜ 값이면 μ „μ§„ν•˜μ§€ μ•ŠμŒ + MIN_SCORE: 0, + MAX_SCORE: 9, + THRESHOULD_SCORE: 4, + // μžλ™μ°¨ 이름은 5자 μ΄ν•˜λ§Œ κ°€λŠ₯ + MAX_CARNAME_LENGTH: 5, + // μ‹œλ„ νšŸμˆ˜λŠ” μ›ν™œν•œ κ²Œμž„μ„ μœ„ν•΄ 자체적으둜 μ œν•œ + MIN_TRY_COUNT: 1, + MAX_TRY_COUNT: 50, +}; +const SELECTOR = { + APP_DIV: '#app', + // input-section + INPUT_SECTION: '#input-section', + CARNAME_INPUT: '#car-names-input', + CARNAME_SUBMIT_BUTTON: '#car-names-submit', + TRYCOUNT_INPUT: '#racing-count-input', + TRYCOUNT_SUBMIT_BUTTON: '#racing-count-submit', + // progress-section + PROGRESS_SECTION: '#progress-section', + CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', + CARNAMES_DIV: '#progress-section .mt-4', + CARNAME_DIVS: '#progress-section .car-player', + SPINNER_DIVS: '#progress-section .mt-3', + // result-section + RESULT_SECTION: '#result-section', + RESTART_SUBMIT_BUTTON: '#restart-button', +}; +const ALERT = { + // for check valid car name + CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_EMPTY: 'λΉ„μ–΄ μžˆλŠ” μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', + // for check valid try count + TRYCOUNT_NOTHING: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”', + TRYCOUNT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (50 μ΄ν•˜)', + TRYCOUNT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (50 μ΄ν•˜)', + // etc. + CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', +}; +export { DELAY, RULE, SELECTOR, ALERT }; diff --git a/dist/constants/alert.js b/dist/constants/alert.js deleted file mode 100644 index e888e94e6..000000000 --- a/dist/constants/alert.js +++ /dev/null @@ -1,12 +0,0 @@ -const ALERT = { - CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', - CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', - CARNAME_EMPTY: 'λΉ„μ–΄ μžˆλŠ” μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', - CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', - CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', - TRYCOUNT_NOTHING: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”', - TRYCOUNT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (50 μ΄ν•˜)', - TRYCOUNT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (50 μ΄ν•˜)', - CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', -}; -export { ALERT }; diff --git a/dist/constants/delay.js b/dist/constants/delay.js deleted file mode 100644 index d1725dec1..000000000 --- a/dist/constants/delay.js +++ /dev/null @@ -1,5 +0,0 @@ -const DELAY = { - TURN: 1000, - END: 2000, -}; -export { DELAY }; diff --git a/dist/constants/index.js b/dist/constants/index.js deleted file mode 100644 index a3f677f02..000000000 --- a/dist/constants/index.js +++ /dev/null @@ -1,4 +0,0 @@ -export { SELECTOR } from './selector.js'; -export { ALERT } from './alert.js'; -export { RULE } from './rule.js'; -export { DELAY } from './delay.js'; diff --git a/dist/constants/rule.js b/dist/constants/rule.js deleted file mode 100644 index ea9197932..000000000 --- a/dist/constants/rule.js +++ /dev/null @@ -1,6 +0,0 @@ -const RULE = { - MIN_SCORE: 0, - MAX_SCORE: 9, - THRESHOULD_SCORE: 4, -}; -export { RULE }; diff --git a/dist/constants/selector.js b/dist/constants/selector.js deleted file mode 100644 index 8e30a9fa5..000000000 --- a/dist/constants/selector.js +++ /dev/null @@ -1,19 +0,0 @@ -const SELECTOR = { - APP_DIV: '#app', - // input-section - INPUT_SECTION: '#input-section', - CARNAME_INPUT: '#car-names-input', - CARNAME_SUBMIT: '#car-names-submit', - TRYCOUNT_INPUT: '#racing-count-input', - TRYCOUNT_SUBMIT: '#racing-count-submit', - // progress-section - PROGRESS_SECTION: '#progress-section', - CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', - CARNAMES_DIV: '#progress-section .mt-4', - CARNAME_DIVS: '#progress-section .car-player', - SPINNER_DIVS: '#progress-section .mt-3', - // result-section - RESULT_SECTION: '#result-section', - RESTART_SUBMIT: '#restart-button', -}; -export { SELECTOR }; diff --git a/dist/controller/event.js b/dist/controller/event.js deleted file mode 100644 index f74f67713..000000000 --- a/dist/controller/event.js +++ /dev/null @@ -1,13 +0,0 @@ -import { $ } from '../utils.js'; -import { SELECTOR } from '../constants/index.js'; -import { getCarNames, getTryCount, restartApp } from './linstener.js'; -const setInputButtonsEvent = () => { - var _a, _b; - (_a = $(SELECTOR.CARNAME_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames()); - (_b = $(SELECTOR.TRYCOUNT_SUBMIT)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount()); -}; -const setRestartButtonEvent = () => { - var _a; - (_a = $(SELECTOR.RESTART_SUBMIT)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => restartApp()); -}; -export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/dist/controller/game.js b/dist/controller/game.js deleted file mode 100644 index 570bff56b..000000000 --- a/dist/controller/game.js +++ /dev/null @@ -1,46 +0,0 @@ -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -import { ALERT, DELAY, SELECTOR } from '../constants/index.js'; -import { $, buttonElementEnable } from '../utils.js'; -import { Car, Game } from '../model/index.js'; -import { removeSpinners } from '../view/remover.js'; -import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRestartButtonEvent } from './event.js'; -const makeDelay = (ms) => __awaiter(void 0, void 0, void 0, function* () { - return new Promise((r) => setTimeout(r, ms)); -}); -const createCarsObject = (carNameArray) => { - const cars = []; - carNameArray.forEach((car, index) => { - cars.push(new Car(car, index)); - }); - return cars; -}; -const playOnce = (racingGame) => { - racingGame.play(); - racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - renderArrowDiv(roundWinnerIndex); - }); - racingGame.initRoundWinnersIndex(); -}; -const startGame = (carNameArray, tryCount) => __awaiter(void 0, void 0, void 0, function* () { - const racingGame = new Game(createCarsObject(carNameArray)); - let racingWinners = []; - for (let index = 0; index < tryCount; index += 1) { - yield makeDelay(DELAY.TURN).then(() => playOnce(racingGame)); - } - removeSpinners(); - racingWinners = racingGame.getWinners(); - renderResultSection(racingWinners.join(', ').toLowerCase()); - yield makeDelay(DELAY.END).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - buttonElementEnable($(SELECTOR.RESTART_SUBMIT)); - setRestartButtonEvent(); -}); -export { startGame }; diff --git a/dist/controller/gameController.js b/dist/controller/gameController.js new file mode 100644 index 000000000..8a54bf459 --- /dev/null +++ b/dist/controller/gameController.js @@ -0,0 +1,36 @@ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { ALERT, DELAY, SELECTOR } from '../constants.js'; +import { $ } from '../utils.js'; +import { Game } from '../model/Game.js'; +import { enableButton } from '../view/utils.js'; +import { renderArrowDiv, removeSpinnerDivs } from '../view/progressSectionRenderer.js'; +import { renderResultSection } from '../view/resultSectionRenderer.js'; +import { addRestartButtonEvent } from './restartController.js'; +const playOnce = (racingGame) => { + racingGame.play(); + racingGame.roundWinners.forEach((index) => { + renderArrowDiv(index); + }); + racingGame.initRoundWinners(); +}; +const startGame = (inputData) => __awaiter(void 0, void 0, void 0, function* () { + const racingGame = new Game(inputData.carNameArray); + for (let index = 0; index < inputData.tryCount; index += 1) { + yield racingGame.makeDelay(DELAY.GAME_TURN).then(() => playOnce(racingGame)); + } + racingGame.judgeFinalWinners(); + removeSpinnerDivs(); + renderResultSection(racingGame.finalWinners.join(', ').toLowerCase()); + yield racingGame.makeDelay(DELAY.GAME_END).then(() => alert(racingGame.finalWinners.join(', ') + ALERT.CONGRATULATION)); + enableButton($(SELECTOR.RESTART_SUBMIT_BUTTON)); + addRestartButtonEvent(); +}); +export { startGame }; diff --git a/dist/controller/inputController.js b/dist/controller/inputController.js new file mode 100644 index 000000000..ba6fd0a45 --- /dev/null +++ b/dist/controller/inputController.js @@ -0,0 +1,40 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; +import { startGame } from './gameController.js'; +import { InputData } from '../model/InputData.js'; +import { renderProgressSection } from '../view/progressSectionRenderer.js'; +import { clearInput, enableInput, disableInput, enableButton, disableButton } from '../view/utils.js'; +const getCarNames = (inputData) => { + const carNameInput = $(SELECTOR.CARNAME_INPUT); + const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); + if (inputData.checkCarNames(carNameInput, carNameArray)) { + renderProgressSection(carNameArray); + inputData.carNameArray = carNameArray; + disableInput(carNameInput); + disableButton($(SELECTOR.CARNAME_SUBMIT_BUTTON)); + enableInput($(SELECTOR.TRYCOUNT_INPUT)); + enableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)); + $(SELECTOR.TRYCOUNT_INPUT).focus(); + return; + } + clearInput(carNameInput); +}; +const getTryCount = (inputData) => { + const tryCountInput = $(SELECTOR.TRYCOUNT_INPUT); + const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); + if (inputData.checkTryCount(tryCountInput)) { + inputData.tryCount = tryCount; + disableInput(tryCountInput); + disableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)); + startGame(inputData); + return; + } + clearInput(tryCountInput); +}; +const addInputButtonsEvent = () => { + var _a, _b; + const inputData = new InputData(); + (_a = $(SELECTOR.CARNAME_SUBMIT_BUTTON)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames(inputData)); + (_b = $(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount(inputData)); +}; +export { addInputButtonsEvent }; diff --git a/dist/controller/linstener.js b/dist/controller/linstener.js deleted file mode 100644 index 658f34bb2..000000000 --- a/dist/controller/linstener.js +++ /dev/null @@ -1,45 +0,0 @@ -import { SELECTOR } from '../constants/index.js'; -import { startGame } from './game.js'; -import { renderProgressSection, renderInputSection } from '../view/renderer.js'; -import { setInputButtonsEvent } from './event.js'; -import { checkCarNames, checkTryCount } from './validtor.js'; -import { removeChildNodes } from '../view/remover.js'; -import { $, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable, } from '../utils.js'; -const getCarNames = () => { - const carNameInput = $(SELECTOR.CARNAME_INPUT); - const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton = $(SELECTOR.CARNAME_SUBMIT); - const tryCountInput = $(SELECTOR.TRYCOUNT_INPUT); - const tryCountSubmitButton = $(SELECTOR.TRYCOUNT_SUBMIT); - inputElementDisable(carNameInput); - buttonElementDisable(carNameSubmitButton); - inputElementEnable(tryCountInput); - buttonElementEnable(tryCountSubmitButton); - renderProgressSection(carNameArray); - tryCountInput.focus(); - return; - } - inputElementClear(carNameInput); -}; -const getTryCount = () => { - const tryCountInput = $(SELECTOR.TRYCOUNT_INPUT); - const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); - if (checkTryCount(tryCountInput)) { - const carNameInput = $(SELECTOR.CARNAME_INPUT); - const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); - const tryCountSubmitButton = $(SELECTOR.TRYCOUNT_SUBMIT); - inputElementDisable(tryCountInput); - buttonElementDisable(tryCountSubmitButton); - startGame(carNameArray, tryCount); - return; - } - inputElementClear(tryCountInput); -}; -const restartApp = () => { - removeChildNodes($(SELECTOR.APP_DIV)); - renderInputSection(); - setInputButtonsEvent(); - $(SELECTOR.CARNAME_INPUT).focus(); -}; -export { getCarNames, getTryCount, restartApp }; diff --git a/dist/controller/restartController.js b/dist/controller/restartController.js new file mode 100644 index 000000000..0e57f6224 --- /dev/null +++ b/dist/controller/restartController.js @@ -0,0 +1,15 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; +import { removeChildNodes } from '../view/utils.js'; +import { renderInputSection } from '../view/inputSectionRenderer.js'; +const init = () => { + removeChildNodes($(SELECTOR.APP_DIV)); + renderInputSection(); + addRestartButtonEvent(); + $(SELECTOR.CARNAME_INPUT).focus(); +}; +const addRestartButtonEvent = () => { + var _a; + (_a = $(SELECTOR.RESTART_SUBMIT_BUTTON)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => init()); +}; +export { addRestartButtonEvent }; diff --git a/dist/controller/validtor.js b/dist/controller/validtor.js deleted file mode 100644 index b2798e259..000000000 --- a/dist/controller/validtor.js +++ /dev/null @@ -1,62 +0,0 @@ -import { ALERT } from '../constants/index.js'; -const checkEmptyInput = (input) => { - return input.value.trim() === ''; -}; -const checkArrayHasEmptyElement = (array) => { - return array.some((x) => x === ''); -}; -const checkArrayHasOneElement = (array) => { - return array.length < 2; -}; -const checkArrayDupElements = (array) => { - return array.some((x) => { - return array.indexOf(x) !== array.lastIndexOf(x); - }); -}; -const checkArrayElementsLength = (array) => { - for (let index = 0; index < array.length; index += 1) { - if (array[index].length > 5) { - return true; - } - } - return false; -}; -const checkCarNames = (carNameInput, carNameArray) => { - if (checkEmptyInput(carNameInput)) { - alert(ALERT.CARNAME_NOTHING); - return false; - } - else if (checkArrayHasOneElement(carNameArray)) { - alert(ALERT.CARNAME_ALONE); - return false; - } - else if (checkArrayHasEmptyElement(carNameArray)) { - alert(ALERT.CARNAME_EMPTY); - return false; - } - else if (checkArrayDupElements(carNameArray)) { - alert(ALERT.CARNAME_DOUBLE); - return false; - } - else if (checkArrayElementsLength(carNameArray)) { - alert(ALERT.CARNAME_LENGTH); - return false; - } - return true; -}; -const checkTryCount = (tryCountInput) => { - if (checkEmptyInput(tryCountInput)) { - alert(ALERT.TRYCOUNT_NOTHING); - return false; - } - else if (Number(tryCountInput.value) < 1) { - alert(ALERT.TRYCOUNT_UINT); - return false; - } - else if (Number(tryCountInput.value) > 50) { - alert(ALERT.TRYCOUNT_TOO_BIG); - return false; - } - return true; -}; -export { checkCarNames, checkTryCount }; diff --git a/dist/index.js b/dist/index.js index 0d4d0962d..c8bceb728 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,7 +1,7 @@ -import { renderInputSection } from './view/renderer.js'; -import { setInputButtonsEvent } from './controller/event.js'; +import { renderInputSection } from './view/inputSectionRenderer.js'; +import { addInputButtonsEvent } from './controller/inputController.js'; const app = () => { renderInputSection(); - setInputButtonsEvent(); + addInputButtonsEvent(); }; app(); diff --git a/dist/model/InputData.js b/dist/model/InputData.js new file mode 100644 index 000000000..7c1e426ce --- /dev/null +++ b/dist/model/InputData.js @@ -0,0 +1,74 @@ +import { RULE, ALERT } from '../constants.js'; +class InputData { + constructor() { + this.carNameArray = []; + this.tryCount = 0; + } + checkEmptyInput(input) { + return input.value.trim() === ''; + } + ; + checkArrayHasEmptyElement(array) { + return array.some((x) => x === ''); + } + checkArrayHasOneElement(array) { + return array.length < 2; + } + ; + checkArrayDupElements(array) { + return array.some((x) => { + return array.indexOf(x) !== array.lastIndexOf(x); + }); + } + ; + checkArrayElementsLength(array) { + for (let index = 0; index < array.length; index += 1) { + if (array[index].length > RULE.MAX_CARNAME_LENGTH) { + return true; + } + } + return false; + } + ; + checkCarNames(carNameInput, carNameArray) { + if (this.checkEmptyInput(carNameInput)) { + alert(ALERT.CARNAME_NOTHING); + return false; + } + else if (this.checkArrayHasOneElement(carNameArray)) { + alert(ALERT.CARNAME_ALONE); + return false; + } + else if (this.checkArrayHasEmptyElement(carNameArray)) { + alert(ALERT.CARNAME_EMPTY); + return false; + } + else if (this.checkArrayDupElements(carNameArray)) { + alert(ALERT.CARNAME_DOUBLE); + return false; + } + else if (this.checkArrayElementsLength(carNameArray)) { + alert(ALERT.CARNAME_LENGTH); + return false; + } + return true; + } + ; + checkTryCount(tryCountInput) { + if (this.checkEmptyInput(tryCountInput)) { + alert(ALERT.TRYCOUNT_NOTHING); + return false; + } + else if (Number(tryCountInput.value) < RULE.MIN_TRY_COUNT) { + alert(ALERT.TRYCOUNT_UINT); + return false; + } + else if (Number(tryCountInput.value) > RULE.MAX_TRY_COUNT) { + alert(ALERT.TRYCOUNT_TOO_BIG); + return false; + } + return true; + } + ; +} +export { InputData }; diff --git a/dist/model/game.js b/dist/model/game.js index 642e31b20..cff8bc76c 100644 --- a/dist/model/game.js +++ b/dist/model/game.js @@ -1,20 +1,43 @@ -import { RULE } from '../constants/index.js'; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import { Car } from './Car.js'; +import { RULE } from '../constants.js'; class Game { - constructor(cars) { - this.cars = cars; + constructor(carNameArray) { + this.cars = []; this.finalWinners = []; - this.roundWinnersIndex = []; + this.roundWinners = []; this.maxPosition = 0; + this.setCarsObject(carNameArray); } play() { this.cars.forEach((car) => { if (Math.floor(Math.random() * RULE.MAX_SCORE) + RULE.MIN_SCORE >= RULE.THRESHOULD_SCORE) { car.moveForward(); - this.roundWinnersIndex.push(car.index); - this.updateMaxPosition(); + this.roundWinners.push(car.index); } }); + this.updateMaxPosition(); } + setCarsObject(carNameArray) { + carNameArray.forEach((car, index) => { + this.cars.push(new Car(car, index)); + }); + } + ; + makeDelay(ms) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((r) => setTimeout(r, ms)); + }); + } + ; updateMaxPosition() { this.cars.forEach((car) => { if (car.position > this.maxPosition) { @@ -22,16 +45,15 @@ class Game { } }); } - initRoundWinnersIndex() { - this.roundWinnersIndex = []; + initRoundWinners() { + this.roundWinners = []; } - getWinners() { + judgeFinalWinners() { this.cars.forEach((car) => { if (car.position === this.maxPosition) { this.finalWinners.push(car.name); } }); - return this.finalWinners; } } export { Game }; diff --git a/dist/model/index.js b/dist/model/index.js deleted file mode 100644 index 313573f01..000000000 --- a/dist/model/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { Car } from './car.js'; -export { Game } from './game.js'; diff --git a/dist/utils.js b/dist/utils.js index 625922527..bfea08cd6 100644 --- a/dist/utils.js +++ b/dist/utils.js @@ -1,19 +1,3 @@ const $ = (selector) => document.querySelector(selector); const $$ = (selector) => document.querySelectorAll(selector); -const inputElementClear = (element) => { - element.value = ''; - element.focus(); -}; -const inputElementEnable = (element) => { - element.disabled = false; -}; -const inputElementDisable = (element) => { - element.disabled = true; -}; -const buttonElementEnable = (element) => { - element.disabled = false; -}; -const buttonElementDisable = (element) => { - element.disabled = true; -}; -export { $, $$, inputElementClear, inputElementEnable, inputElementDisable, buttonElementEnable, buttonElementDisable }; +export { $, $$ }; diff --git a/dist/view/templates/input-section.js b/dist/view/inputSectionRenderer.js similarity index 83% rename from dist/view/templates/input-section.js rename to dist/view/inputSectionRenderer.js index b071372fd..0bdbdeec8 100644 --- a/dist/view/templates/input-section.js +++ b/dist/view/inputSectionRenderer.js @@ -1,3 +1,5 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; const inputSection = () => { return `
@@ -24,4 +26,7 @@ const inputSection = () => {
`; }; -export { inputSection }; +const renderInputSection = () => { + $(SELECTOR.APP_DIV).innerHTML = inputSection(); +}; +export { renderInputSection }; diff --git a/dist/view/progressSectionRenderer.js b/dist/view/progressSectionRenderer.js new file mode 100644 index 000000000..084c9ec95 --- /dev/null +++ b/dist/view/progressSectionRenderer.js @@ -0,0 +1,51 @@ +import { $, $$ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; +const progressSection = () => { + return ` +
+
+
+
+ `; +}; +const carNameDiv = (carName) => { + return ` +
+
${carName}
+
+ `; +}; +const spinnerDiv = () => { + return ` +
+
+ +
+
+ `; +}; +const arrowDiv = () => { + return ` +
⬇️️
+ `; +}; +const renderProgressSection = (carNameArray) => { + $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', progressSection()); + carNameArray.forEach((carName) => { + $(SELECTOR.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); + }); + $$(SELECTOR.CAR_RACE_TRACK_DIVS).forEach((element) => { + element.insertAdjacentHTML(`beforeend`, spinnerDiv()); + }); +}; +const renderArrowDiv = (roundWinnerIndex) => { + $$(SELECTOR.CARNAME_DIVS).forEach((element, index) => { + index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; + }); +}; +const removeSpinnerDivs = () => { + $$(SELECTOR.SPINNER_DIVS).forEach((element) => { + element.remove(); + }); +}; +export { renderProgressSection, renderArrowDiv, removeSpinnerDivs }; diff --git a/dist/view/remover.js b/dist/view/remover.js deleted file mode 100644 index 05320964c..000000000 --- a/dist/view/remover.js +++ /dev/null @@ -1,18 +0,0 @@ -import { $$ } from '../utils.js'; -import { SELECTOR } from '../constants/selector.js'; -const removeSpinners = () => { - $$(SELECTOR.SPINNER_DIVS).forEach((element) => { - element.remove(); - }); -}; -const removeChildNodes = (element) => { - if (!element) { - return; - } - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } - } -}; -export { removeSpinners, removeChildNodes }; diff --git a/dist/view/renderer.js b/dist/view/renderer.js deleted file mode 100644 index 85046e459..000000000 --- a/dist/view/renderer.js +++ /dev/null @@ -1,24 +0,0 @@ -import { $, $$ } from '../utils.js'; -import { SELECTOR } from '../constants/index.js'; -import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; -const renderInputSection = () => { - $(SELECTOR.APP_DIV).innerHTML = inputSection(); -}; -const renderProgressSection = (carNameArray) => { - $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', progressSection()); - carNameArray.forEach((carName) => { - $(SELECTOR.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); - }); - $$(SELECTOR.CAR_RACE_TRACK_DIVS).forEach((element) => { - element.insertAdjacentHTML(`beforeend`, spinnerDiv()); - }); -}; -const renderArrowDiv = (roundWinnerIndex) => { - $$(SELECTOR.CARNAME_DIVS).forEach((element, index) => { - index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; - }); -}; -const renderResultSection = (winners) => { - $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', resultSection(winners)); -}; -export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; diff --git a/dist/view/templates/result-section.js b/dist/view/resultSectionRenderer.js similarity index 61% rename from dist/view/templates/result-section.js rename to dist/view/resultSectionRenderer.js index 7e07a6190..d6f1737c4 100644 --- a/dist/view/templates/result-section.js +++ b/dist/view/resultSectionRenderer.js @@ -1,3 +1,5 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; const resultSection = (winners) => { return `
@@ -10,4 +12,7 @@ const resultSection = (winners) => {
`; }; -export { resultSection }; +const renderResultSection = (winners) => { + $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', resultSection(winners)); +}; +export { renderResultSection }; diff --git a/dist/view/templates/index.js b/dist/view/templates/index.js deleted file mode 100644 index bbce73e91..000000000 --- a/dist/view/templates/index.js +++ /dev/null @@ -1,3 +0,0 @@ -export { inputSection } from './input-section.js'; -export { progressSection, carNameDiv, spinnerDiv, arrowDiv } from './progress-section.js'; -export { resultSection } from './result-section.js'; diff --git a/dist/view/templates/progress-section.js b/dist/view/templates/progress-section.js deleted file mode 100644 index 355284e6c..000000000 --- a/dist/view/templates/progress-section.js +++ /dev/null @@ -1,30 +0,0 @@ -const progressSection = () => { - return ` -
-
-
-
- `; -}; -const carNameDiv = (carName) => { - return ` -
-
${carName}
-
- `; -}; -const spinnerDiv = () => { - return ` -
-
- -
-
- `; -}; -const arrowDiv = () => { - return ` -
⬇️️
- `; -}; -export { progressSection, carNameDiv, spinnerDiv, arrowDiv }; diff --git a/dist/view/utils.js b/dist/view/utils.js new file mode 100644 index 000000000..4567fa02d --- /dev/null +++ b/dist/view/utils.js @@ -0,0 +1,27 @@ +const clearInput = (element) => { + element.value = ''; + element.focus(); +}; +const enableInput = (element) => { + element.disabled = false; +}; +const disableInput = (element) => { + element.disabled = true; +}; +const enableButton = (element) => { + element.disabled = false; +}; +const disableButton = (element) => { + element.disabled = true; +}; +const removeChildNodes = (element) => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } +}; +export { clearInput, enableInput, disableInput, enableButton, disableButton, removeChildNodes }; diff --git a/package.json b/package.json index c9ff4f41c..2180aecc3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "cypress": "^7.4.0", + "cypress": "^7.5.0", "typescript": "^4.3.2" }, "name": "javascript-racingcar", diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 000000000..ff0b036b0 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,60 @@ +const DELAY = { + // millisecond(s) + GAME_TURN: 1000, + GAME_END: 2000, +}; + +const RULE = { + // random(0~9) 값이 4 이상일 경우 전진, 3 μ΄ν•˜μ˜ 값이면 μ „μ§„ν•˜μ§€ μ•ŠμŒ + MIN_SCORE: 0, + MAX_SCORE: 9, + THRESHOULD_SCORE: 4, + + // μžλ™μ°¨ 이름은 5자 μ΄ν•˜λ§Œ κ°€λŠ₯ + MAX_CARNAME_LENGTH: 5, + + // μ‹œλ„ νšŸμˆ˜λŠ” μ›ν™œν•œ κ²Œμž„μ„ μœ„ν•΄ 자체적으둜 μ œν•œ + MIN_TRY_COUNT: 1, + MAX_TRY_COUNT: 50, +}; + +const SELECTOR = { + APP_DIV: '#app', + + // input-section + INPUT_SECTION: '#input-section', + CARNAME_INPUT: '#car-names-input', + CARNAME_SUBMIT_BUTTON: '#car-names-submit', + TRYCOUNT_INPUT: '#racing-count-input', + TRYCOUNT_SUBMIT_BUTTON: '#racing-count-submit', + + // progress-section + PROGRESS_SECTION: '#progress-section', + CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', + CARNAMES_DIV: '#progress-section .mt-4', + CARNAME_DIVS: '#progress-section .car-player', + SPINNER_DIVS: '#progress-section .mt-3', + + // result-section + RESULT_SECTION: '#result-section', + RESTART_SUBMIT_BUTTON: '#restart-button', +}; + +const ALERT = { + // for check valid car name + CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', + CARNAME_EMPTY: 'λΉ„μ–΄ μžˆλŠ” μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', + CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', + + // for check valid try count + TRYCOUNT_NOTHING: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”', + TRYCOUNT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (50 μ΄ν•˜)', + TRYCOUNT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (50 μ΄ν•˜)', + + // etc. + CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', +}; + +export { DELAY, RULE, SELECTOR, ALERT } \ No newline at end of file diff --git a/src/constants/alert.ts b/src/constants/alert.ts deleted file mode 100644 index 7283e5e21..000000000 --- a/src/constants/alert.ts +++ /dev/null @@ -1,15 +0,0 @@ -const ALERT = { - CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', - CARNAME_ALONE: 'μžλ™μ°¨ 이름을 2개 이상 μž…λ ₯ν•΄μ£Όμ„Έμš”', - CARNAME_EMPTY: 'λΉ„μ–΄ μžˆλŠ” μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', - CARNAME_DOUBLE: 'μ€‘λ³΅λœ μžλ™μ°¨ 이름이 μžˆμŠ΅λ‹ˆλ‹€', - CARNAME_LENGTH: 'μžλ™μ°¨ 이름 κΈ€μžμˆ˜κ°€ μ΄ˆκ³Όλ˜μ—ˆμŠ΅λ‹ˆλ‹€ (5자 이내)', - - TRYCOUNT_NOTHING: 'μ‹œλ„ 횟수λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”', - TRYCOUNT_UINT: 'μ‹œλ„ νšŸμˆ˜λŠ” μ–‘μ˜ μ •μˆ˜λ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš” (50 μ΄ν•˜)', - TRYCOUNT_TOO_BIG: 'μ‹œλ„ νšŸμˆ˜κ°€ λ„ˆλ¬΄ λ§ŽμŠ΅λ‹ˆλ‹€ (50 μ΄ν•˜)', - - CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', -}; - -export { ALERT }; diff --git a/src/constants/delay.ts b/src/constants/delay.ts deleted file mode 100644 index e0cf9b333..000000000 --- a/src/constants/delay.ts +++ /dev/null @@ -1,6 +0,0 @@ -const DELAY = { - TURN: 1000, - END: 2000, -}; - -export { DELAY }; diff --git a/src/constants/index.ts b/src/constants/index.ts deleted file mode 100644 index a3f677f02..000000000 --- a/src/constants/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { SELECTOR } from './selector.js'; -export { ALERT } from './alert.js'; -export { RULE } from './rule.js'; -export { DELAY } from './delay.js'; diff --git a/src/constants/rule.ts b/src/constants/rule.ts deleted file mode 100644 index cb50eaaee..000000000 --- a/src/constants/rule.ts +++ /dev/null @@ -1,7 +0,0 @@ -const RULE = { - MIN_SCORE: 0, - MAX_SCORE: 9, - THRESHOULD_SCORE: 4, -}; - -export { RULE }; diff --git a/src/constants/selector.ts b/src/constants/selector.ts deleted file mode 100644 index 0b69dfd47..000000000 --- a/src/constants/selector.ts +++ /dev/null @@ -1,23 +0,0 @@ -const SELECTOR = { - APP_DIV: '#app', - - // input-section - INPUT_SECTION: '#input-section', - CARNAME_INPUT: '#car-names-input', - CARNAME_SUBMIT: '#car-names-submit', - TRYCOUNT_INPUT: '#racing-count-input', - TRYCOUNT_SUBMIT: '#racing-count-submit', - - // progress-section - PROGRESS_SECTION: '#progress-section', - CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', - CARNAMES_DIV: '#progress-section .mt-4', - CARNAME_DIVS: '#progress-section .car-player', - SPINNER_DIVS: '#progress-section .mt-3', - - // result-section - RESULT_SECTION: '#result-section', - RESTART_SUBMIT: '#restart-button', -}; - -export { SELECTOR }; diff --git a/src/controller/event.ts b/src/controller/event.ts deleted file mode 100644 index 0f0c82622..000000000 --- a/src/controller/event.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { $ } from '../utils.js'; -import { SELECTOR } from '../constants/index.js'; -import { getCarNames, getTryCount, restartApp } from './linstener.js'; - -const setInputButtonsEvent = (): void => { - $(SELECTOR.CARNAME_SUBMIT)?.addEventListener('click', () => getCarNames()); - $(SELECTOR.TRYCOUNT_SUBMIT)?.addEventListener('click', () => getTryCount()); -}; - -const setRestartButtonEvent = (): void => { - $(SELECTOR.RESTART_SUBMIT)?.addEventListener('click', () => restartApp()); -}; - -export { setInputButtonsEvent, setRestartButtonEvent }; diff --git a/src/controller/game.ts b/src/controller/game.ts deleted file mode 100644 index 177a14d23..000000000 --- a/src/controller/game.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { ALERT, DELAY, SELECTOR } from '../constants/index.js'; -import { $, buttonElementEnable } from '../utils.js'; -import { Car, Game } from '../model/index.js'; -import { removeSpinners } from '../view/remover.js'; -import { renderArrowDiv, renderResultSection } from '../view/renderer.js'; -import { setRestartButtonEvent } from './event.js'; -import { buttonElementDisable } from '../utils.js'; - -const makeDelay = async (ms: number): Promise => { - return new Promise((r) => setTimeout(r, ms)); -}; - -const createCarsObject = (carNameArray: Array) => { - const cars: Array = []; - - carNameArray.forEach((car, index) => { - cars.push(new Car(car, index)); - }); - return cars; -}; - -const playOnce = (racingGame: Game) => { - racingGame.play(); - racingGame.roundWinnersIndex.forEach((roundWinnerIndex) => { - renderArrowDiv(roundWinnerIndex); - }); - racingGame.initRoundWinnersIndex(); -}; - -const startGame = async (carNameArray: Array, tryCount: number): Promise => { - const racingGame: Game = new Game(createCarsObject(carNameArray)); - let racingWinners: Array = []; - - for (let index = 0; index < tryCount; index += 1) { - await makeDelay(DELAY.TURN).then(() => playOnce(racingGame)); - } - removeSpinners(); - racingWinners = racingGame.getWinners(); - renderResultSection(racingWinners.join(', ').toLowerCase()); - await makeDelay(DELAY.END).then(() => alert(racingWinners.join(', ') + ALERT.CONGRATULATION)); - buttonElementEnable($(SELECTOR.RESTART_SUBMIT) as HTMLButtonElement); - setRestartButtonEvent(); -}; - -export { startGame }; diff --git a/src/controller/gameController.ts b/src/controller/gameController.ts new file mode 100644 index 000000000..dd813b8c6 --- /dev/null +++ b/src/controller/gameController.ts @@ -0,0 +1,32 @@ +import { ALERT, DELAY, SELECTOR } from '../constants.js'; +import { $ } from '../utils.js'; +import { Game } from '../model/Game.js'; +import { enableButton } from '../view/utils.js'; +import { renderArrowDiv, removeSpinnerDivs } from '../view/progressSectionRenderer.js'; +import { renderResultSection } from '../view/resultSectionRenderer.js'; +import { addRestartButtonEvent } from './restartController.js'; +import { InputData } from '../model/InputData.js'; + +const playOnce = (racingGame: Game) => { + racingGame.play(); + racingGame.roundWinners.forEach((index) => { + renderArrowDiv(index); + }); + racingGame.initRoundWinners(); +}; + +const startGame = async (inputData: InputData): Promise => { + const racingGame: Game = new Game(inputData.carNameArray); + + for (let index = 0; index < inputData.tryCount; index += 1) { + await racingGame.makeDelay(DELAY.GAME_TURN).then(() => playOnce(racingGame)); + } + racingGame.judgeFinalWinners(); + removeSpinnerDivs(); + renderResultSection(racingGame.finalWinners.join(', ').toLowerCase()); + await racingGame.makeDelay(DELAY.GAME_END).then(() => alert(racingGame.finalWinners.join(', ') + ALERT.CONGRATULATION)); + enableButton($(SELECTOR.RESTART_SUBMIT_BUTTON) as HTMLButtonElement); + addRestartButtonEvent(); +}; + +export { startGame }; diff --git a/src/controller/inputController.ts b/src/controller/inputController.ts new file mode 100644 index 000000000..f8b5f1a5f --- /dev/null +++ b/src/controller/inputController.ts @@ -0,0 +1,46 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; +import { startGame } from './gameController.js'; +import { InputData } from '../model/InputData.js'; +import { renderProgressSection } from '../view/progressSectionRenderer.js'; +import { clearInput, enableInput, disableInput, enableButton, disableButton } from '../view/utils.js'; + +const getCarNames = (inputData: InputData): void => { + const carNameInput: HTMLInputElement = $(SELECTOR.CARNAME_INPUT) as HTMLInputElement; + const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); + + if (inputData.checkCarNames(carNameInput, carNameArray)) { + renderProgressSection(carNameArray); + inputData.carNameArray = carNameArray; + disableInput(carNameInput); + disableButton($(SELECTOR.CARNAME_SUBMIT_BUTTON) as HTMLButtonElement); + enableInput($(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement); + enableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON) as HTMLButtonElement); + ($(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement).focus(); + return; + } + clearInput(carNameInput); +}; + +const getTryCount = (inputData: InputData): void => { + const tryCountInput: HTMLInputElement = $(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement; + const tryCount = Number(tryCountInput?.value); + + if (inputData.checkTryCount(tryCountInput)) { + inputData.tryCount = tryCount; + disableInput(tryCountInput); + disableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON) as HTMLButtonElement); + startGame(inputData); + return; + } + clearInput(tryCountInput); +}; + +const addInputButtonsEvent = (): void => { + const inputData: InputData = new InputData(); + + $(SELECTOR.CARNAME_SUBMIT_BUTTON)?.addEventListener('click', () => getCarNames(inputData)); + $(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)?.addEventListener('click', () => getTryCount(inputData)); +}; + +export { addInputButtonsEvent }; diff --git a/src/controller/linstener.ts b/src/controller/linstener.ts deleted file mode 100644 index 4e8833ebd..000000000 --- a/src/controller/linstener.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { SELECTOR } from '../constants/index.js'; -import { startGame } from './game.js'; -import { renderProgressSection, renderInputSection } from '../view/renderer.js'; -import { setInputButtonsEvent } from './event.js'; -import { checkCarNames, checkTryCount } from './validtor.js'; -import { removeChildNodes } from '../view/remover.js'; -import { - $, - inputElementClear, - inputElementEnable, - inputElementDisable, - buttonElementEnable, - buttonElementDisable, -} from '../utils.js'; - -const getCarNames = (): void => { - const carNameInput: HTMLInputElement = $(SELECTOR.CARNAME_INPUT) as HTMLInputElement; - const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - - if (checkCarNames(carNameInput, carNameArray)) { - const carNameSubmitButton: HTMLButtonElement = $(SELECTOR.CARNAME_SUBMIT) as HTMLButtonElement; - const tryCountInput: HTMLInputElement = $(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement; - const tryCountSubmitButton: HTMLButtonElement = $(SELECTOR.TRYCOUNT_SUBMIT) as HTMLButtonElement; - - inputElementDisable(carNameInput); - buttonElementDisable(carNameSubmitButton); - inputElementEnable(tryCountInput); - buttonElementEnable(tryCountSubmitButton); - renderProgressSection(carNameArray); - tryCountInput.focus(); - return; - } - inputElementClear(carNameInput); -}; - -const getTryCount = (): void => { - const tryCountInput: HTMLInputElement = $(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement; - const tryCount = Number(tryCountInput?.value); - - if (checkTryCount(tryCountInput)) { - const carNameInput: HTMLInputElement = $(SELECTOR.CARNAME_INPUT) as HTMLInputElement; - const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); - const tryCountSubmitButton: HTMLButtonElement = $(SELECTOR.TRYCOUNT_SUBMIT) as HTMLButtonElement; - - inputElementDisable(tryCountInput); - buttonElementDisable(tryCountSubmitButton); - startGame(carNameArray, tryCount); - return; - } - inputElementClear(tryCountInput); -}; - -const restartApp = (): void => { - removeChildNodes($(SELECTOR.APP_DIV)); - renderInputSection(); - setInputButtonsEvent(); - ($(SELECTOR.CARNAME_INPUT) as HTMLInputElement).focus(); -}; - -export { getCarNames, getTryCount, restartApp }; diff --git a/src/controller/restartController.ts b/src/controller/restartController.ts new file mode 100644 index 000000000..69d07ba69 --- /dev/null +++ b/src/controller/restartController.ts @@ -0,0 +1,17 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; +import { removeChildNodes } from '../view/utils.js'; +import { renderInputSection } from '../view/inputSectionRenderer.js'; + +const init = (): void => { + removeChildNodes($(SELECTOR.APP_DIV)); + renderInputSection(); + addRestartButtonEvent(); + ($(SELECTOR.CARNAME_INPUT) as HTMLInputElement).focus(); +}; + +const addRestartButtonEvent = (): void => { + $(SELECTOR.RESTART_SUBMIT_BUTTON)?.addEventListener('click', () => init()); +}; + +export { addRestartButtonEvent }; diff --git a/src/controller/validtor.ts b/src/controller/validtor.ts deleted file mode 100644 index e8929835a..000000000 --- a/src/controller/validtor.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { ALERT } from '../constants/index.js'; - -const checkEmptyInput = (input: HTMLInputElement) => { - return input.value.trim() === ''; -}; - -const checkArrayHasEmptyElement = (array: Array) => { - return array.some((x) => x === ''); -} - -const checkArrayHasOneElement = (array: Array) => { - return array.length < 2; -}; - -const checkArrayDupElements = (array: Array) => { - return array.some((x) => { - return array.indexOf(x) !== array.lastIndexOf(x); - }); -}; - -const checkArrayElementsLength = (array: Array) => { - for (let index = 0; index < array.length; index += 1) { - if (array[index].length > 5) { - return true; - } - } - return false; -}; - -const checkCarNames = (carNameInput: HTMLInputElement, carNameArray: Array): boolean => { - if (checkEmptyInput(carNameInput)) { - alert(ALERT.CARNAME_NOTHING); - return false; - } else if (checkArrayHasOneElement(carNameArray)) { - alert(ALERT.CARNAME_ALONE); - return false; - } else if (checkArrayHasEmptyElement(carNameArray)) { - alert(ALERT.CARNAME_EMPTY); - return false; - } else if (checkArrayDupElements(carNameArray)) { - alert(ALERT.CARNAME_DOUBLE); - return false; - } else if (checkArrayElementsLength(carNameArray)) { - alert(ALERT.CARNAME_LENGTH); - return false; - } - return true; -}; - -const checkTryCount = (tryCountInput: HTMLInputElement): boolean => { - if (checkEmptyInput(tryCountInput)) { - alert(ALERT.TRYCOUNT_NOTHING); - return false; - } else if (Number(tryCountInput.value) < 1) { - alert(ALERT.TRYCOUNT_UINT); - return false; - } else if (Number(tryCountInput.value) > 50) { - alert(ALERT.TRYCOUNT_TOO_BIG); - return false; - } - return true; -}; - -export { checkCarNames, checkTryCount }; diff --git a/src/index.ts b/src/index.ts index cc20e8b6c..417aed623 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,9 +1,9 @@ -import { renderInputSection } from './view/renderer.js'; -import { setInputButtonsEvent } from './controller/event.js'; +import { renderInputSection } from './view/inputSectionRenderer.js'; +import { addInputButtonsEvent } from './controller/inputController.js'; const app = (): void => { renderInputSection(); - setInputButtonsEvent(); + addInputButtonsEvent(); }; app(); diff --git a/src/model/InputData.ts b/src/model/InputData.ts new file mode 100644 index 000000000..45a399d61 --- /dev/null +++ b/src/model/InputData.ts @@ -0,0 +1,75 @@ +import { RULE, ALERT } from '../constants.js'; + +class InputData { + carNameArray: Array; + tryCount: Number; + + constructor() { + this.carNameArray = []; + this.tryCount = 0; + } + + checkEmptyInput(input: HTMLInputElement): boolean { + return input.value.trim() === ''; + }; + + checkArrayHasEmptyElement(array: Array): boolean { + return array.some((x) => x === ''); + } + + checkArrayHasOneElement(array: Array): boolean { + return array.length < 2; + }; + + checkArrayDupElements(array: Array): boolean { + return array.some((x) => { + return array.indexOf(x) !== array.lastIndexOf(x); + }); + }; + + checkArrayElementsLength(array: Array): boolean { + for (let index = 0; index < array.length; index += 1) { + if (array[index].length > RULE.MAX_CARNAME_LENGTH) { + return true; + } + } + return false; + }; + + checkCarNames(carNameInput: HTMLInputElement, carNameArray: Array): boolean { + if (this.checkEmptyInput(carNameInput)) { + alert(ALERT.CARNAME_NOTHING); + return false; + } else if (this.checkArrayHasOneElement(carNameArray)) { + alert(ALERT.CARNAME_ALONE); + return false; + } else if (this.checkArrayHasEmptyElement(carNameArray)) { + alert(ALERT.CARNAME_EMPTY); + return false; + } else if (this.checkArrayDupElements(carNameArray)) { + alert(ALERT.CARNAME_DOUBLE); + return false; + } else if (this.checkArrayElementsLength(carNameArray)) { + alert(ALERT.CARNAME_LENGTH); + return false; + } + return true; + }; + + checkTryCount(tryCountInput: HTMLInputElement): boolean { + if (this.checkEmptyInput(tryCountInput)) { + alert(ALERT.TRYCOUNT_NOTHING); + return false; + } else if (Number(tryCountInput.value) < RULE.MIN_TRY_COUNT) { + alert(ALERT.TRYCOUNT_UINT); + return false; + } else if (Number(tryCountInput.value) > RULE.MAX_TRY_COUNT) { + alert(ALERT.TRYCOUNT_TOO_BIG); + return false; + } + return true; + }; + +} + +export { InputData } diff --git a/src/model/game.ts b/src/model/game.ts index 0ddc9b22e..cbe115332 100644 --- a/src/model/game.ts +++ b/src/model/game.ts @@ -1,29 +1,40 @@ -import { Car } from './index.js'; -import { RULE } from '../constants/index.js'; +import { Car } from './Car.js'; +import { RULE } from '../constants.js'; class Game { cars: Array; finalWinners: Array; - roundWinnersIndex: Array; + roundWinners: Array; maxPosition: number; - constructor(cars: Array) { - this.cars = cars; + constructor(carNameArray: Array) { + this.cars = []; this.finalWinners = []; - this.roundWinnersIndex = []; + this.roundWinners = []; this.maxPosition = 0; + this.setCarsObject(carNameArray); } play(): void { this.cars.forEach((car) => { if (Math.floor(Math.random() * RULE.MAX_SCORE) + RULE.MIN_SCORE >= RULE.THRESHOULD_SCORE) { car.moveForward(); - this.roundWinnersIndex.push(car.index); - this.updateMaxPosition(); + this.roundWinners.push(car.index); } }); + this.updateMaxPosition(); } + setCarsObject(carNameArray: Array): void { + carNameArray.forEach((car, index) => { + this.cars.push(new Car(car, index)); + }); + }; + + async makeDelay(ms: number): Promise { + return new Promise((r) => setTimeout(r, ms)); + }; + updateMaxPosition(): void { this.cars.forEach((car) => { if (car.position > this.maxPosition) { @@ -32,17 +43,16 @@ class Game { }); } - initRoundWinnersIndex(): void { - this.roundWinnersIndex = []; + initRoundWinners(): void { + this.roundWinners = []; } - getWinners(): Array { + judgeFinalWinners(): void { this.cars.forEach((car) => { if (car.position === this.maxPosition) { this.finalWinners.push(car.name); } }); - return this.finalWinners; } } diff --git a/src/model/index.ts b/src/model/index.ts deleted file mode 100644 index b7af6d7f6..000000000 --- a/src/model/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { Car } from './car.js'; -export { Game } from './game.js'; \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 10ffc9764..147a8b8af 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,34 +1,4 @@ const $ = (selector: string): Element | null => document.querySelector(selector); - const $$ = (selector: string): NodeListOf => document.querySelectorAll(selector); -const inputElementClear = (element: HTMLInputElement): void => { - element.value = ''; - element.focus(); -}; - -const inputElementEnable = (element: HTMLInputElement): void => { - element.disabled = false; -}; - -const inputElementDisable = (element: HTMLInputElement): void => { - element.disabled = true; -}; - -const buttonElementEnable = (element: HTMLButtonElement): void => { - element.disabled = false; -}; - -const buttonElementDisable = (element: HTMLButtonElement): void => { - element.disabled = true; -}; - -export { - $, - $$, - inputElementClear, - inputElementEnable, - inputElementDisable, - buttonElementEnable, - buttonElementDisable -}; +export { $, $$ }; diff --git a/src/view/templates/input-section.ts b/src/view/inputSectionRenderer.ts similarity index 82% rename from src/view/templates/input-section.ts rename to src/view/inputSectionRenderer.ts index b7c65782c..cf19df63b 100644 --- a/src/view/templates/input-section.ts +++ b/src/view/inputSectionRenderer.ts @@ -1,3 +1,6 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; + const inputSection = (): string => { return `
@@ -25,4 +28,8 @@ const inputSection = (): string => { `; }; -export { inputSection }; +const renderInputSection = (): void => { + ($(SELECTOR.APP_DIV) as HTMLDivElement).innerHTML = inputSection(); +}; + +export { renderInputSection }; diff --git a/src/view/progressSectionRenderer.ts b/src/view/progressSectionRenderer.ts new file mode 100644 index 000000000..bb9f48864 --- /dev/null +++ b/src/view/progressSectionRenderer.ts @@ -0,0 +1,59 @@ +import { $, $$ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; + +const progressSection = (): string => { + return ` +
+
+
+
+ `; +}; + +const carNameDiv = (carName: string): string => { + return ` +
+
${carName}
+
+ `; +}; + +const spinnerDiv = (): string => { + return ` +
+
+ +
+
+ `; +}; + +const arrowDiv = (): string => { + return ` +
⬇️️
+ `; +}; + +const renderProgressSection = (carNameArray: Array): void => { + ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); + carNameArray.forEach((carName) => { + ($(SELECTOR.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); + }); + ($$(SELECTOR.CAR_RACE_TRACK_DIVS) as NodeListOf).forEach((element) => { + element.insertAdjacentHTML(`beforeend`, spinnerDiv()); + }); +}; + +const renderArrowDiv = (roundWinnerIndex: number): void => { + ($$(SELECTOR.CARNAME_DIVS) as NodeListOf).forEach((element, index) => { + index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; + }); +}; + +const removeSpinnerDivs = (): void => { + $$(SELECTOR.SPINNER_DIVS).forEach((element) => { + element.remove(); + }); +}; + +export { renderProgressSection, renderArrowDiv, removeSpinnerDivs }; diff --git a/src/view/remover.ts b/src/view/remover.ts deleted file mode 100644 index 44af637f7..000000000 --- a/src/view/remover.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { $$ } from '../utils.js'; -import { SELECTOR } from '../constants/selector.js'; - -const removeSpinners = (): void => { - $$(SELECTOR.SPINNER_DIVS).forEach((element) => { - element.remove(); - }); -}; - -const removeChildNodes = (element: Element | null): void => { - if (!element) { - return; - } - while (element.hasChildNodes()) { - if (element.lastChild) { - element.removeChild(element.lastChild); - } - } -}; - -export { removeSpinners, removeChildNodes }; diff --git a/src/view/renderer.ts b/src/view/renderer.ts deleted file mode 100644 index 36b380e8a..000000000 --- a/src/view/renderer.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { $, $$ } from '../utils.js'; -import { SELECTOR } from '../constants/index.js'; -import { inputSection, progressSection, carNameDiv, spinnerDiv, arrowDiv, resultSection } from './templates/index.js'; - -const renderInputSection = (): void => { - ($(SELECTOR.APP_DIV) as HTMLDivElement).innerHTML = inputSection(); -}; - -const renderProgressSection = (carNameArray: Array): void => { - ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); - carNameArray.forEach((carName) => { - ($(SELECTOR.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); - }); - ($$(SELECTOR.CAR_RACE_TRACK_DIVS) as NodeListOf).forEach((element) => { - element.insertAdjacentHTML(`beforeend`, spinnerDiv()); - }); -}; - -const renderArrowDiv = (roundWinnerIndex: number): void => { - ($$(SELECTOR.CARNAME_DIVS) as NodeListOf).forEach((element, index) => { - index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; - }); -}; - -const renderResultSection = (winners: string): void => { - ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); -}; - -export { renderInputSection, renderProgressSection, renderArrowDiv, renderResultSection }; diff --git a/src/view/templates/result-section.ts b/src/view/resultSectionRenderer.ts similarity index 59% rename from src/view/templates/result-section.ts rename to src/view/resultSectionRenderer.ts index 16e923e1a..ebd567806 100644 --- a/src/view/templates/result-section.ts +++ b/src/view/resultSectionRenderer.ts @@ -1,3 +1,6 @@ +import { $ } from '../utils.js'; +import { SELECTOR } from '../constants.js'; + const resultSection = (winners: string): string => { return `
@@ -11,4 +14,8 @@ const resultSection = (winners: string): string => { `; }; -export { resultSection }; +const renderResultSection = (winners: string): void => { + ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); +}; + +export { renderResultSection }; diff --git a/src/view/templates/index.ts b/src/view/templates/index.ts deleted file mode 100644 index 485004e86..000000000 --- a/src/view/templates/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { inputSection } from './input-section.js'; -export { progressSection, carNameDiv, spinnerDiv, arrowDiv } from './progress-section.js'; -export { resultSection } from './result-section.js'; \ No newline at end of file diff --git a/src/view/templates/progress-section.ts b/src/view/templates/progress-section.ts deleted file mode 100644 index d026bf652..000000000 --- a/src/view/templates/progress-section.ts +++ /dev/null @@ -1,34 +0,0 @@ -const progressSection = (): string => { - return ` -
-
-
-
- `; -}; - -const carNameDiv = (carName: string): string => { - return ` -
-
${carName}
-
- `; -}; - -const spinnerDiv = (): string => { - return ` -
-
- -
-
- `; -}; - -const arrowDiv = (): string => { - return ` -
⬇️️
- `; -}; - -export { progressSection, carNameDiv, spinnerDiv, arrowDiv }; diff --git a/src/view/utils.ts b/src/view/utils.ts new file mode 100644 index 000000000..19a4bc9b4 --- /dev/null +++ b/src/view/utils.ts @@ -0,0 +1,33 @@ +const clearInput = (element: HTMLInputElement): void => { + element.value = ''; + element.focus(); +}; + +const enableInput = (element: HTMLInputElement): void => { + element.disabled = false; +}; + +const disableInput = (element: HTMLInputElement): void => { + element.disabled = true; +}; + +const enableButton = (element: HTMLButtonElement): void => { + element.disabled = false; +}; + +const disableButton = (element: HTMLButtonElement): void => { + element.disabled = true; +}; + +const removeChildNodes = (element: Element | null): void => { + if (!element) { + return; + } + while (element.hasChildNodes()) { + if (element.lastChild) { + element.removeChild(element.lastChild); + } + } +}; + +export { clearInput, enableInput, disableInput, enableButton, disableButton, removeChildNodes }; From 2d88e563cdb6995d0a01f0fe6e1bb46c3eae960a Mon Sep 17 00:00:00 2001 From: jwon42 Date: Wed, 16 Jun 2021 16:37:58 +0900 Subject: [PATCH 66/70] refactor: change file name --- dist/model/{car.js => Car.js} | 0 dist/model/{game.js => Game.js} | 0 src/model/{car.ts => Car.ts} | 0 src/model/{game.ts => Game.ts} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename dist/model/{car.js => Car.js} (100%) rename dist/model/{game.js => Game.js} (100%) rename src/model/{car.ts => Car.ts} (100%) rename src/model/{game.ts => Game.ts} (100%) diff --git a/dist/model/car.js b/dist/model/Car.js similarity index 100% rename from dist/model/car.js rename to dist/model/Car.js diff --git a/dist/model/game.js b/dist/model/Game.js similarity index 100% rename from dist/model/game.js rename to dist/model/Game.js diff --git a/src/model/car.ts b/src/model/Car.ts similarity index 100% rename from src/model/car.ts rename to src/model/Car.ts diff --git a/src/model/game.ts b/src/model/Game.ts similarity index 100% rename from src/model/game.ts rename to src/model/Game.ts From a81a040a1117717dd2e8b5cfb4078faeeee09818 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Wed, 16 Jun 2021 17:42:45 +0900 Subject: [PATCH 67/70] refactor: remove SELECTOR constant --- dist/constants.js | 20 +------------------- dist/controller/gameController.js | 4 ++-- dist/controller/inputController.js | 19 +++++++++---------- dist/controller/restartController.js | 7 +++---- dist/view/inputSectionRenderer.js | 3 +-- dist/view/progressSectionRenderer.js | 11 +++++------ dist/view/resultSectionRenderer.js | 3 +-- src/constants.ts | 24 +----------------------- src/controller/gameController.ts | 4 ++-- src/controller/inputController.ts | 19 +++++++++---------- src/controller/restartController.ts | 7 +++---- src/view/inputSectionRenderer.ts | 3 +-- src/view/progressSectionRenderer.ts | 11 +++++------ src/view/resultSectionRenderer.ts | 3 +-- 14 files changed, 44 insertions(+), 94 deletions(-) diff --git a/dist/constants.js b/dist/constants.js index 59415bd98..40239342a 100644 --- a/dist/constants.js +++ b/dist/constants.js @@ -14,24 +14,6 @@ const RULE = { MIN_TRY_COUNT: 1, MAX_TRY_COUNT: 50, }; -const SELECTOR = { - APP_DIV: '#app', - // input-section - INPUT_SECTION: '#input-section', - CARNAME_INPUT: '#car-names-input', - CARNAME_SUBMIT_BUTTON: '#car-names-submit', - TRYCOUNT_INPUT: '#racing-count-input', - TRYCOUNT_SUBMIT_BUTTON: '#racing-count-submit', - // progress-section - PROGRESS_SECTION: '#progress-section', - CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', - CARNAMES_DIV: '#progress-section .mt-4', - CARNAME_DIVS: '#progress-section .car-player', - SPINNER_DIVS: '#progress-section .mt-3', - // result-section - RESULT_SECTION: '#result-section', - RESTART_SUBMIT_BUTTON: '#restart-button', -}; const ALERT = { // for check valid car name CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', @@ -46,4 +28,4 @@ const ALERT = { // etc. CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', }; -export { DELAY, RULE, SELECTOR, ALERT }; +export { DELAY, RULE, ALERT }; diff --git a/dist/controller/gameController.js b/dist/controller/gameController.js index 8a54bf459..1e222bd10 100644 --- a/dist/controller/gameController.js +++ b/dist/controller/gameController.js @@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -import { ALERT, DELAY, SELECTOR } from '../constants.js'; +import { ALERT, DELAY } from '../constants.js'; import { $ } from '../utils.js'; import { Game } from '../model/Game.js'; import { enableButton } from '../view/utils.js'; @@ -30,7 +30,7 @@ const startGame = (inputData) => __awaiter(void 0, void 0, void 0, function* () removeSpinnerDivs(); renderResultSection(racingGame.finalWinners.join(', ').toLowerCase()); yield racingGame.makeDelay(DELAY.GAME_END).then(() => alert(racingGame.finalWinners.join(', ') + ALERT.CONGRATULATION)); - enableButton($(SELECTOR.RESTART_SUBMIT_BUTTON)); + enableButton($('#restart-button')); addRestartButtonEvent(); }); export { startGame }; diff --git a/dist/controller/inputController.js b/dist/controller/inputController.js index ba6fd0a45..933b237e2 100644 --- a/dist/controller/inputController.js +++ b/dist/controller/inputController.js @@ -1,31 +1,30 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; import { startGame } from './gameController.js'; import { InputData } from '../model/InputData.js'; import { renderProgressSection } from '../view/progressSectionRenderer.js'; import { clearInput, enableInput, disableInput, enableButton, disableButton } from '../view/utils.js'; const getCarNames = (inputData) => { - const carNameInput = $(SELECTOR.CARNAME_INPUT); + const carNameInput = $('#car-names-input'); const carNameArray = carNameInput === null || carNameInput === void 0 ? void 0 : carNameInput.value.split(',').map((x) => x.trim()); if (inputData.checkCarNames(carNameInput, carNameArray)) { renderProgressSection(carNameArray); inputData.carNameArray = carNameArray; disableInput(carNameInput); - disableButton($(SELECTOR.CARNAME_SUBMIT_BUTTON)); - enableInput($(SELECTOR.TRYCOUNT_INPUT)); - enableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)); - $(SELECTOR.TRYCOUNT_INPUT).focus(); + disableButton($('#car-names-submit')); + enableInput($('#racing-count-input')); + enableButton($('#racing-count-submit')); + $('#racing-count-input').focus(); return; } clearInput(carNameInput); }; const getTryCount = (inputData) => { - const tryCountInput = $(SELECTOR.TRYCOUNT_INPUT); + const tryCountInput = $('#racing-count-input'); const tryCount = Number(tryCountInput === null || tryCountInput === void 0 ? void 0 : tryCountInput.value); if (inputData.checkTryCount(tryCountInput)) { inputData.tryCount = tryCount; disableInput(tryCountInput); - disableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)); + disableButton($('#racing-count-submit')); startGame(inputData); return; } @@ -34,7 +33,7 @@ const getTryCount = (inputData) => { const addInputButtonsEvent = () => { var _a, _b; const inputData = new InputData(); - (_a = $(SELECTOR.CARNAME_SUBMIT_BUTTON)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames(inputData)); - (_b = $(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount(inputData)); + (_a = $('#car-names-submit')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => getCarNames(inputData)); + (_b = $('#racing-count-submit')) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => getTryCount(inputData)); }; export { addInputButtonsEvent }; diff --git a/dist/controller/restartController.js b/dist/controller/restartController.js index 0e57f6224..fc03bb5e2 100644 --- a/dist/controller/restartController.js +++ b/dist/controller/restartController.js @@ -1,15 +1,14 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; import { removeChildNodes } from '../view/utils.js'; import { renderInputSection } from '../view/inputSectionRenderer.js'; const init = () => { - removeChildNodes($(SELECTOR.APP_DIV)); + removeChildNodes($('#app')); renderInputSection(); addRestartButtonEvent(); - $(SELECTOR.CARNAME_INPUT).focus(); + $('#car-names-input').focus(); }; const addRestartButtonEvent = () => { var _a; - (_a = $(SELECTOR.RESTART_SUBMIT_BUTTON)) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => init()); + (_a = $('#restart-button')) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => init()); }; export { addRestartButtonEvent }; diff --git a/dist/view/inputSectionRenderer.js b/dist/view/inputSectionRenderer.js index 0bdbdeec8..08c7b1cde 100644 --- a/dist/view/inputSectionRenderer.js +++ b/dist/view/inputSectionRenderer.js @@ -1,5 +1,4 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; const inputSection = () => { return `
@@ -27,6 +26,6 @@ const inputSection = () => { `; }; const renderInputSection = () => { - $(SELECTOR.APP_DIV).innerHTML = inputSection(); + $('#app').innerHTML = inputSection(); }; export { renderInputSection }; diff --git a/dist/view/progressSectionRenderer.js b/dist/view/progressSectionRenderer.js index 084c9ec95..f2b0a01f4 100644 --- a/dist/view/progressSectionRenderer.js +++ b/dist/view/progressSectionRenderer.js @@ -1,5 +1,4 @@ import { $, $$ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; const progressSection = () => { return `
@@ -30,21 +29,21 @@ const arrowDiv = () => { `; }; const renderProgressSection = (carNameArray) => { - $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', progressSection()); + $('#app').insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - $(SELECTOR.CARNAMES_DIV).insertAdjacentHTML('beforeend', carNameDiv(carName)); + $('#progress-section .mt-4').insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - $$(SELECTOR.CAR_RACE_TRACK_DIVS).forEach((element) => { + $$('#progress-section .mr-2').forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex) => { - $$(SELECTOR.CARNAME_DIVS).forEach((element, index) => { + $$('#progress-section .car-player').forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const removeSpinnerDivs = () => { - $$(SELECTOR.SPINNER_DIVS).forEach((element) => { + $$('#progress-section .mt-3').forEach((element) => { element.remove(); }); }; diff --git a/dist/view/resultSectionRenderer.js b/dist/view/resultSectionRenderer.js index d6f1737c4..494468012 100644 --- a/dist/view/resultSectionRenderer.js +++ b/dist/view/resultSectionRenderer.js @@ -1,5 +1,4 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; const resultSection = (winners) => { return `
@@ -13,6 +12,6 @@ const resultSection = (winners) => { `; }; const renderResultSection = (winners) => { - $(SELECTOR.APP_DIV).insertAdjacentHTML('beforeend', resultSection(winners)); + $('#app').insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderResultSection }; diff --git a/src/constants.ts b/src/constants.ts index ff0b036b0..4b492e64a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -18,28 +18,6 @@ const RULE = { MAX_TRY_COUNT: 50, }; -const SELECTOR = { - APP_DIV: '#app', - - // input-section - INPUT_SECTION: '#input-section', - CARNAME_INPUT: '#car-names-input', - CARNAME_SUBMIT_BUTTON: '#car-names-submit', - TRYCOUNT_INPUT: '#racing-count-input', - TRYCOUNT_SUBMIT_BUTTON: '#racing-count-submit', - - // progress-section - PROGRESS_SECTION: '#progress-section', - CAR_RACE_TRACK_DIVS: '#progress-section .mr-2', - CARNAMES_DIV: '#progress-section .mt-4', - CARNAME_DIVS: '#progress-section .car-player', - SPINNER_DIVS: '#progress-section .mt-3', - - // result-section - RESULT_SECTION: '#result-section', - RESTART_SUBMIT_BUTTON: '#restart-button', -}; - const ALERT = { // for check valid car name CARNAME_NOTHING: 'μžλ™μ°¨ 이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”', @@ -57,4 +35,4 @@ const ALERT = { CONGRATULATION: 'λ‹˜ μš°μŠΉμ„ μΆ•ν•˜ν•©λ‹ˆλ‹€ πŸ‘', }; -export { DELAY, RULE, SELECTOR, ALERT } \ No newline at end of file +export { DELAY, RULE, ALERT } \ No newline at end of file diff --git a/src/controller/gameController.ts b/src/controller/gameController.ts index dd813b8c6..1a85b6efe 100644 --- a/src/controller/gameController.ts +++ b/src/controller/gameController.ts @@ -1,4 +1,4 @@ -import { ALERT, DELAY, SELECTOR } from '../constants.js'; +import { ALERT, DELAY } from '../constants.js'; import { $ } from '../utils.js'; import { Game } from '../model/Game.js'; import { enableButton } from '../view/utils.js'; @@ -25,7 +25,7 @@ const startGame = async (inputData: InputData): Promise => { removeSpinnerDivs(); renderResultSection(racingGame.finalWinners.join(', ').toLowerCase()); await racingGame.makeDelay(DELAY.GAME_END).then(() => alert(racingGame.finalWinners.join(', ') + ALERT.CONGRATULATION)); - enableButton($(SELECTOR.RESTART_SUBMIT_BUTTON) as HTMLButtonElement); + enableButton($('#restart-button') as HTMLButtonElement); addRestartButtonEvent(); }; diff --git a/src/controller/inputController.ts b/src/controller/inputController.ts index f8b5f1a5f..40651c8e4 100644 --- a/src/controller/inputController.ts +++ b/src/controller/inputController.ts @@ -1,35 +1,34 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; import { startGame } from './gameController.js'; import { InputData } from '../model/InputData.js'; import { renderProgressSection } from '../view/progressSectionRenderer.js'; import { clearInput, enableInput, disableInput, enableButton, disableButton } from '../view/utils.js'; const getCarNames = (inputData: InputData): void => { - const carNameInput: HTMLInputElement = $(SELECTOR.CARNAME_INPUT) as HTMLInputElement; + const carNameInput: HTMLInputElement = $('#car-names-input') as HTMLInputElement; const carNameArray: Array = carNameInput?.value.split(',').map((x) => x.trim()); if (inputData.checkCarNames(carNameInput, carNameArray)) { renderProgressSection(carNameArray); inputData.carNameArray = carNameArray; disableInput(carNameInput); - disableButton($(SELECTOR.CARNAME_SUBMIT_BUTTON) as HTMLButtonElement); - enableInput($(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement); - enableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON) as HTMLButtonElement); - ($(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement).focus(); + disableButton($('#car-names-submit') as HTMLButtonElement); + enableInput($('#racing-count-input') as HTMLInputElement); + enableButton($('#racing-count-submit') as HTMLButtonElement); + ($('#racing-count-input') as HTMLInputElement).focus(); return; } clearInput(carNameInput); }; const getTryCount = (inputData: InputData): void => { - const tryCountInput: HTMLInputElement = $(SELECTOR.TRYCOUNT_INPUT) as HTMLInputElement; + const tryCountInput: HTMLInputElement = $('#racing-count-input') as HTMLInputElement; const tryCount = Number(tryCountInput?.value); if (inputData.checkTryCount(tryCountInput)) { inputData.tryCount = tryCount; disableInput(tryCountInput); - disableButton($(SELECTOR.TRYCOUNT_SUBMIT_BUTTON) as HTMLButtonElement); + disableButton($('#racing-count-submit') as HTMLButtonElement); startGame(inputData); return; } @@ -39,8 +38,8 @@ const getTryCount = (inputData: InputData): void => { const addInputButtonsEvent = (): void => { const inputData: InputData = new InputData(); - $(SELECTOR.CARNAME_SUBMIT_BUTTON)?.addEventListener('click', () => getCarNames(inputData)); - $(SELECTOR.TRYCOUNT_SUBMIT_BUTTON)?.addEventListener('click', () => getTryCount(inputData)); + $('#car-names-submit')?.addEventListener('click', () => getCarNames(inputData)); + $('#racing-count-submit')?.addEventListener('click', () => getTryCount(inputData)); }; export { addInputButtonsEvent }; diff --git a/src/controller/restartController.ts b/src/controller/restartController.ts index 69d07ba69..248505aea 100644 --- a/src/controller/restartController.ts +++ b/src/controller/restartController.ts @@ -1,17 +1,16 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; import { removeChildNodes } from '../view/utils.js'; import { renderInputSection } from '../view/inputSectionRenderer.js'; const init = (): void => { - removeChildNodes($(SELECTOR.APP_DIV)); + removeChildNodes($('#app')); renderInputSection(); addRestartButtonEvent(); - ($(SELECTOR.CARNAME_INPUT) as HTMLInputElement).focus(); + ($('#car-names-input') as HTMLInputElement).focus(); }; const addRestartButtonEvent = (): void => { - $(SELECTOR.RESTART_SUBMIT_BUTTON)?.addEventListener('click', () => init()); + $('#restart-button')?.addEventListener('click', () => init()); }; export { addRestartButtonEvent }; diff --git a/src/view/inputSectionRenderer.ts b/src/view/inputSectionRenderer.ts index cf19df63b..a065d2958 100644 --- a/src/view/inputSectionRenderer.ts +++ b/src/view/inputSectionRenderer.ts @@ -1,5 +1,4 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; const inputSection = (): string => { return ` @@ -29,7 +28,7 @@ const inputSection = (): string => { }; const renderInputSection = (): void => { - ($(SELECTOR.APP_DIV) as HTMLDivElement).innerHTML = inputSection(); + ($('#app') as HTMLDivElement).innerHTML = inputSection(); }; export { renderInputSection }; diff --git a/src/view/progressSectionRenderer.ts b/src/view/progressSectionRenderer.ts index bb9f48864..c3af3f3d8 100644 --- a/src/view/progressSectionRenderer.ts +++ b/src/view/progressSectionRenderer.ts @@ -1,5 +1,4 @@ import { $, $$ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; const progressSection = (): string => { return ` @@ -35,23 +34,23 @@ const arrowDiv = (): string => { }; const renderProgressSection = (carNameArray: Array): void => { - ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); + ($('#app') as HTMLDivElement).insertAdjacentHTML('beforeend', progressSection()); carNameArray.forEach((carName) => { - ($(SELECTOR.CARNAMES_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); + ($('#progress-section .mt-4') as HTMLDivElement).insertAdjacentHTML('beforeend', carNameDiv(carName)); }); - ($$(SELECTOR.CAR_RACE_TRACK_DIVS) as NodeListOf).forEach((element) => { + ($$('#progress-section .mr-2') as NodeListOf).forEach((element) => { element.insertAdjacentHTML(`beforeend`, spinnerDiv()); }); }; const renderArrowDiv = (roundWinnerIndex: number): void => { - ($$(SELECTOR.CARNAME_DIVS) as NodeListOf).forEach((element, index) => { + ($$('#progress-section .car-player') as NodeListOf).forEach((element, index) => { index === roundWinnerIndex ? element.insertAdjacentHTML(`afterend`, arrowDiv()) : null; }); }; const removeSpinnerDivs = (): void => { - $$(SELECTOR.SPINNER_DIVS).forEach((element) => { + $$('#progress-section .mt-3').forEach((element) => { element.remove(); }); }; diff --git a/src/view/resultSectionRenderer.ts b/src/view/resultSectionRenderer.ts index ebd567806..70d88b4d2 100644 --- a/src/view/resultSectionRenderer.ts +++ b/src/view/resultSectionRenderer.ts @@ -1,5 +1,4 @@ import { $ } from '../utils.js'; -import { SELECTOR } from '../constants.js'; const resultSection = (winners: string): string => { return ` @@ -15,7 +14,7 @@ const resultSection = (winners: string): string => { }; const renderResultSection = (winners: string): void => { - ($(SELECTOR.APP_DIV) as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); + ($('#app') as HTMLDivElement).insertAdjacentHTML('beforeend', resultSection(winners)); }; export { renderResultSection }; From c85401c484acb4e8961aa9b9bc8f9e99a628d071 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Thu, 17 Jun 2021 12:55:07 +0900 Subject: [PATCH 68/70] refactor: modify constants --- src/constants.ts | 4 ++-- src/model/InputData.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index 4b492e64a..45716dabd 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -14,8 +14,8 @@ const RULE = { MAX_CARNAME_LENGTH: 5, // μ‹œλ„ νšŸμˆ˜λŠ” μ›ν™œν•œ κ²Œμž„μ„ μœ„ν•΄ 자체적으둜 μ œν•œ - MIN_TRY_COUNT: 1, - MAX_TRY_COUNT: 50, + MIN_TRYCOUNT: 1, + MAX_TRYCOUNT: 50, }; const ALERT = { diff --git a/src/model/InputData.ts b/src/model/InputData.ts index 45a399d61..e8558dc55 100644 --- a/src/model/InputData.ts +++ b/src/model/InputData.ts @@ -60,10 +60,10 @@ class InputData { if (this.checkEmptyInput(tryCountInput)) { alert(ALERT.TRYCOUNT_NOTHING); return false; - } else if (Number(tryCountInput.value) < RULE.MIN_TRY_COUNT) { + } else if (Number(tryCountInput.value) < RULE.MIN_TRYCOUNT) { alert(ALERT.TRYCOUNT_UINT); return false; - } else if (Number(tryCountInput.value) > RULE.MAX_TRY_COUNT) { + } else if (Number(tryCountInput.value) > RULE.MAX_TRYCOUNT) { alert(ALERT.TRYCOUNT_TOO_BIG); return false; } From b12bee1643c22b40d102d4c37f8a71ae1004592d Mon Sep 17 00:00:00 2001 From: jwon42 Date: Thu, 17 Jun 2021 12:56:17 +0900 Subject: [PATCH 69/70] refactor: modify constants --- dist/constants.js | 4 ++-- dist/model/InputData.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/constants.js b/dist/constants.js index 40239342a..7e06f9006 100644 --- a/dist/constants.js +++ b/dist/constants.js @@ -11,8 +11,8 @@ const RULE = { // μžλ™μ°¨ 이름은 5자 μ΄ν•˜λ§Œ κ°€λŠ₯ MAX_CARNAME_LENGTH: 5, // μ‹œλ„ νšŸμˆ˜λŠ” μ›ν™œν•œ κ²Œμž„μ„ μœ„ν•΄ 자체적으둜 μ œν•œ - MIN_TRY_COUNT: 1, - MAX_TRY_COUNT: 50, + MIN_TRYCOUNT: 1, + MAX_TRYCOUNT: 50, }; const ALERT = { // for check valid car name diff --git a/dist/model/InputData.js b/dist/model/InputData.js index 7c1e426ce..0d0357cc7 100644 --- a/dist/model/InputData.js +++ b/dist/model/InputData.js @@ -59,11 +59,11 @@ class InputData { alert(ALERT.TRYCOUNT_NOTHING); return false; } - else if (Number(tryCountInput.value) < RULE.MIN_TRY_COUNT) { + else if (Number(tryCountInput.value) < RULE.MIN_TRYCOUNT) { alert(ALERT.TRYCOUNT_UINT); return false; } - else if (Number(tryCountInput.value) > RULE.MAX_TRY_COUNT) { + else if (Number(tryCountInput.value) > RULE.MAX_TRYCOUNT) { alert(ALERT.TRYCOUNT_TOO_BIG); return false; } From 304d03d002d4e6b4c5e9664cbb396d88010b9813 Mon Sep 17 00:00:00 2001 From: jwon42 Date: Thu, 17 Jun 2021 13:05:05 +0900 Subject: [PATCH 70/70] refactor: cypress constants --- cypress/integration/racingcar.spec.js | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/cypress/integration/racingcar.spec.js b/cypress/integration/racingcar.spec.js index cf02ec81f..39c545fde 100644 --- a/cypress/integration/racingcar.spec.js +++ b/cypress/integration/racingcar.spec.js @@ -1,20 +1,20 @@ -import { SELECTOR, ALERT, DELAY } from '../../dist/constants.js'; +import { ALERT, DELAY } from '../../dist/constants.js'; let carNamesSample = 'jwon, yeji, holee, yshin'; let tryCountSample = 3; const carNameInputAndSubmit = (carNames) => { if (carNames) { - cy.get(SELECTOR.CARNAME_INPUT).type(carNames); + cy.get('#car-names-input').type(carNames); } - cy.get(SELECTOR.CARNAME_SUBMIT).click(); + cy.get('#car-names-submit').click(); }; const tryCountInputAndSubmit = (tryCount) => { if (tryCount) { - cy.get(SELECTOR.TRYCOUNT_INPUT).type(tryCount); + cy.get('#racing-count-input').type(tryCount); } - cy.get(SELECTOR.TRYCOUNT_SUBMIT).click(); + cy.get('#racing-count-submit').click(); }; const catchAlertMessage = (alertMessage) => { @@ -29,9 +29,9 @@ describe('0. μ΄ˆκΈ°ν™”λ©΄ λ‘œλ”© ν…ŒμŠ€νŠΈ', () => { }); it('μžλ™μ°¨ κ²½μ£Ό κ²Œμž„μ„ μ‹€ν–‰ν•˜λ©΄, 인풋 μ„Ήμ…˜μ΄ 보이고 μžλ™μ°¨ μž…λ ₯창이 ν™œμ„±ν™”λœλ‹€.=', () => { - cy.get(SELECTOR.INPUT_SECTION).should('be.visible'); - cy.get(SELECTOR.CARNAME_INPUT).should('not.be.disabled'); - cy.get(SELECTOR.CARNAME_SUBMIT).should('not.be.disabled'); + cy.get('#input-section').should('be.visible'); + cy.get('#car-names-input').should('not.be.disabled'); + cy.get('#car-names-submit').should('not.be.disabled'); }); }); @@ -67,16 +67,16 @@ describe('1. μžλ™μ°¨ 이름 μž…λ ₯ ν…ŒμŠ€νŠΈ', () => { it('μžλ™μ°¨ 이름을 μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, μžλ™μ°¨ 이름 μž…λ ₯μΉΈκ³Ό 클릭 λ²„νŠΌμ„ λΉ„ν™œμ„±ν™” ν•˜κ³  μ‹œλ„ 횟수 μž…λ ₯μΉΈκ³Ό μ‹œλ„ 횟수 λ²„νŠΌμ„ ν™œμ„±ν™”ν•œλ‹€', () => { carNameInputAndSubmit(carNamesSample); - cy.get(SELECTOR.CARNAME_INPUT).should('be.disabled'); - cy.get(SELECTOR.CARNAME_SUBMIT).should('be.disabled'); - cy.get(SELECTOR.TRYCOUNT_INPUT).should('not.be.disabled'); - cy.get(SELECTOR.TRYCOUNT_SUBMIT).should('not.be.disabled'); + cy.get('#car-names-input').should('be.disabled'); + cy.get('#car-names-submit').should('be.disabled'); + cy.get('#racing-count-input').should('not.be.disabled'); + cy.get('#racing-count-submit').should('not.be.disabled'); }); it('μžλ™μ°¨ 이름을 μ •μƒμ μœΌλ‘œ μž…λ ₯ν•˜κ³  확인 λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 진행상황 μ„Ήμ…˜μ΄ λ‘œλ”©λœλ‹€. ', () => { carNameInputAndSubmit(carNamesSample); tryCountInputAndSubmit(tryCountSample); - cy.get(SELECTOR.PROGRESS_SECTION).should('be.visible'); + cy.get('#progress-section').should('be.visible'); }); }); @@ -130,10 +130,10 @@ describe('4. κ²Œμž„ μž¬μ‹œμž‘ ν…ŒμŠ€νŠΈ', () => { it('λ‹€μ‹œ μ‹œμž‘ν•˜κΈ° λ²„νŠΌμ„ ν΄λ¦­ν•˜λ©΄, 진행 μ„Ήμ…˜κ³Ό κ²°κ³Ό μ„Ήμ…˜μ΄ 사라지고, μžλ™μ°¨ 이름 μž…λ ₯칸이 빈 μƒνƒœλ‘œ κ²Œμž„ μ‹œμž‘ λŒ€κΈ°μƒνƒœκ°€ λœλ‹€', () => { carNameInputAndSubmit(carNamesSample); tryCountInputAndSubmit(tryCountSample); - cy.wait(tryCountSample * DELAY.TURN + DELAY.END); - cy.get(SELECTOR.RESTART_SUBMIT).click(); - cy.get(SELECTOR.PROGRESS_SECTION).should('not.exist'); - cy.get(SELECTOR.RESULT_SECTION).should('not.exist'); - cy.get(SELECTOR.CARNAME_INPUT).should('have.value', ''); + cy.wait(tryCountSample * DELAY.GAME_TURN + DELAY.GAME_END); + cy.get('#restart-button').click(); + cy.get('#progress-section').should('not.exist'); + cy.get('#result-section').should('not.exist'); + cy.get('#car-names-input').should('have.value', ''); }); });