본문 바로가기

Development/[Game] BaseBall Game

[BaseBall Game] #1. 야구 게임 만들기

728x90
반응형

야구 게임이란 랜덤 한 숫자를 맞추는 간단한 게임이다.

숫자를 맞출때 자리와 숫자가 동시에 맞으면 스트라이크, 자리는 다르지만 숫자를 맞출 때에는 로 취급한다.

 

먼저 게임의 로직은 다음과 같다.

  • 게임 시작과 함께 컴퓨터는 랜덤 한 3자리 숫자를 생성한다.
  • 플레이어는 랜덤한 숫자를 맞춘다. 이때 사용자가 숫자를 입력하면 스트라이크와 볼, 입력 횟수가 출력된다.
  • 가장 짧은 턴 안에 숫자를 맞춘다.

해당 로직은 가장 간단하게 게임을 즐길 수 있는 로직이며, 코드를 조금 더 개선하여 다음 기능을 추가한다.

  1. 게임 시작/ 재시작 버튼 추가
  2. AI와의 대결 (이때 컴퓨터는 랜덤 한 숫자를 생성하여 숫자를 맞추게 되며 틀릴 경우 해당 숫자를 배제하여 게임에 참여한다.)
  3. (2)에서의 알고리즘 구체화

해당 게임은 자바스크립트를 이용해 제작한다.

필자가 직접 코딩한다.

랜덤값 구현하기

먼저 랜덤 한 숫자를 생성해야 한다. 랜덤 값 생성에 대해서는 다음 포스팅을 참조한다.

 

[Tip] 자바스크립트 난수 생성

난수 생성 (1) : 부동소수점 Math.random() Javascript에서 난수를 생성하기 위해서는, Math.random() 함수를 사용한다. 이 함수는 0~1(1은 미포함) 구간에서 부동소수점의 난수를 생성한다. 위 코드는 실행할

udangtangtang-cording-oldcast1e.tistory.com

코드를 본다면 먼저 3개의 배열을 선언 후 첫 번째 요소의 값을 랜덤으로 선정한다.

이후 두 번째와 세 번째는 각각 앞에 있는 숫자와의 중복을 피하기 위해 dif_one()과 dif_two()함수를 이용해 중복을 없앤다.

 

랜덤 값을 저장할 배열에 중복되지 않는 숫자가 저장된다면 출력에 용이하도록 random_number 변수에 저장한다.

해당 값의 100의 자리가 0인 경우 두 자리로 출력되므로 알고리즘 확인용으로 사용하도록 하자.
<script>
        function dif_one(N1,N2){
            while(N1 == N2){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
                N2 = Math.floor(Math.random() * 10);
            }
            return N2;
        }

        function dif_two(N1,N2,N3){
            while(N3 == N1 || N3 == N2){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
                N3 = Math.floor(Math.random() * 10);
            }
            return N3;
        }
  
        /*사용자 입력값*/
        var ipt_arr = [[0],[0],[0]];
        var ipt,rep=0;

        /* 랜덤값 */
        var random_num = [[0],[0],[0]];
        random_num[0] = Math.floor(Math.random() * 10);
        random_num[1] = dif_one(random_num[0],random_num[1]);
        random_num[2] = dif_two(random_num[0],random_num[1],random_num[2]);

        var random_number = num1*100 + num2*10 + num3;
 </script>

사용자의 입력값 구현

먼저 스트라이크와 볼 값을 저장할 변수를 선언하고 초기화한다.

사용자의 입력을 저장할 배열을 선언한다. 이때 랜덤 값과 사용자 값에서 배열을 이용한 이유는 배열이 반복을 이용한 비교가 용이하기 때문이다.

<script>
   var strike_cnt = 0, ball_cnt = 0;

    /*사용자 입력값 선언: 초기 선언*/
    var ipt_arr = [[0],[0],[0]],ipt,rep=0;
    var ipt = parseInt(prompt("첫 번째 값을 입력하세요. "));

    //사용자가 입력한 값 분할
    ipt_arr[0] = parseInt(ipt / 100); //123/100 ==> 1
    ipt_arr[1] = parseInt(ipt/10%10); //123/10 ==> 12 %10 ==>2
    ipt_arr[2] = parseInt(ipt%10)	
