⛵ 항해99/TIL · WIL ✏️

[TIL] 2023.08.16 - 숫자 야구 프로그램 / Math.random() /문자열 변경(숫자 + '') / 문자열 인덱스 접근 / includes()

hhhhy 2023. 8. 16. 19:47

 [팀과제] 숫자 야구 프로그램 만들기 

팀으로 진행된 숫자야구 프로그램 만들기 과제! 같이 풀었다기보다는 팀장님의 주도로 한 줄 한 줄 이해하면서 작성을 해나갔다. 덕분에 코드의 흐름을 이해하는데 큰 도움이 됐지만, 혼자서 작성하기엔 아직 무리가 있어 코드에 주석을 달아보면서 다시 읽어봤다. 언젠가는 혼자서도 술술 풀 수 있기를 ㅎㅎ😅
<과제 조건>
1) 컴퓨터는 0과 9 사이의 서로 다른 숫자 3개를 무작위로 뽑습니다. (ex) 123, 759
2) 사용자는 컴퓨터가 뽑은 숫자를 맞추기 위해 시도합니다.
3) 컴퓨터는 사용자가 입력한 세자리 숫자에 대해서, 아래의 규칙대로 스트라이크(S)와 볼(B)을 알려줍니다.    - 숫자의 값과 위치가 모두 일치하면 S    - 숫자의 값은 일치하지만 위치가 틀렸으면 B
4) 기회는 무제한이며, 몇 번의 시도 후에 맞췄는지 기록됩니다.
5) 숫자 3개를 모두 맞춘 경우, 게임을 종료합니다.

 

  • 알게 된 것
📍 Math.random()
- 0 이상 1 미만의 구간에서 부동소숫점 의사난수를 반환함

# 예시
let ranNum = Math.random();
console.log(ranNum)
// 0 이상 1 미만의 부동소숫점 의사 난수로, 찍을때 마다 값이 다름 (0.987654.. 등등)

# 참고
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Math/random


📍 숫자 + '' : 문자열로 변경
- 숫자에 빈 문자열("")을 연결하면 숫자가 문자로 변경됨

# 예시
let a = 123 + '';
console.log(a)  // 123
console.log(typeof a)  // string

# 참고
https://hianna.tistory.com/491


📍 문자열 인덱스 접근
- JavaScript에서 문자열은 문자의 배열로 취급되기 때문에, 문자열[index]와 같은 방식으로 특정 위치에 있는 문자에 접근할 수 있음
- 문자열은 불변(immutable)하기 때문에 특정 인덱스에 접근해서 값을 변경하는 것은 불가능

# 예시
const str = "Hello";
console.log(str[0]);  // H
console.log(str[2]);  // l


📍 includes()
- 배열이 특정 요소를 포함하고 있는지 판별
- . 앞이 큰 범위가 들어가고 () 안에 확인할 특정 요소 넣으면 됨

# 예시
[1, 2, 3].includes(2); // true
[1, 2, 3].includes(4); // false


# 참고
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/includes

 

  • 완성 코드
더보기
// 터미널에서 입력받기 위해 내장 모듈인 readline 가져오기
const readline = require("readline");

// readline 인터페이스를 생성 => 이를 통해 터미널에서 입력을 받고 출력할 수 있음
const rl = readline.createInterface({
	input: process.stdin,  // 입력은 표준 입력으로 설정
    output: process.stdout  // 출력은 표준 출력으로 설정
});

let count = 0;  // 시도 횟수를 나타내는 변수를 초기화
let random_num = '';  // 컴퓨터가 생성한 랜덤한 숫자를 담을 변수를 초기화

// 1. 랜덤 숫자 생성하기
for(let i = 0; i < 3; i++) {  // 3개의 서로 다른 숫자로 이루어진 랜덤한 숫자를 생성하기
    let ran = Math.floor(Math.random() * 10) + '';  // 0부터 9까지의 랜덤한 정수를 생성하고 문자로 변환하기

    if(random_num[0] === '0') {  // random_num의 0번째(=첫번째) 숫자가 0이 나오면,
        i--;  // 현재 반복을 다시 실행하기 위해 i를 감소시킴
    } else if(random_num.includes(ran)) {  // 0번째 숫자가 0이 아니지만, 이미 생성된 숫자와 중복된 경우가 있으면,
        i--;  // 현재 반복을 다시 실행하기 위해 i를 감소시킴
    } else {  // 위 두가지 상황이 아니라면,
        random_num += ran;  // 생성된 랜덤 숫자(ran)를 변수 random_num에 추가해줘
    }
}
console.log(random_num);  // 생성된 랜덤 숫자 출력하기


console.log('컴퓨터가 숫자를 생성하였습니다. 답을 맞춰보세요!');


// rl.on("line", function (line) { ... }): 이 코드는 rl 변수에 line 이벤트 리스너를 등록
// 이 리스너는 사용자가 터미널에서 한 줄을 입력하고 엔터 키를 눌렀을 때 발생
// 사용자 입력은 line 매개변수를 통해 전달되며, 이후 리스너 함수 내부에서 사용자 입력을 처리

rl.on("line", function (line) { // line : 한 줄을 키보드로 입력받기 (여러줄을 입력받으려면 반복문)
    count++;  // 입력이 되면, 바로 시도한 횟수가 증가함
    console.log(`${count}번째 시도 : ${line}`);  // 시도 횟수(count)와 상용자 입력 내용(line)을 가져와서 찍어줌

    let ball = 0;  // B 개수 초기화
    let strike = 0;  // S 개수 초기화
    let result = '';  // 결과 나타낼 문자열 초기화
    
    // 인덱스 번호(위치)가 같고 값도 같으면 => 스트라이크, 인덱스 번호(위치)가 다르지만 같은 값이 있다면(includes()) => 볼 
    for(let i = 0 ; i < line.length; i++) {  // 사용자 입력값의 길이만큼 도는 반복문
        if(line[i] === random_num[i]) {  // 사용자 입력값의 i번째와 랜덤숫자의 i번째가 같으면,
            strike++;  // S를 1 증가시킴
        } else if(random_num.includes(line[i])) {  // 만약 랜덤숫자 중에 사용자 입력값의 i번째와 중복인게 있으면,
            ball++;  // B를 1 증가시킴
        }
    }

    // 볼과 스트라이크 개수에 따라 결과 문자열 다르게 출력하기
    if(ball === 0 && strike === 0) {  // 볼도 없고, 스트라이크도 없으면
        result += `${ball}B${strike}S`;  // result에 볼 값과 스트라이크 값 넣기 => 0B0S
    }
    if(ball !== 0) {  // 볼만 있는 경우
        result += `${ball}B`  // result에 볼 값 넣기 => 1B
    }
    if(strike !==0) {  // 스트라이크만 있는 경우
        result += `${strike}S`  // result에 스트라이크 값 넣기 => 1S
    }
    console.log(result);


    if(result === '3S') {  // 3S(=정답)인 경우,
        rl.close();  // readline 인터페이스를 닫아 입력을 종료함
    }


    // .on("close", function () { ... })는 readline 인터페이스에서 "close" 이벤트가 발생했을 때 실행할 함수를 등록하는 역할을 함
}).on("close", function () { // 입력 종료 후 실행되는 코드
    console.log(`${count}번만에 맞히셨습니다.`);  // 시도횟수 넣어서 시도결과 출력
    console.log('게임을 종료합니다.');
    process.exit();  //이 부분은 Node.js 프로세스를 종료하는 명령어
});