diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..29298219 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,25 @@ +##๐Ÿ“„๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋ชฉ๋ก +###1. ์ž„์˜์˜ ์ˆซ์ž ์ƒ์„ฑ +- 1์—์„œ 9๊นŒ์ง€ ์„œ๋กœ ๋‹ค๋ฅธ ์ž„์˜์˜ ์ˆ˜ 3๊ฐœ๋ฅผ ์„ ํƒํ•œ๋‹ค. +- ์ปดํ“จํ„ฐ์˜ ๋žœ๋ค ๊ฐ’์€ ๋ฐ˜๋“œ์‹œ JavaScript์˜ Math.random ๋Œ€์‹  MissionUtils ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ Random.pickNumberInRange๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ•œ๋‹ค. + +###2. ์œ ํšจํ•œ ๊ฐ’ ์ž…๋ ฅ๋ฐ›๊ธฐ +- 1์—์„œ 9๊นŒ์ง€ ์„œ๋กœ ๋‹ค๋ฅธ ์ˆ˜ 3๊ฐœ +- ์‚ฌ์šฉ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ์ž…๋ ฅํ•œ ๊ฒฝ์šฐ alert์œผ๋กœ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ , ๋‹ค์‹œ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. + +###3. ์ •๋‹ต ๊ฒ€์‚ฌ +- ์ŠคํŠธ๋ผ์ดํฌ: ๊ฐ™์€ ์ˆ˜๊ฐ€ ๊ฐ™์€ ์ž๋ฆฌ์— ์žˆ์„ ๋•Œ +- ๋ณผ: ๊ฐ™์€ ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ์ž๋ฆฌ์— ์žˆ์„ ๋•Œ +- ๋‚ซ์‹ฑ: ๊ฐ™์€ ์ˆ˜๊ฐ€ ์ „ํ˜€ ์—†์„ ๋•Œ +- ์ •๋‹ต ์—ฌ๋ถ€ ๋ฐ”ํ™˜ + +###4. ๊ฒŒ์ž„์˜ ์ข…๋ฃŒ +- ์ž„์˜์˜ ์ˆซ์ž 3๊ฐœ๋ฅผ ๋ชจ๋‘ ๋งž์ถœ ๊ฒฝ์šฐ ๊ฒŒ์ž„ ์ข…๋ฃŒ +- ๊ฒŒ์ž„ ์ข…๋ฃŒ ์‹œ ์žฌ์‹œ์ž‘ ๋ฒ„ํŠผ ๋…ธ์ถœ + +###5. ์žฌ์‹œ์ž‘ +- ์žฌ์‹œ์ž‘ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ๊ฒŒ์ž„ ์žฌ์‹œ์ž‘ + + +###๐Ÿ“ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ +![ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ](./result.png) \ No newline at end of file diff --git a/docs/result.png b/docs/result.png new file mode 100644 index 00000000..ed4000b7 Binary files /dev/null and b/docs/result.png differ diff --git a/index.html b/index.html index c85d50be..c370d91d 100644 --- a/index.html +++ b/index.html @@ -17,11 +17,11 @@

โšพ ์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„

- +

๐Ÿ“„ ๊ฒฐ๊ณผ

