숫자야구 프로그램 만들기

박서현·2023년 8월 15일
0
post-thumbnail

🌵문제

  • 컴퓨터는 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번만에 맞히셨습니다. 
게임을 종료합니다.



1. 입력값 받기

const readline = require("readline");
 
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});
 
rl.question("line", (line) => {
    console.log("input: ", line);
    rl.close();
});
 
rl.on('close', () => {
   process.exit();
})

1) const readline = require("readline");

  • node.js의 'readline' 모듈을 불러온다.
  • 터미널 등의 입력을 쉽게 다루기 위한 기능을 제공한다.

2) const rl = readline.createInterface({ ... })

  • readline 모듈의 createInterface 함수를 호출하여 인터페이스 객체 rl을 생성한다.
  • 입력과 출력을 관리하며, 터미널로부터 사용자 입력을 받는 역할을 한다.

3) rl.question("line", (line) => { ... });

  • rl 객체의 question 메서드를 호출하여 사용자에게 질문을 출력하고 사용자 입력을 받는다.
  • 첫 번째 매개변수인 문자열 "line"은 사용자에게 출력할 질문이다.
  • 두 번째 매개변수인 콜백 함수는 사용자 입력을 받았을 때 실행되는 함수로, 입력된 내용은 line 매개변수로 전달된다.
  • rl.close()를 호출하여 입력을 종료한다.

4) rl.on('close', () => { ... })

  • rl 객체의 on 메서드를 사용하여 'close' 이벤트를 등록한다.
  • 사용자가 입력을 종료하면 이 이벤트가 발생하며, 등록된 콜백 함수가 실행된다.
  • process.exit()를 호출하여 프로그램을 종료한다.

❓rl.question과 rl.on의 차이

rl.question

  • 사용자로부터 질문을 출력하고, 사용자의 입력을 기다리는 역할을 한다.
  • 사용자가 입력을 하고 Enter키를 누를 때까지 프로그램이 일시정지된다.
  • 사용자 입력을 받으면 콜백 함수가 실행되며, 입력된 내용을 콜백 함수의 매개변수로 전달한다.
  • 이후 프로그램은 계속 진행된다.

rl.on

  • readline 객체의 이벤트를 등록하고 해당 이벤트가 발생했을 때 실행할 동작을 설정한다.
  • 대표적으로 'close', 'line', 'SIGINT' 등의 이벤트가 있다.
  • rl.on을 사용하면 이벤트가 발생할 때마다 등록한 콜백 함수가 호출된다.

❓rl.close()와 process.exit()의 차이

rl.close()

  • readline 모듈에서 생성한 인터페이스 객체(rl)의 입력 스트림을 닫고, 프로그램의 터미널 입력을 종료한다.
  • 주로 rl.question과 함께 사용되어 사용자 입력을 처리한 후 입력을 종료할 때 호출됩니다.

process.exit()

  • Node.js 프로세스를 종료하는 함수로, 프로그램 전체를 종료한다.
  • 실행 중인 프로그램이 모든 동작을 완료하거나 강제로 종료되어야 할 때 사용된다.
  • 인자로 전달된 숫자를 통해 종료 코드를 지정할 수 있습니다. 일반적으로 0은 정상 종료를, 1은 오류가 발생한 종료를 의미한다.



2. 각 자기수의 숫자가 다른 3자리 랜덤수 만들기

let num = []
function getRandomNum() {
    while(num.length < 3) {
        const ranNum = Math.floor(Math.random() * 10);
        if (!num.includes(ranNum)) {
            num.push(ranNum)
        }
    }
    console.log("컴퓨터가 숫자를 생성하였습니다. 답을 맞춰보세요!")
}

1) Math.random()

  • 0 이상 1 미만의 난수를 만든다.

2) Math.floor()

  • 주어진 숫자를 내림하여 정수로 반환하는 함수이다.

3) includes()

  • 주어진 값이 배열에 포함되어 있는지 여부를 확인하는 함수이다.
  • 주어진값이 배열 내에 존재하면 'true'를 반환하고, 그렇지 않으면 'false'를 반환한다.

4) !

  • 논리 NOT 연산자
  • 주어진 값을 논리적으로 반대로 바꾸는 역할이다.

5) push()

  • 배열의 끝에 하나 이상의 요소를 추가하는 역할을 한다.
  • 새로운 요소가 배열의 마지막에 추가된다.



3. 각 자리 수 비교

function baseball(line) {
    let input = line.split("").map(Number);
    let countB = 0
    let countS = 0

    for(let i = 0; i < 3; i++) {
        if(num[i] === input[i]) {
            countS++
        } else {
            for(let j = 0; j < 3; j++ ){
                if(num[i] === input[j]) {
                    countB++
                }
            }
        }
    }
    console.log(`${countB}B${countS}S`)

    if(countS === 3) {
        console.log(`${count}번만에 맞히셨습니다. 
        게임을 종료합니다.`)
        rl.close();
    } else {
        getInput()
    }
}



전체 코드

const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

let count = 0
let num = []

// 각 자리수의 숫자가 다른 3자리 난수 만들기
function getRandomNum() {
    while(num.length < 3) {
        const ranNum = Math.floor(Math.random() * 10);
        if (!num.includes(ranNum)) {
            num.push(ranNum)
        }
    }
    console.log("컴퓨터가 숫자를 생성하였습니다. 답을 맞춰보세요!")
}

// 사용자 입력값 받기
function getInput() {

    //입력값 받으면 실행
    rl.question("3자리 정수를 입력해주세요", (line) => {
        count++
        console.log(`${count}번째 시도 : ${line}`)
        if(line > 99 && line < 1000 && /^\d+$/.test(line)) {
            baseball(line)
        } else { //3자리 정수가 아니라면 
            console.log("3자리 정수를 입력해주세요")
            getInput()
        }
    });
    
}

function baseball(line) {
    let input = line.split("").map(Number);
    let countB = 0
    let countS = 0

    for(let i = 0; i < 3; i++) {
        if(num[i] === input[i]) {
            countS++
        } else {
            for(let j = 0; j < 3; j++ ){
                if(num[i] === input[j]) {
                    countB++
                }
            }
        }
    }
    console.log(`${countB}B${countS}S`)

    if(countS === 3) {
        console.log(`${count}번만에 맞히셨습니다. 
        게임을 종료합니다.`)
        rl.close();
    } else {
        getInput()
    }
}

getRandomNum()
getInput()

rl.on('close', () => {
    process.exit();
})

0개의 댓글