TIL

0l0l·2021년 6월 8일
0

TIL

목록 보기
46/86

숫자야구 게임 (반복문 학습) ;네자리 숫자를 뽑아 특정 횟수 안에 숫자 맞추기
스트라이크: 숫자와 자리 모두 맞은 경우
볼: 숫자는 일치하지만 자리가 틀린 경우

1. 랜덤 함수 사용해 무작위로 숫자 네 개 뽑기

랜덤 함수 사용하기

Math.random() × 10은 '숫자 0' 이 나올 수 있기 때문에 불가하고,
'1 ≤ Math.random() × 9 + 1 < 10' 을 통해 숫자 1 ~ 9인 정수만 얻고 소숫점을 버리기 위해 Math.floor를 사용해 감싸준다.

<Math 관련 메서드>

  • Math.random() : 0 이상 1 미만의 랜덤 소숫점
  • Math.ceil() : 소숫점 올림 -> 자연수
  • Math.floor() : 소숫점 내림 -> 자연수
  • Math.round() : 소숫점 반올림 -> 자연수

랜덤으로 숫자 네 개 뽑기

여러 개의 값을 모아둘 때 사용한다는 공통점이 있으며, 차이점은

  • 배열([]): 단순히 값만 저장할 때 사용
  • 객체({}): 값에 이름을 붙여 속성으로 값을 구분할 때 사용
const answer = [];
for(let i = 0; i < 4; i++) { // 네 번 반복
  const index = Math.floor(Math.random() * numbers.length); // 0~8 정수
  answer.push(numbers[index]); // 뽑은 숫자 저장
  numbers.splice(index, 1); // 중복 방지를 위해 뽑은 숫자 제거
}

🌈splice 배열 메서드 : 배열의 특정 요소를 포함한 다른 요소들을 제거할 때 사용

✨Tip!
코드를 수정할 때 동일한 값을 가리키는 다른 코드도 수정한다면 실수 발생할 우려가 있어, 변수나 메서드를 이용해 특정 코드가 수정되면 자동으로 수정되는 것까지 고려하여 코드를 작성하도록 한다.
(위의 코드에서 9를 사용해 계속 수정하는 방식 대신 numbers.length를 사용해 알아서 numbers 배열 인덱스 감소)

2. 입력값 검증하기

(네 자리에 맞게 입력했는가, 각각 중복된 숫자 없이 입력했는가, 이전에 입력한 네 자리 숫자와 중복되지 않았는가를 확인)
보통 사용자로부터 입력받은 경우, 값의 유효성 여부를 먼저 판단!(ex. 이메일)

웹표준에 맞게 input 태그, button 태그가 있는 경우 form 태그로 감싸주고, form 태그에 이벤트 리스너를 적용시킨다.
addEventListener의 두번째 인자 자리는 함수이다!★(고차함수 참고)

$form.addEventListener('submit', (event) => {
  event.preventDefault(); // 기본 동작 막기
  // console.log(event); // event 객체 속성 확인용
});

form 태그는 button을 click하면, submit 이벤트가 발생하여 서버에게 데이터를 제공하기 위해 기본적으로 페이지가 새로고침 되는 동작이 있다.
(a 태그의 경우, 링크로 이동되는 기본 동작과 유사)
위의 경우, 이전에 설정한 변수 numbers, answer가 초기화되지 않고 상태를 유지하기 위해 event 매개변수를 사용하여 기본 동작을 막는다.

event객체내target객체

event.target[0] : input 태그 대신 사용 가능
event.target[1] : button 태그 대신 사용 가능


😈 'Uncaught TypeError: Cannot read property 'addEventListener' of null' 에러 해결방법😭

나의 경우 별도의 js 파일을 생성하여 html 파일에 연결시켜 작성하고 코드 상 아무 문제가 없었다.
위의 에러가 발생한 이유 중 가장 흔한 경우는 'html이 렌더링 되기 전에 먼저 실행'되었기 때문이다.
html이 가장 먼저 실행되도록 js 파일을 연결하는 script 태그를 body 태그 맨 하단으로 이동시켰더니 문제가 해결되었다.😁

3. 홈런인지 검사해서 표시하기

자료형을 바꿔주는 메서드 익히기!
join : 배열을 문자열로 바꾸는 메서드(인수에 합칠 조건 작성)
num1.join(); // [1, 2, 3, 4] -> "1,2,3,4"
num1.join(''); // [1, 2, 3, 4] -> "1234"
split : 문자열을 배열로 바꾸는 메서드(인수에 나눌 조건 작성)
num2.split(); // '5678' -> ["5678"]
num2.split(''); // '5678' -> ["5", "6", "7", "8"]


화면에 글자를 작성하는 방법들 중 경우에 따라 선택해서 사용한다.

《간단하게 한 줄만 표시할 때 - append 사용X》

  • textContent : 화면에 문자열만 표시할 때(문자열로만 인식)
  • innerHTML : 화면에 html코드와 문자열을 표시할 때(html코드는 태그로 인식)
$logs.textContent = '홈런!';
$logs.innerHTML = '<br/>홈런!'; // 화면에는 줄바꿈된 상태에서 문자열만 표시

