이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌8 - JavaScript - 2년 전 등록 / 일 년 전 수정

야구게임 만들기(2)

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
var list = [0,1,2,3,4,5,6,7,8,9];
var number = [];
for (var i = 0; i < 4; i++) {
  var select = Math.floor(Math.random() * list.length);
  number[i] = list.splice(select, 1)[0];
}

지난 시간의 코드입니다. 현재 number 변수에는 네 자리 숫자의 배열이 저장되어 있습니다.

이제 공격자의 숫자를 받아야겠죠? 입력을 받는 함수는 prompt입니다. alert와 친구에요. prompt("숫자를 입력하세요"); 를 콘솔에 쳐보세요. 창이 뜨죠? 거기에 글자를 치면 그 값이 그대로 변수로 전달됩니다. 

이제 열 번 반복적으로 숫자를 받을 것이기 때문에 반복문을 만듭니다. 그 전에 10번의 숫자를 셀 count 변수와, 스트라이크, 볼을 기록할 strike, ball 변수를 만들어줍니다. 반복문에는 이미 i 변수가 사용됐기 때문에 알파벳순서대로 j, k를 사용합니다.

var count = 0;
var strike = 0;
var ball = 0;
while (count < 10) {
  // 숫자를 입력받고 비교를 준비하는 부분
  var input = prompt('숫자를 입력하세요'); // 숫자를 받는 부분
  var inputArray = input.split(''); // split함수는 아래에 설명
  strike = 0; // strike와 ball의 개수를 초기화
  ball = 0;
  count++; // 시도 횟수는 하나 증가
  // 입력받은 숫자를 비교분석하는 부분
  for (var j = 0; j < 4; j++) {
    for (var k = 0; k < 4; k++) {
      if (number[j] == inputArray[k]) {
        if (j === k) {
          strike++;
        } else {
          ball++;
        }
        break;
      }
    }
  }
  // 결과를 표시하는 부분 console객체는 밑에 설명
  if (strike === 4) {
    console.log('홈런!!! ' + (count - 1) + '번 만에 맞추셨습니다');
    break;
  } else if (count >= 10) {
    console.error('시도 횟수를 초과하셨습니다.');
  } else {
    console.info(inputArray.join('') + ': ' + strike + '스트라이크 ' + ball + '볼');
  }
}

차근차근 알아보죠. 일단 count는 0부터 9까지 시작합니다. 몇 번 만에 맞췄나를 보여줍니다. while 문을 쓰는 이유는 몇 번만에 맞출지(몇 번 반복될 지) 모르기 때문에 for 대신 while을 썼습니다.

반복문 안의 var input = prompt('숫자를 입력하세요');에서 입력된 숫자(숫자를 입력했지만 prompt는 문자열로 입력됩니다. 즉, 1234가 아니라 '1234'로 입력됩니다.)를 input변수에 저장하고, var inputArray = input.split(''); 에서 아까 input변수를 한 글자씩 따로 나눕니다.

새로운 함수인데요. 문자열.split(구분자) 함수가 바로 문자열을 쪼개서 배열로 만드는 역할을 합니다. 구분자가 ''(작은따옴표 두개)인데 그냥 한 글자씩 따로 떨어뜨리라는 겁니다. 따라서 '1234'.split('') == ['1','2','3','4']가 됩니다.

이제 수비자가 만든 네 자리 숫자와 공격자가 입력한 네 자리 숫자를 비교해야겠죠? for문이 두 번 중복된 곳이 바로 그 역할입니다.

for (var j = 0; j < 4; j++) {
  for (var k = 0; k < 4; k++) {
    if (number[j] == inputArray[k]) {
      if (j === k) {
        strike++;
      } else {
        ball++;
      }
      break;
    }
  }
}

복잡해보일 수도 있지만 차근차근 보면 number[0]inputArray[0]을 비교하고, number[0]inputArray[1]을 비교하고, number[0]inputArray[2], ... , number[3]inputArray[3]을 비교하는 것을 알 수 있습니다.

그리고 number[k] == inputArray[j]일 때 (여기서 === 대신 ==을 썼습니다. 왜냐하면 number[j]는 숫자고 inputArray[k]는 문자열이기 때문에 자료형을 제외하고 값만 비교합니다.) 만약, j === k면 자리수도 같은 것이기 때문에 스트라이크가 됩니다. 다르다면 자리수는 같지 않고 값만 같은 것이기 때문에 볼이 되고요.

헷갈린다면 네 자리수 배열 두 개를 직접 만든 뒤에 반복적으로 계산해보세요. 마지막 break;number[j]inputArray[k]가 같을 경우 다음 자리로 넘어가기 위해 중복문을 하나 break하는겁니다. break는 모든 중복문을 멈추는 게 아니라 가장 가까운 하나만 멈춥니다. 물론 break를 생략해도 정상 작동하지만, 불필요한 비교를 그만두고 바로 다음 것으로 넘어가라고 알려주는 겁니다. 프로그래밍에서 효율과 성능은 중요하니까요.

