공부/JavaScript

1주차 팀과제(야구게임)

뀨뿌뀨뿌 2023. 6. 13. 20:54

Q.  숫자야구 프로그램 만들기

컴퓨터는 0과 9 사이의 서로 다른 숫자 3개를 무작위로 뽑습니다. (ex) 123, 759
사용자는 컴퓨터가 뽑은 숫자를 맞추기 위해 시도합니다.
컴퓨터는 사용자가 입력한 세자리 숫자에 대해서, 아래의 규칙대로 스트라이크(S)와 볼(B)를 알려줍니다.

◾ 숫자의 값과 위치가 모두 일치하면 S

 숫자의 값은 일치하지만 위치가 틀렸으면 B

 

기회는 무제한이며, 몇번의 시도 후에 맞췄는지 기록됩니다.

숫자 3개를 모두 맞춘 경우, 게임을 종료합니다.

❗입출력 예
컴퓨터가 숫자를 생성하였습니다. 답을 맞춰보세요!
1번째 시도 : 134
0B0S
2번째 시도 : 238
1B1S
3번째 시도 : 820
2B1S
4번째 시도 : 028
3B
5번째 시도 : 280
3S
4번만에 맞히셨습니다. 
게임을 종료합니다.

 

😀 내가 푼 답

ⅰ. 컴퓨터가 무작위로 뽑아주는 함수를 생성

const randomNum = () => {
  let numbers = [];
  while (numbers.length < 3) {
  // Math.random()은 0 ~ 1사이의 값을 랜덤하게 반환하므로 10을 곱하면
  // 0 ~ 9까지의 숫자를 랜덤하게 반환받을수 있음
  // 정수로 반환받아야 하므로 Math.floor()를 사용하여 정수를 반환받음
    const randomNumber = Math.floor(Math.random() * 10);
    
  // 3자리의 숫자가 모두 달라야하기 하므로
  // includes를 사용하여 동일한 숫자가 있는지 확인 후 동일하지 않으면
  // 배열에 추가 합니다.
    if (!numbers.includes(randomNumber)) {
      numbers.push(randomNumber);
    }
  }
  // 입력받은 내용은 문자열로 들어오기 때문에 join("")을 사용하여 문자열로 반환
  return numbers.join("");
};

ⅱ. 사용자가 입력한 값이 3자리 숫자인지 확인

사용자에게 입력받은 값이 3자리 숫자인지 확인할때 정규식을 사용하여 확인을 하고 싶지만
아직까지 정규식에 대한 개념이 명확하게 잡히지 않은 상태여서 정규식에 대해서 알아 보았습니다.

❓ 정규표현식이란?
◾ 정규표현식이란 특정 패턴의 문자열을 찾기 위한 표현 방식(형식 언어, formal languange라고 함)
정규표현식을 이용하면, 특정 패턴에 매칭되는 문자열을 쉽게 찾아낼 수 있음!
정규표현식 형식
   /패턴/플래그
  슬래시(/) 사이에는 매칭시킬 패턴을 작성
  슬래시(/) 다음에는 옵션을 설정하는 플래그를 작성 
  ❓ 플래그란? 하나만 찾을지, 모두 다 찾을지 등을 설정하는 옵션이라고 생각하기!!
정규표현식 매칭 패턴(문자, 숫자, 기호등)
   ✔ a-z A-Z - 영어알페벳(-로 범위 지정)
   ✔ ㄱ-ㅎ 가-힣 - 한글 문자(-로 범위 지정)
   ✔ 0-9 - 슷자(-로 범위지정)
   ✔ . - 모든 문자열(숫자, 한글, 영어, 특수기호, 공백
   ✔ \d - 숫자
   ✔ \D - 숫자가 아닌것
   ✔ \w - 영어 알파벳, 숫자, 언더스코어(_)
   ✔ \W - \w가 아닌 것
   ✔ \s - space 공백
   ✔ \S - space 공백이 아닌 것
   ✔ \특수기호 - 특수기호

// 정규표현식을 사용하여 만든 유효성 검사 함수
const isTrueNum = (guess) => {
  // 3자리 숫자인지 정규식으로 확인하기
  // ^ - 패턴의 시작을 나타내며, 문자열의 처음을 의미함
  // \d{3} - '\d'는 숫자(digit)를 의미하며, `{3}`은 앞의 패턴이 3번 반복됨을 나타냄 = 세자리 숫자
  // $ - 패턴의 끝을 나타내며, 문자열의 끝을 의미
  // test 메서드는 주어진 문자열이 정규식 패턴과 일치하는지 검사고 일치하면, true를 반환
  // 그렇지 않으면 false를 반환
  
  return /^\d{3}$/.test(guess);
};

ⅲ. 스트라이크와 볼 일치 함수 생성하기

const strikeOrBall = (guess) => {
  let strikes = 0;
  let balls = 0;

  for (let i = 0; i < guess.length; i++) {
    if (guess[i] === computerNum[i]) {
      strikes++;
    } else if (computerNum.includes(Number(guess[i]))) {
    // 같은 위치가 아닌 같은 값을 포함하고 있는지 검사하는 조건식을 작성!!
      balls++;
    }
  }
  return { B: balls, S: strikes };
};

ⅳ. 사용자 입력 횟수와 컴퓨터 임의 생성 숫자 변수 선언하기

// 사용자 입력 횟수
let count = 0;

// 컴퓨터 임의 생성 숫자
let computerNum = randomNum();

ⅴ. 게임 시작하기

사용자가 컴퓨터가 임의로 정한 숫자를 맞추는 동안 코드를 반복해야 하므로 while문을 사용하여 작성

// 게임 시작하기
while (true) {
  count++;

  // 입력 받기
  const guess = prompt(`${count}번째 시도!`);

  // 유효성 검사하기
  if (isTrueNum(guess)) {
    // 스트라이크, 볼 확인
    const result = strikeOrBall(guess);

    console.log(`${result.B}B${result.S}S`);

    // 게임 종료
    if (result.S === 3) {
      console.log(`게임을 종료합니다. ${count}번만에 맞히셨습니다.`);
      break;
    }
  } else {
    console.log("잘못된 입력입니다. 다시 시도해주세요.");
  }
}

😢 발생한 오류

처음에 하나하나 console에 찍어가면서 작업을 하였을때는 오류가 나지 않다가 게임 시작하기 반복문을 작성하는 순간 오류가 발생하기 시작(vscode내부에서)

ReferenceError: prompt is not defined

window.prompt()는 사용자에게 일부 텍스트를 입력하고 사용자가 텍스트를 제출하거나 대화 상자를 취소할 때까지 기다리라는 선택적 선택적 메시지가 있는 대화상자를 표시하도록 브라우저에게 지시
단, 노드 환경에서는 프롬프트와 윈도우가 정의되어 있지 않음!!!!!!
이러한 유형의 환경에서 이러한 유형의 프로그램을 실행할고 할 때마다 이 참조유형 오류가 발생하게 됨!
가장 효과적인 해결방법은 prompt-sync를 설치하는것!!
설치하여 const prompt = require("prompt-sync")를 선언하고 사용하는 방법이 있음

하지만 나는 npm 라이브러리를 설치하지 않고 브라우저에서 실행해서 해결을 함
크롬 개발자도구에서 위에 코드를 작성하니 원할하게 작동이 되었습니다!