</script>

게임 포인트 계산하기

랜덤값과 사용자의 입력값이 저장됐다면 이제 비교를 통해 게임 포인트를 계산한다.

이때 스트라이크는 인덱스가 같은 경우 요소의 값이 같다면 증가, 볼인 경우는 인덱스가 다를 때 요소의 값이 같다면 증가한다.

 

아래 코드는 반복없이 한번 출력 후 종료된다.

<script>
    while(1){
            strike_cnt = 0; ball_cnt=0;
            for(let i=0;i<3;i++) if(ipt_arr[i]==random_num[i]) strike_cnt ++;

            for(let i=0;i<3;i++){
                for(let j=0;j<3;j++){
                    if(i!=j) if(ipt_arr[i]==random_num[i]) ball_cnt ++;
                }
            }
            print(random_num[0],random_num[1],random_num[2],ipt_arr[0],ipt_arr[1],ipt_arr[2],strike_cnt,ball_cnt);
            break;
        }
</script>

다음 포스팅에서 다룰 내용은 아래와 같다.

  1. 맞출 때까지 반복 => 두 수가 같으면 break 문으로 종료.
  2. 현재 반복한 횟수 출력
  3. 시작/ 재시작 버튼 삽입
  4. 외부 파일 분리로 최적화

현재까지의 코드는 다음과 같다.

<!DOCTYPE html>
<html lang="ko">
<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>야구 게임</title>

    <style>
        body {
            text-align: center;
            font-size: 30px;
        }
    </style>

</head>
<body>
    <h1>야구 게임</h1>
    <script>

function dif_one(N1,N2){
            N2 = Math.floor(Math.random() * 10);
            while(1){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
                if(N1 != N2) break;
                else N2 = Math.floor(Math.random() * 10);
            }
            return N2;
        }

        function dif_two(N1,N2,N3){
            N3 = Math.floor(Math.random() * 10);
            while(N3 == N1 || N3 == N2){ //첫번째 난수와 두번째 난수가 다른 숫자일 때까지 반복
                N3 = Math.floor(Math.random() * 10);
            }
            return N3;
        }

        function print(R1,R2,R3,I1,I2,I3,sc,bc){
            document.write("<br><br>랜덤 숫자: "+R1+R2+R3+"<br>");
            document.write("입력한 숫자:"+I1+I2+I3+"<br><br>");

            document.write("Strike!: "+strike_cnt + "<br>");
            document.write("ball: :" + ball_cnt);
        }
        


        /* 랜덤값 */
        var random_num = [[0],[0],[0]];
        
        random_num[0] = Math.floor(Math.random() * 10);
        random_num[1] = dif_one(random_num[0],random_num[1]);
        random_num[2] = dif_two(random_num[0],random_num[1],random_num[2]);
        //랜덤 값은 생성시 계속 유지

        
        var strike_cnt = 0, ball_cnt = 0;

        /*사용자 입력값 선언: 초기 선언*/
        var ipt_arr = [[0],[0],[0]],ipt,rep=0;
        var ipt = parseInt(prompt("첫 번째 값을 입력하세요. "));
                
        //사용자가 입력한 값 분할
        ipt_arr[0] = parseInt(ipt / 100); //123/100 ==> 1
        ipt_arr[1] = parseInt(ipt/10%10); //123/10 ==> 12 %10 ==>2
        ipt_arr[2] = parseInt(ipt%10)


        while(1){
            strike_cnt = 0; ball_cnt=0;
            for(let i=0;i<3;i++) if(ipt_arr[i]==random_num[i]) strike_cnt ++;

            for(let i=0;i<3;i++){
                for(let j=0;j<3;j++){
                    if(i!=j) if(ipt_arr[i]==random_num[i]) ball_cnt ++;
                }
            }
            print(random_num[0],random_num[1],random_num[2],ipt_arr[0],ipt_arr[1],ipt_arr[2],strike_cnt,ball_cnt);

            break;
            
        }
    
    </script>

    
</body>
</html>

실행 결과


 

728x90
반응형
댓글