if (strike === 4) {
  console.log('홈런!!! ' + (count - 1) + '번 만에 맞추셨습니다');
  break;
} else if (count >= 10) {
  console.error('시도 횟수를 초과하셨습니다.');
} else {
  console.info(inputArray.join('') + ': ' + strike + '스트라이크 ' + ball + '볼');
}

결국 반복문을 돌면서 자동으로 비교해 strike와 ball이 ++되고, 결과만 표시해주면 됩니다. 결과 부분은 쉽죠? 근데 console객체를 처음 보셨을 겁니다. console객체는 우리가 실습할 때 썼던 브라우저의 F12 콘솔의 그 콘솔입니다. console.log(내용), console.info(내용), console.error(내용), console.warn(내용) 등이 있는데 각각 일반기록, 정보, 에러, 경고를 나타냅니다. 콘솔에 한 번 쳐보세요.

결과를 출력하는 부분 '홈런!!! ' + count + '번 만에 맞추셨습니다'를 보면 문자열에 count를 더합니다. 좀 이상하죠? 이게 문자열의 연결 방법입니다. 숫자는 + 하면 더해지지만, 문자열은 +하면 두 개의 문자열이 합쳐집니다. 숫자나 다른 것들도 강제로 문자열로 변경되어 합쳐집니다.

만약 count가 5라고 하면 홈런!!! 5번 만에 맞추셨습니다.가 됩니다. 숫자 5가 강제로 문자열 '5'로 바뀌어서 문자열끼리 더해지는 겁니다. 문자열에 더하는 것은 모두가 강제로 문자열이 된다는 것을 기억하세요!

마지막에 inputArray.join('')도 있는데 배열.join(구분자)는 배열을 합쳐서 문자열로 만드는데 배열의 아이템 사이에 구분자를 넣으란겁니다. 여기서 ''는 구분자 없이 그냥 합치라는 뜻입니다. [1,2,3,4].join('')=='1234'가 되고, [1,2,3,4].join(':')=='1:2:3:4'가 됩니다.

마지막은 처음부터 끝까지 완성 코드입니다. 실행 결과도 보여드릴게요.

저보다 더 빨리 맞춰보세요! ㅎㅎ

var list = [0,1,2,3,4,5,6,7,8,9];
var number = [];
for (var i = 0; i < 4; i++) {
  var select = Math.floor(Math.random() * list.length);
  number[i] = list.splice(select, 1)[0];
}
var count = 1;
var strike = 0;
var ball = 0;
while (count <= 10) {
  var input = prompt('숫자를 입력하세요');
  var inputArray = input.split('');
  strike = 0;
  ball = 0;
  count++;
  for (var j = 0; j < 4; j++) {
    for (var k = 0; k < 4; k++) {
      if (number[j] == inputArray[k]) {
        if (j === k) {
          strike++;
        } else {
          ball++;
        }
        break;
      }
    }
  }
  if (strike === 4) {
    console.log('홈런!!! ' + (count - 1) + '번 만에 맞추셨습니다');
    break;
  } else if (count > 10) {
    console.error('시도 횟수를 초과하셨습니다.');
  } else {
    console.info(inputArray.join('') + ': ' + strike + '스트라이크 ' + ball + '볼');
  }
}

찬찬히 다시 한 번 봐 보세요. 중요한 것은 알고리즘입니다. 아무리 언어를 알고 문법을 알더라도 알고리즘을 모르면 프로그램을 짤 수 없습니다. 조만간에 알고리즘 강의도 해야겠네요. 알고리즘을 알아야 언제 반복문을 쓰고 언제 조건문을 쓸 지 판단할 수 있습니다. 이 프로그램을 더 업그레이드 해보세요!

  • prompt에서 취소를 눌렀을 때 게임을 종료하도록 업그레이드(힌트: prompt때 취소를 누르면 input이 undefined가 됩니다)
  • 중복된 숫자(예: 2254)를 입력했을 때 오류가 표시되도록 업그레이드
  • 몇 번째 시도인지 항상 보여주도록 업그레이드(힌트: console.info에 count를 추가하면 됩니다)

이제 왕초보를 벗어나셨습니다. 다음 강의부터는 자바스크립트에서 기본적으로 제공하는 객체와 함수들에 대해 알아보겠습니다. console이나 Math같은 것과, 배열.join() 배열.split()같은 함수들을요.

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