-
1๋ณผ 1์ŠคํŠธ๋ผ์ดํฌ
- +
+ diff --git a/src/controller.js b/src/controller.js new file mode 100644 index 00000000..9794444a --- /dev/null +++ b/src/controller.js @@ -0,0 +1,37 @@ +import BaseballGame from './model.js'; +import InputView from './views/InputView.js' +import OutputView from './views/OutputView.js'; + +export default class BaseballController { + constructor() { + this.model = new BaseballGame(); + this.inputView = new InputView(); + this.outputView = new OutputView(); + + this.init(); + } + + init() { + this.inputView.bindSubmitEvent(this.onSubmit.bind(this)); + this.outputView.bindRestartEvent(this.onRestart.bind(this)); + } + + onSubmit(inputNumber) { + try { + this.model.checkValidity(inputNumber); + + const score = this.model.play(this.model.randomNumber, inputNumber); + this.outputView.showResult(score.ball, score.strike); + + } catch (error) { + this.outputView.showError(error.message); + this.inputView.clearInput(); + } + } + + onRestart() { + this.model.init(); + this.inputView.clearInput(); + this.outputView.clearResult(); + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 00000000..dbeede74 --- /dev/null +++ b/src/index.js @@ -0,0 +1,3 @@ +import BaseballController from './controller.js'; + +new BaseballController(); \ No newline at end of file diff --git a/src/model.js b/src/model.js new file mode 100644 index 00000000..7413a11e --- /dev/null +++ b/src/model.js @@ -0,0 +1,49 @@ +import {isDuplicate, checkValidity} from './utils/validation.js'; + +export default class BaseballGame { + constructor() { + this.randomNumber = this.getRandomNumber(); + } + + getRandomNumber() { + const tempArr = []; + + while (tempArr.length < 3) { + const tempNumber = MissionUtils.Random.pickNumberInRange(1, 9); + tempArr.push(tempNumber); + + if(isDuplicate(tempArr)) { + tempArr.pop(); + } + } + + console.log("RandomNumber: "+ tempArr) + return tempArr; + } + + checkValidity(inputNumber) { + checkValidity(inputNumber); + } + + play(randomNumber, inputNumber) { + let ball = 0, strike = 0; + + // ๋ณผ ๊ฐœ์ˆ˜ ํ™•์ธ + for (let i = 0; i < randomNumber.length; i++) { + for (let j = 0; j < inputNumber.length; j++) { + if (randomNumber[i] == inputNumber[j]) { + ball++; + } + } + } + + // ์ŠคํŠธ๋ผ์ดํฌ ๊ฐœ์ˆ˜ ํ™•์ธ + for (let i = 0; i < randomNumber.length; i++) { + if (randomNumber[i] == inputNumber[i]) { + strike++; + } + } + + return {ball, strike}; + } +} \ No newline at end of file diff --git a/src/utils/validation.js b/src/utils/validation.js new file mode 100644 index 00000000..ab3b92ee --- /dev/null +++ b/src/utils/validation.js @@ -0,0 +1,27 @@ + // ์ž…๋ ฅํ•œ ์ˆซ์ž์— ๋Œ€ํ•œ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ +export function checkValidity(inputNumber) { + // ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ + for (let i = 0; i < inputNumber.length; i++) { + if ('0' > inputNumber[i] || inputNumber[i] > '9') { + throw new Error('์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.'); + } + } + + // 3์ž๋ฆฌ๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ + if (inputNumber.length !== 3) { + throw new Error('3๊ฐœ์˜ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”.'); + } + + // ์ค‘๋ณต๋œ ์ˆ˜๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ + if (isDuplicate(inputNumber)) { + throw new Error('์ค‘๋ณต ์—†์ด ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.'); + } +} + +export function isDuplicate(arr) { + const isDup = arr.some(function(x) { + return arr.indexOf(x) !== arr.lastIndexOf(x); + }); + + return isDup; +} \ No newline at end of file diff --git a/src/views/InputView.js b/src/views/InputView.js new file mode 100644 index 00000000..bc149ac3 --- /dev/null +++ b/src/views/InputView.js @@ -0,0 +1,18 @@ +export default class InputView { + constructor() { + this.userInput = document.getElementById('user-input'); + this.submitBtn = document.getElementById('submit'); + } + + bindSubmitEvent(handler) { + this.submitBtn.addEventListener('click', (event) => { + event.preventDefault(); + const inputNumber = this.userInput.value.split(""); + handler(inputNumber); + } + );} + + clearInput() { + this.userInput.value = ""; + } +} \ No newline at end of file diff --git a/src/views/OutputView.js b/src/views/OutputView.js new file mode 100644 index 00000000..06bb7684 --- /dev/null +++ b/src/views/OutputView.js @@ -0,0 +1,51 @@ +export default class OutputView { + constructor() { + this.result = document.getElementById('result'); + this.restartBtn = document.getElementById('game-restart-button'); + + this.restartBtn.style.display = "none"; + } + + // ์ •๋‹ต ์ถœ๋ ฅ + showResult(ball, strike) { + if (ball == 3 && strike == 3) { + this.restartBtn.style.display = "block"; + this.result.innerHTML = "

๐ŸŽ‰์ •๋‹ต์„ ๋งž์ถ”์…จ์Šต๋‹ˆ๋‹ค๐ŸŽ‰


๊ฒŒ์ž„์„ ์ƒˆ๋กœ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?

"; + return; + } + + if (ball == 0 && strike == 0) { + this.result.innerHTML = "๋‚ซ์‹ฑ"; + return; + } + + if ((ball == 0 || ball - strike == 0) && strike != 0) { + this.result.innerHTML = strike + "์ŠคํŠธ๋ผ์ดํฌ"; + return; + } + + if (ball != 0 && strike == 0) { + this.result.innerHTML = ball + "๋ณผ"; + return; + } + + this.result.innerHTML = ball - strike + "๋ณผ " + strike + "์ŠคํŠธ๋ผ์ดํฌ"; + return; + } + + showError(errorMessage) { + alert(errorMessage); + } + + clearResult() { + this.result.innerHTML = ""; + this.restartBtn.style.display = "none"; + } + + // ์žฌ์‹œ์ž‘ ๋ฒ„ํŠผ ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฐ”์ธ๋”ฉ + bindRestartEvent(handler) { + this.restartBtn.addEventListener("click", () => { + handler(); + }); + } +} \ No newline at end of file