Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
##📄구현 기능 목록
###1. 임의의 숫자 생성
- 1에서 9까지 서로 다른 임의의 수 3개를 선택한다.
- 컴퓨터의 랜덤 값은 반드시 JavaScript의 Math.random 대신 MissionUtils 라이브러리의 Random.pickNumberInRange를 사용해 구한다.

###2. 유효한 값 입력받기
- 1에서 9까지 서로 다른 수 3개
- 사용자가 잘못된 값을 입력한 경우 alert으로 에러 메시지를 보여주고, 다시 입력할 수 있게 한다.

###3. 정답 검사
- 스트라이크: 같은 수가 같은 자리에 있을 때
- 볼: 같은 수가 다른 자리에 있을 때
- 낫싱: 같은 수가 전혀 없을 때
- 정답 여부 바환

###4. 게임의 종료
- 임의의 숫자 3개를 모두 맞출 경우 게임 종료
- 게임 종료 시 재시작 버튼 노출

###5. 재시작
- 재시작 버튼 클릭 시 게임 재시작


###📝테스트 결과
Comment on lines +1 to +24
![테스트 결과](./result.png)
Binary file added docs/result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ <h1>⚾ 숫자 야구 게임</h1>
</p>
<form>
<input type="text" id="user-input" />
<button id="submit">확인</button>
<button id="submit" type="button">확인</button>
</form>
<h3>📄 결과</h3>
<div id="result">1볼 1스트라이크</div>
<button id="game-restart-button">재시작</button>
<div id="result"></div>
<button id="game-restart-button">게임 재시작</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/@woowacourse/mission-utils@1.0.1/dist/mission-utils.min.js"></script>
<script type="module" src="src/index.js"></script>
Expand Down
37 changes: 37 additions & 0 deletions src/controller.js
Original file line number Diff line number Diff line change
@@ -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();
}
Comment on lines +32 to +36
}
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import BaseballController from './controller.js';

new BaseballController();
49 changes: 49 additions & 0 deletions src/model.js
Original file line number Diff line number Diff line change
@@ -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);
}
Comment on lines +1 to +26

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};
}
}
27 changes: 27 additions & 0 deletions src/utils/validation.js
Original file line number Diff line number Diff line change
@@ -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('숫자를 입력해 주세요.');
Comment on lines +3 to +6
}
}

// 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;
}
18 changes: 18 additions & 0 deletions src/views/InputView.js
Original file line number Diff line number Diff line change
@@ -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 = "";
}
}
51 changes: 51 additions & 0 deletions src/views/OutputView.js
Original file line number Diff line number Diff line change
@@ -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 = "<h4>🎉정답을 맞추셨습니다🎉</h4><br><div>게임을 새로 하시겠습니까?</div><br>";
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();
});
}
}
Loading