14개의 댓글이 있습니다.
2달 전
안녕하세요! 좋은강좌 항상 잘보고 있습니다~
공부하다가 궁금한 점이 있는데
위에서 변수를 선언할때 스트라이크와 볼 변수에 0을 넣어줬는데
while문안에서 아래와 같이 다시 초기화 해주는 이유는 무엇인가요??
strike = 0; // strike와 ball의 개수를 초기화
ball = 0;
답변부탁드립니다! 좋은 하루되세욥!
2달 전
초기화하지 않으면 계속해서 strike랑 ball이 쌓여버립니다. 한 번 초기화 코드를 빼보세요.
3달 전
while 문이 말고 for문을 사용해도 상관 없는것 아닌가요?? for문으로 바꿔도 정상 작동 하는것 같아서요
3달 전
네네 break;이 걸려있어서 for로 해도 됩니다.
7달 전
안녕하세요 강좌 잘 보고 있습니다
저는 Codecademy랑 W3school에서 자바스크립트 강좌를 보고 넘어왔는데요
지금 저 야구게임 만들기가 강좌8 만에 할 수 있는 수준의 것인가요?ㅠㅠ
너무 절망스러워서요.. 영어라서 어렵다고 생각했는데 한국어로 봐도 어렵고 그냥 머리가 안되는가봐요
7달 전
자바스크립트는 위에서부터 한 줄씩 실행됩니다. 한 줄 한 줄 의미를 파악하시면 조금 나을겁니다. 다만 반복문같은 것은 익숙해질때까지 손으로 직접 반복되는 것들을 써보세요. 많은 분들이 어려워하셔서 더 쉽게 설명해보도록 하겠습니다.
7달 전
안녕하세요. 강좌 너무 잘 보고 있습니다.
if()에서 true 값을 만족하면 어차피 else if() 비교는 하지 않기 때문에 '불필요한 비교'는 일어나지 않는 것 아닌가요..?
7달 전
break는 for문에서 빠져나오는 것입니다!
8달 전
현재 야구게임을 만들고 문제를
업그레이드 중인데요. prompt 눌렀을때 취소를 눌르면 게임이 종료 되게끔까지는 했는데요, 그 다음 중복된 숫자를 입력했을때

if(input === 'undefined') break; //취소 눌렀을시 종료;

for(s = 0; s < inputArray.length; s++){
for(var l = s; l <= s; l++){
if(inputArray[s] === inputArray[l]) {
console.log('중복입력')
}
}
}
이렇게 for문을 돌려서 중복이되는상태인지 구한상태인데요, 중복카운트를 추가하려고하는데 어떻게 추가해야하는지 잘 모르겠어서 질문드립니다.....
또한 for문말고 좀더 효율적인 방법이 있을까요? 2중for문을 돌리니까 속도측면에서 느려질꺼같아서 더 좋은방법이있다면 조언 부탁드리겠습니다.
8달 전
2중 for문은 작은 숫자에서는 오히려 다른 알고리즘보다 더 빠릅니다. 중복카운트는 무엇을 말씀하시는지 잘 모르겠습니다. 그냥 변수 하나 만들어두고 ++하면 되지 않을까요
8달 전
아 제가 설명을 잘 말씀못드린거같네요. 중복카운트는 오류났을때 중복된걸 표시하려고하는데요, var error =0;이라는 변수를 만들어두고 if(inputArray[s] === inputArray[l]) {console.log('중복입력')} 말씀하신것처럼 error++을하니 error이 for문안에있기때문에 제가 의도한거처럼 1번만 ++되는게아니라 inputArray.length 길이만큼 값이 더해지는 상황이라 이 부분을 어떻게 처리해야할지 몰라서 질문드렸었습니다.제 말이 이해가 안가실꺼같아서 링크 남겨놓습니다.

https://jsfiddle.net/chunyong/33LcLewu/1/
8달 전
break;를 추가하면 될 것 같아요
8달 전
답변 감사합니다. 좀 더 고민해보고 풀어보겠습니다~
10달 전
랜덤으로 list배열에서 4개의 숫자를 가져왔는데요. 아래의 코드로 하면 중복 될 수 있죠? 콘솔창에서는 중복은 되지 않지만 궁금하내요. ex) [1,1,3,3]
//var number = [];
//for(var i = 0; i < 4; i++){number[i] = Math.floor(Math.random() * 9)}
10달 전
네 중복될 수도 있습니다.
10달 전
네 선물 1이 있는데요. 어떡해 열어요? 혹시 개발자님과 식사권이에요?
10달 전
아아 선물은 아니고 포인트입니다. ㅎㅎ 50점 쌓으시면 문화상품권 드려요
10달 전
number[0] == inputArr[0], number[0] == inputArr[1], number[0] == inputArr[2], number[0] == inputArr[3]

number[1] == inputArr[0], number[1] == inputArr[1], number[1] == inputArr[2], number[1] == inputArr[3]