이전에 작성한 글을 그대로 유지하고 다음에 작성하는 글자를 추가하고 싶을 때 사용하며, 좀 더 자바스크립트 프로그램적으로 글자를 작성하는 방법이다.

《여러 줄 표시할 때 - append 또는 appendChild 사용O》
먼저 아래의 메서드를 이용해 텍스트를 생성하고, 특정 요소(태그)의 자식 태그로 append(추가)해야만 화면에 보여준다.

  • document.createTextNode : 텍스트 노드 생성
  • document.createElement : 태그 생성(div, form, input, button 등)
$logs.append(document.createTextNode('추가할 텍스트'));
$logs.append(document.createElement('br')); // 화면에서 줄바뀜

🔆 문자열을 append를 이용해 작성할 때는 createTextNode 없이, 문자열 자체만 작성해도 추가된다.

  • append : 한번에 문자열과 태그 여러개 추가 가능 (실무에서 많이 사용)
  • appendChild : 한개만 추가 가능. 항상 createTextNode를 이용해 먼저 텍스트 노드를 생성하고 추가해야 함(옛날 방식)
$logs.append(`${value}: ${strike} strike, ${ball} ball`, document.createElement('br'));

const msg = document.createTextNode('실패! 다시 도전~');
$logs.appendChild(msg);

화면에 텍스트나 태그를 표기하는 방법!
① 'document.createElement / document.createTextNode' 로 텍스트 또는 태그 만들기
② 'append / appendChild' 로 화면에 그리기

4. 스트라이크/볼 계산하기

프로그램으로 시도나 횟수를 세는 경우라면 항상 변수를 만들어 카운팅한다.
초기값을 0으로 두고, 실행 후에 1씩 더해 카운팅하는 방식으로 작성한다.
순서도에서 판단하는 과정(if문) 이후, 과거로 돌아가는 화살표를 그린다면 코드에서 반복문★을 의미한다.

인덱스 하나씩 총 4번(네자리 숫자)을 반복하며, 각각 인덱스 값과 동일한 값이 존재하는지 비교한다.
indexOf : 배열이나 문자열을 검색할 때 사용하는 메서드이며, 특정 문자가 위치한 인덱스를 반환(존재하면 위치까지 확인 가능)

// indexOf(찾고자하는 데이터, 시작점)
const num = ['1', '2', '3', '1', '3'];
num.indexOf('1'); // 0 (맨 처음 발견한 인덱스)
num.indexOf('1', 2); // 3 (2번째 값 이후 발견한 인덱스)
num.indexOf('5'); // -1 (일치하는 값이 없음)
num.indexOf(2); // -1 (요소의 자료형까지 일치해야 함)

includes : indexOf와 같이 배열이나 문자열에 원하는 값이 있는지 확인하는 메서드로 true/false를 반환(존재 여부만 확인)

'1357'.includes(5); // true
['4', '6', '8', '9'].includes(3); // false

strike⚾ : index > -1, index 값 일치(일치하는 값이 있으며, 자리도 같다)
ball🥎 : index > -1, index 값 불일치(일치하는 값이 있으며, 자리는 다르다)

5. 배열 메서드 forEach, map, fill

for보다 성능은 낮지만 반복문 역할을 하는 배열 메서드를 연달아 사용할 때 유용하다.
(예. Array(10).fill().map((el, idx) => {});)
(for문은 연달아 사용 불가하며, 일일이 하나씩 만들고 push해서 넣어줘야 함)

forEach : 배열 각각의 요소들을 순회하며 함수를 적용하는 메서드
인수로 함수를 받고, 매개변수가 요소와 인덱스로 고정되어 있다.

const answer = [3, 5, 4, 2]; // 배열
const value = '3214'; // 문자열
for (let i = 0; i < answer.length; i++) {
  const index = value.indexOf(answer[i]);
  // 인덱스 비교 조건문...
}

// 변수.forEach((element, index) => { });
answer.forEach((a_el, a_idx) => {
  const index = value.indexOf(a_ele); // a_el === answer[a_idx]
});

map : 배열 각각의 요소를 순회하며 다른 값으로 바꿔주는 메서드(기존 배열 유지, 새로운 배열 생성)
forEach 역할을 하면서 return문을 적용한 새로운 배열을 생성한다.
return 값이 배열의 각각 요소(element)로 들어간다.
인수로 함수를 받고, 매개변수가 요소와 인덱스로 고정되어 있다.

const array = [1, 2, 3, 4];
const result = [];
for (let i = 0; i < array.length; i++) {
  result.push(array[i] * 2);
}
console.log(result); // [2, 4, 6, 8]

// 변수.map((element, index) => { });
array.map((element, index) => {
  return element * 2;
}); // [2, 4, 6, 8]
console.log(array); // [1, 2, 3, 4]

fill : 배열의 길이를 깔끔하게 만들 때 유용한 메서드

// Array(원하는 길이).fill(배열 요소로 채울 값)
Array(2).fill() // [undefined, undefined]
Array(3).fill(0) // [0, 0, 0]

// 1 ~ 9 숫자 뽑기
Array(9).fill(0).map((element, index) => {
  return index + 1; // 리턴값이 element가 됨
}); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// element는 모두 0, index는 0 ~ 8이므로 index+1한 값을 넣어줌
profile
천방지축 빙글빙글

0개의 댓글