이번에 자바스크립트 과제로 숫자야구 프로그램 과제를 받았다. 2인 1조로 페어 프로그래밍을 진행했고, 다른 팀원분은 임의로 숫자를 뽑는 로직을 작성하는 역할을 담당하셨고, 나는 함수와 프런트를 담당했다. 챗지피티 디톡스를 하고 실력을 늘리기 위해 최대한 스스로 코드를 작성해보려 하였다.
과제 조건
컴퓨터는 0과 9 사이의 서로 다른 숫자 3개를 무작위로 뽑습니다. (ex) 123, 759
사용자는 컴퓨터가 뽑은 숫자를 맞추기 위해 시도합니다.
컴퓨터는 사용자가 입력한 세자리 숫자에 대해서, 아래의 규칙대로 스트라이크(S)와 볼(B)을 알려줍니다.
숫자의 값과 위치가 모두 일치하면 S
숫자의 값은 일치하지만 위치가 틀렸으면 B
기회는 무제한이며, 몇번의 시도 후에 맞췄는지 기록됩니다.
숫자 3개를 모두 맞춘 경우, 게임을 종료합니다.
해결방법
1. 컴퓨터가 숫자 임의로 3개 나열하게 하기(팀원)
// 1. 랜덤 숫자 3자리 만들기
// for문으로 만들기
const numbers = [];
for(let n = 1; n < 10; n++) {
numbers.push(n);
}
const answer = [];
for(let n =0; n < 3; n++) { // 3번 반복(3자리수 만들기)
const index = Math.floor(Math.random() * numbers.length); //0~9 사이 정수
answer.push(numbers[index]);
numbers.splice(index, 1);
}
console.log(answer);
- 빈 배열 'numbers'를 생성하고 1부터 9까지의 숫자를 순차적으로 추가했다.
- answer라는 빈 배열을 만들고 3번 반복해서 숫자를 선택했다.
- Math.random() 은 0 이상 1 미만의 랜덤 숫자를 생성하므로, number.length를 곱하면 ㅇ
- 위 값에는 위로 부터 0에 수렴하는 값과 아래로부터 10에 수렴하는 값이 나오게 됩니다.
- 해당 값에 반올림을 해 numbers의 배열의 원소 중에 하나를 꺼내와 사용자의 입력과 비교할 배열인 answer에 넣습니다.
- numbers.splice(index, 1); 코드는 해당 인덱스의 값을 배열에서 제거해 다시 뽑히지 않도록 만듭니다.
질문?
그러면 numbers.length 가 반복문이 돌 때마다 1씩 감소하니까 점차적으로 극단값에 있는 수들이 뽑힐 확률이 줄어들듯 싶습니다.
2. 유저의 입력값 받아와 컴퓨터의 값과 비교해 볼과 스트라이크 계산하기
//const $input = document.querySelector('#input');
//const $form = document.querySelector('#form');
let NumberTry = 0;
// 버튼 제출
document
.getElementById("submit-btn")
.addEventListener("click", UserInput);
function UserInput() {
let input = document.getElementById("user-input").value;
let ball = 0;
let strike = 0;
// 스트라이크와 볼 판단 로직
for (let i = 0; i < 3; i++) {
if (input[i] == answer[i]) {
strike++;
} else if (answer.includes(Number(input[i]))) {
ball++;
}
}
- cont $input = document.querySelector('#input) : 쿼리 실렉터를 통해 user의 인풋값을 가지고 있어요.
- 유저의 횟수를 계산해줘야 하기 때문에 전역변수로 'NumberTry' 설정
- document.getElementByID("submit-btn").addEventListener("click",UserInput) : 버튼 클릭 이벤트를 감지해서 클릭 시에 아래 UserInput 함수를 실행합니다.
- 안에서 user-input ID 태그 안의 값을 가져오기 때문에 const $input은 필요 없을거 같아요. - 그리고 함수 내에 지역변수인 볼과 스트라이크를 선언해줍니다. 이 값들은 매번 함수가 돌 때마다 초기화되어야 해요.
-그리고 함수 안에 반복문을 통해 스트라이크와 볼을 판단해줍니다.
- 자바스크립트에서는 문자열은 문자의 배열로 취급될 수 있어서, 문자열에서 특정 위치의 문자에 접근하려면 배열과 마찬가지로 인덱스를 활용할 수 있습니다.
- 그래서 사용자가 입력한 값(input)과 answer 배열의 각 원소를 첫 번째 자리부터 세 번째 자리까지 비교합니다. 맞다면 strike 카운트를 올려주고, else if 구문에서는 사용자가 입력한 값이 동일한 인덱스에는 없지만 answer의 원소 중에 하나라도 input [i] 번째 위치한 값을 가지고 있다면 볼 카운트를 늘려주는 것입니다.
2. 이 값은 docummet.innertext를 통해 전역변수인 NumberTry를 따라 span 태그 내의 값이 매번 바뀌게 됩니다.
볼 스트라이크 판별문(삼항연산자)
1. 결과 로그를 담을 ul 태그를 가져와 resultLog에 담습니다.
2. 변수 스트라이크의 값이 3인지 확인하고 맞다면, NumberTry +1 값 만에 맞췄다'를 출력합니다. 1을 더한 이유는, 해당 값은 유저가 제출 버튼을 누르기 전의 값을 가지고 있기 때문입니다. NumberTry ++ 가 삼항연산자보다 위에 있으면 1을 더하지 않아도 됩니다.