number[2] == inputArr[0], number[2] == inputArr[1], number[2] == inputArr[2], number[2] == inputArr[3]

number[3] == inputArr[0], number[3] == inputArr[1], number[3] == inputArr[2], number[3] == inputArr[3]

for 문 안에서 number, inputArray 를 비교합니다. 같으면 break가 되고 if문은 배열 index 숫자를 비교합니다. 즉, j == k 든 j === k든 상관없습니다. 1. number[0] == inputArr[3] // 3 == '3' 같음 2. 0 == 3 false ball++
10달 전
아 저는 원칙적으로 ==는 쓰지 않습니다.
일 년 전
잘 보았습니다 덕분에 조금 더 지식이 확장되었네요
업글부분은 현 시점의 지식에선 알고리즘은 알겠으나 그걸 구현할 수 있는 함수기능 존재 여부 및 존재시 사용법 자체에 대해 모르니 현 시점에선 아직 무리인 듯 싶습니다

가장 간단한 건 input.split('') 값에서 중복된 부분을 자동경고하는 라이브러리 제공 함수를 쓰는건데 그게 아니라면 제일 효율적인건 prompt 기능 자체에서
중복값을 제어시키는 건데 (마치 숫자형으로 지정된 박스에 문자열 넣자마자 경고띄우는 것처럼) 그건 더더욱 현 영역을 벗어나는거라 그도 아니면 일단 입력 받은 것을 배열로 저장해서 그것들에서 중복값을 확인하는 반복문으로 하는건데 그건 그냥 생각해도 꽤 비효율적일듯 싶어 시도해보고 싶은 생각이 안드네요

업글 부분은 좀 더 강좌를 보면서 생각하는 알고리즘을 현실화시키는 수단들에 대한 존재여부와 사용법이 익혀졌을 때 시도해보는 것이 저와 같은 현 강좌를 보는 시점의 수준에 있는 사람들이 실력을 높이는데에 더 효율적일 거 같다는 생각도 듭니다

초딩이 생각은 중학생수준이라도 그걸 구현할 지식이 없는 상태라면
기초 지식부터 쌓아야지, 괜히 파고들어봐야 제풀에 지치고 결국 기초지식 쌓기로 돌아오거나 무의식적 거부감형성으로 의욕이 떨어지는 쪽으로 안좋게 흘러갈 여지도 있을 수 있기에..

유료강의 커리큘럼을 보았는데 시간적으로 직장인은 불가능해서 강좌로만 일단 정보 얻어갑니다 감사합니다
일 년 전
네 우선 자바스크립트 기초 문법을 익히신 후에 로직을 생각하셔야 합니다. 업그레이드 부분은 라이브러리를 안 쓰고도 간단하게 체크할 수 있습니다. 방법을 생각해보세요 ^^
일 년 전
오호 간단하게 처리될 수 있는 제공코드가 있나보군요 앞으로 익히다보면 알수 있겠네요 감사합니다
2년 전
2번정도 해보니 대충 이해가 가네요 하지만 제것으로 만들려면 시간이 걸리네요 이놈의 머리가 문제네요
2년 전
어려운 게 있다면 언제든지 질문하세요! 이해되실 때까지 알려드리겠습니다.
2년 전
너무나 좋은 블로그입니다 공부잘 하고있어요
근데 위 내용 중 console.warning();이 아니구 console.warn(); 아닌가요?
2년 전
아 그렇네요. 감사합니다~!
2년 전
이 야밤에 댓글까지.. 감사드립니다. 혹시 쪽지기능은 없는지궁금하네요 개인적으로 여쭙고싶은내용이 있는데 ㅎㅎ..
2년 전
메일로 보내주세요!
2년 전
저는 영 머리가 안좋은거같습니다..ㅠ number[i] = list.splice(select, 1)[0]; 이부분에서 셀렉트옆에있는 1은뭘의미하는건가요..? 계속처다봐도 헷갈리네요..
2년 전
저 부분은 그냥 list 배열에서 숫자 1개를 빼라는 것으로 생각하시면 됩니다!
2년 전
Zerocho님 고맙습니다! 잘 배우고 있습니다
2년 전
감사합니다~
2년 전
강좌 7까지 완주 했습니다

인강으로 자바스크립트를 완주하고

막상 배운걸 써먹긴커녕 코드 해석도 제대로 안됐었는데

한줄한줄 콘솔창에 뛰어보면서 해보니 이해가 되네요

물론 설명을 너무 잘해주셔서 그렇겟지요

이런 예제와 함께하는 강좌 정말좋네요

염치없지만 동영상 강좌도 있었으면 좋겠습니다 ㅎㅎ

감사합니다








2년 전
감사합니다~ 동영상 강좌도 해보고 싶지만 여건이 안 되네요 ㅎㅎ