JS 야구게임 만들기

shinyeongwoon·2022년 10월 26일
0

JS

목록 보기
16/16

야구게임 만들기

  • 상대편이 숫자 1~9 중에서 중복되지 않게 4개를 고른다.

  • 총 10번의 기회가 주어지고 상대편 이 고른 숫자 4개를 맞힌다. 이때, 숫자 뿐만 아니라 숫자의 순서까지 맞혀야 한다.

  • 틀릴 때마다 힌트를 준다. 맞힌 숫 자의 개수(볼), 숫자 뿐만 아니라 순서까지 맞히면(스트라이크)

  • 예를 들어 4268이 정답이라고 할 때 플레이어가 5429라고 하면 2ball 이 라고 출력

  • 컴퓨터를 상대편으로 간주

  • 컴퓨터가 무작위로 숫자 4개를 뽑으면 사용자가 답을입력창에입력

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <form action="" id="form">
    <input type="text" id="input">
    <button>확인</button>
  </form>
  <div id="logs"></div>

</body>
</html>

숫자 뽑기

  • 먼저네개의숫자를저장할자리를마련해야함
  • 무작위로 숫자를 하나씩 뽑아 저장하는 절차를 네번반복해야함
  • 여기서 중요한 것은 무작위로 뽑지만, 중복되지 않게 뽑아야 함

무작위 숫자를 만들기

Math.random() 이용

  • 이 함수는 0이상 1미만의 수를 무작위로 생성 (숫자야구 게임에서는 1에서 9까지의 숫자 필요)
  • Math.random()에 9를 곱한 후 1을 더하면 됨
    (1 이상 10 미만의 수가 만들어지는데 이 수는 자연수가 아니라서 쓸 수 없음)
  • 숫자를 자연수로 만들려면 내림, 올림, 반올림 해야 함
    (이 경우에는 내림하면 결과로 1부터 9까지의 자연수가 나옴)
  • 자바스크립트에서 숫자의 내림: Math.floor()

어떻게 하면 중복되지 않게 뽑을까?

  • 로또의 원리를 프로그램에 구현하면 됨
  • 이 프로그램에서도 1부터 9까지의 숫자를 미리 모아 두고 하나씩 네 번 뽑으면 됨
  • 1에서 9까지의 숫자를 먼저 모아둠
    (여러 개의 값을 모아 둘 때는 배열이나 객체 사용)
  • 단순한 값들의 나열이면 배열 사용
  • 값에 이름이 붙는다면 객체 사용

HTML Tag 선택하기

const $form = document.querySelector('#form');
const $input = document.querySelector('#input');
const $logs = document.querySelector('#logs');

1 ~ 9 까지의 number 를 저장한 배열 만들기

const numbers = [];
for (let n = 0 ; n <= 9 ; n++){
  nembers.push(n);
}

1 ~ 9 까지의 수 중에서 무작위로 4개의 숫자 뽑기, 중복 없이 뽑는 방법

const answer = [];
for (let n = 1; n <=4; n++){
  const index = Math.floor(Math.random()*numbers.length);
  answer.push(numbers[index]);
  nembers.splice(index,1);
}

코드분석

  • const index = Math.floor(Math.random()*numbers.length);

0 에서 1사이의 랜덤수를 받아와서 * numbers.length를 한다.
상수 9를 사용하는 경우 밑에서 splice로 배열에서 뽑힌 숫자를 잘라내기 때문에 undefined가 나올 수 있다.

  • answer.push(numbers[index]);

뽑아낸 숫자를 인덱스로 사용하여 answer 배열에 하나씩 넣는다.

  • nembers.splice(index,1);
    뽑아낸 숫자를 numbers 배열에서 제외 시킨다.

입력창으로 숫자야구의 예측값 받기

$form.addEventListener('submit',(event)=> {
  event.preventDefault();
  const value = $input.value;
  $input.value ='';
});
  • 버튼 태그에 click 이벤트를 달지 않고, $form 태그에 submit 이벤트를 달았음
  • 보통 입력창이 있으면 폼 태그로 감싸서 submit 이벤트를 사용하는 것이 좋음
  • 위와 같이 사용 시 enter 키 입력으로 값을 받아 올 수 있음
  • event.preventDefault(); submit으로 브라우저가 새로고침 되는 현상을 방지
  • 입력을 받아오면 $input.value = ''; 를 하여 다음 입력 시 수월 하도록 변경

입력값 검증하기

  • 이 값을 checkInput 함수로 검증함
    길이가 4글자인가?
    중복된 숫자는 없는가?
    이미 시도했던 값은 아닌가?
const tries = [];
function checkInput(input){
  console.log(input);
  if(input.length != 4){
    return alert('숫자 4개를 입력하세요');
  }
  if((new Set(input).size) !== 4){
    return alert('중복되지 않게 입력해 주세요');
  }
  if(tries.includes(input)){
    return alert('이미 시도했던 값 입니다.');
  }
  return true;
}

1)

if(input.length != 4){
  return alert('숫자 4개를 입력하세요');
}   

input으로 들어온 숫자(문자열)의 길이가 4가 아니라면 알림

2)

if((new Set(input).size) !== 4){
    return alert('중복되지 않게 입력해 주세요');
}

new Set() 객체를 이용하여 중복을 검열함
Set은 중복이 허용되지 않는 자료구조

3)

if(tries.includes(input)){
  return alert('이미 시도했던 값 입니다.');
}

전에 입력된 값들은 tries 배열에 저장하여 includes로 중복 확인

홈런과 시도 횟수가 10번 인지 확인 후 게임 종료하기

$form.addEventListener('submit',(event)=> {
  event.preventDefault();
  const value = $input.value;
  $input.value ='';
  const valid = checkInput(value);
  if(!valid) return;
  if(answer.join('') === value){
    $logs.textContent = "홈런!";
    return;
  }
  if(tries.length >= 9){
    $logs.append(`패배! 정답은 ${answer.join('')}`);
    return;
  }
});

ball 과 strike 판단하기

console.log(answer);
let strike = 0;
let ball = 0;
let out = 0;    
answer.forEach(function(v,i){
  const index = value.indexOf(v);
  console.log(v);
  if(index > -1){ 
    if (index === i){
      strike += 1;
    }else{
      ball += 1;
    }
  }    
});

if(strike == 0 && ball == 0){
  out += 1;
}

$logs.append(`${value} : ${strike} 스트라이크 ${ball}${out} out`,document.createElement('br'));
tries.push(value);

value에서 answer에 값이 있는지 확인
1) 있을때
1-1 value의 index와 answer의 index가 같다
- strike count + 1
1-2 value의 index와 answer의 index가 다르다
- ball count + 1
2) 없을때
out cnt + 1

$logs.append를 통해 이전 기록을 지우지 않으면서 strike, ball, out을 표시한다.
tries에 value를 push를 통해 입력하여 다음 번 입력 시 중복 확인 값으로 사용한다.

0개의 댓글