-
Notifications
You must be signed in to change notification settings - Fork 9
정용준 #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
정용준 #2
Changes from all commits
854ff0e
b0b7cc3
4279b4e
e2699de
97cd89b
d7b75c5
24aec7e
0a9cbda
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| // Controller | ||
| export default class BaseballGame { | ||
| #DIGIT_LENGTH = 3; | ||
| #referee; | ||
|
|
||
| constructor(referee) { | ||
| this.#referee = referee; | ||
| } | ||
|
|
||
| play(computerInputNumbers, userInputNumbers) { | ||
| const isValidInput = | ||
| this.#validateInputNumbers(computerInputNumbers) && | ||
| this.#validateInputNumbers(userInputNumbers); | ||
| if (!isValidInput) return ""; | ||
|
|
||
| const judgement = this.#judge(computerInputNumbers, userInputNumbers); | ||
| const result = this.#formatResult(judgement); | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| // TODO: 널 오브젝트 패턴?? Judgeable을 validate하는 서비스로 추출 | ||
| #validateInputNumbers(inputNumbers) { | ||
| const inputStr = String(inputNumbers); | ||
| if (!this.#validateCorrectLength(inputStr)) return false; | ||
| if (!this.#validateAllDigit(inputStr)) return false; | ||
| if (!this.#validateDuplication(inputStr)) return false; | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| #validateCorrectLength(input) { | ||
| return input.length === this.#DIGIT_LENGTH; | ||
| } | ||
|
|
||
| #validateAllDigit(input) { | ||
| return /^\d+$/.test(input); | ||
| } | ||
|
|
||
| #validateDuplication(input) { | ||
| return new Set(input).size === inputStr.length; | ||
| } | ||
|
|
||
| // TODO: Judgeable 객체를 두 개를 비즈니스 로직에 따라 처리하는 Referee 서비스로 추출 | ||
| #judge(computerInputNumbers, userInputNumbers) { | ||
| const set = new Set(); | ||
| let strike = 0; | ||
| let ball = 0; | ||
| const computerInputDigits = Array.from( | ||
| String(computerInputNumbers), | ||
| Number | ||
| ); | ||
| const userInputDigits = Array.from(String(userInputNumbers), Number); | ||
|
|
||
| for (let i = 0; i < computerInputDigits.length; i++) { | ||
| if (computerInputDigits[i] === userInputDigits[i]) { | ||
| strike += 1; | ||
| continue; | ||
| } | ||
| set.add(computerInputDigits[i]); | ||
| } | ||
|
|
||
| for (const userInputDigit of userInputDigits) { | ||
| if (set.has(userInputDigit)) ball += 1; | ||
| } | ||
|
|
||
| return { strike, ball }; | ||
| } | ||
|
|
||
| // TODO: VO 객체(Judge) 내의 로직으로 분리 | ||
| #formatResult({ strike, ball }) { | ||
| if (strike === 0 && ball === 0) return "낫싱"; | ||
| if (strike === this.#DIGIT_LENGTH) return "정답을 맞추셨습니다!"; | ||
| if (strike === 0) return `${ball}볼`; | ||
| if (ball === 0) return `${strike}스트라이크`; | ||
| return `${ball}볼 ${strike}스트라이크`; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,76 @@ | ||
| export default function BaseballGame() { | ||
| this.play = function (computerInputNumbers, userInputNumbers) { | ||
| return "결과 값 String"; | ||
| }; | ||
| } | ||
|
|
||
| // export default class BaseballGame { | ||
| // play(computerInputNumbers, userInputNumbers) { | ||
| // return "결과 값 String"; | ||
| // } | ||
| // } | ||
|
|
||
| new BaseballGame(); | ||
| import BaseballGame from "/src/BaseballGame.js"; | ||
| import { | ||
| convertDigitArrayToInt, | ||
| generateNonDuplicateRandomIntArray, | ||
| } from "/src/utils.js"; | ||
|
|
||
| const generateComputerInputNumbers = () => | ||
| convertDigitArrayToInt( | ||
| generateNonDuplicateRandomIntArray({ | ||
| arraylength: 3, | ||
| digitCount: 1, | ||
| }) | ||
| ); | ||
|
|
||
| const userInputEl = document.querySelector("#user-input"); | ||
| const submitBtnEl = document.querySelector("#submit"); | ||
| const resultEl = document.querySelector("#result"); | ||
|
|
||
| const baseballGame = new BaseballGame(); | ||
| let computerInputNumbers = generateComputerInputNumbers(); | ||
|
|
||
| const resetUserInput = () => { | ||
| userInputEl.disabled = false; | ||
| userInputEl.value = null; | ||
| userInputEl.focus(); | ||
| }; | ||
|
|
||
| const resetResultEl = () => { | ||
| resultEl.innerHTML = ""; | ||
| }; | ||
|
|
||
| const showWinningResult = () => { | ||
| const strongEl = document.createElement("strong"); | ||
| strongEl.textContent = result; | ||
| resultEl.textContent = ""; | ||
| resultEl.appendChild(strongEl); | ||
|
|
||
| const restartMention = document.createElement("span"); | ||
| restartMention.textContent = "게임을 새로 시작하시겠습니까?"; | ||
|
|
||
| const restartButtonEl = document.createElement("button"); | ||
| restartButtonEl.textContent = "게임 재시작"; | ||
| restartButtonEl.addEventListener("click", handleRestart); | ||
|
|
||
| const restartWrapper = document.createElement("div"); | ||
| restartWrapper.appendChild(restartMention); | ||
| restartWrapper.appendChild(restartButtonEl); | ||
|
|
||
| resultEl.appendChild(restartWrapper); | ||
| }; | ||
|
|
||
| const handleRestart = (e) => { | ||
| resetUserInput(); | ||
| resetResultEl(); | ||
| computerInputNumbers = generateComputerInputNumbers(); | ||
| }; | ||
|
|
||
| const handleSubmit = (e) => { | ||
| const userInputNumbers = Number(userInputEl?.value); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| const result = baseballGame.play(computerInputNumbers, userInputNumbers); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| if (!result) { | ||
| alert("유효하지 않은 입력입니다."); | ||
| userInputEl.focus(); | ||
| return; | ||
| } | ||
| if (result === "정답을 맞추셨습니다!") { | ||
| userInputEl.disabled = true; | ||
| showWinningResult(); | ||
| return; | ||
| } | ||
|
|
||
| resultEl.textContent = result; | ||
| }; | ||
|
|
||
| submitBtnEl.addEventListener("click", handleSubmit); | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. form을 사용하도록 변경해서 여기도 |
||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 깔끔하네요 👍 👍 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| export const convertDigitArrayToInt = (digitArr) => parseInt(digitArr.join("")); | ||
|
|
||
| export const generateRandomInt = (length = 1) => { | ||
| const min = 10 ** (length - 1); | ||
| const max = 10 ** length; | ||
|
|
||
| return Math.floor(Math.random() * (max - min)) + min; | ||
| }; | ||
|
|
||
| export const generateFixedSizeSet = (generateValue, { size = 1 }) => { | ||
| const set = new Set(); | ||
| while (set.size < size) { | ||
| const value = generateValue(); | ||
| set.add(value); | ||
| } | ||
| return set; | ||
| }; | ||
|
|
||
| export const generateNonDuplicateRandomIntArray = ({ | ||
| arraylength, | ||
| digitCount = 1, | ||
| }) => | ||
| Array.from( | ||
| generateFixedSizeSet(() => generateRandomInt(digitCount), { | ||
| size: arraylength, | ||
| }) | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 👍 👍