이번 글은 연습문제 풀이입니다. 이전 글에서 연습문제를 풀어 보신 분들만 아래 내용을 확인하시길 바랍니다.






11-1 풀이

function fileExtensionSwitch(fileExtension){
  var type;

  switch(fileExtension){
    case "jpg":
    case "jpeg":
    case "png":
    case "gif":
      type = "그림파일";
      break;

    case "wav":
    case "mp3":
    case "mid":
      type = "음악파일";
      break;

    case "mp4":
    case "avi":
    case "mkv":
      type = "영상파일";
      break;

    default:
      type = "알수 없는 파일";
  }

 return type;
}

실전이라면 파일 타입에 따라 각각 다른 일을 하는 코드가 들어갈 겁니다. 예를들어 그림파일이라면 그림을 출력하는 코드, 음악파일이라면 음악을 재생하는 코드, 영상 파일이라면 영상을 재생하는 코드, 알수 없는 파일이라면 오류를 표시하는 코드 등..

11-2 풀이

//연습문제 9-2에서 가져온 윤년 구하는 함수
function checkLeapYear(year){
  var isLeapYear;

  if(year%4 != 0){
    isLeapYear = false;
  }
  else if(year%100 != 0){
    isLeapYear = true;
  }
  else if(year%400 != 0) {
    isLeapYear = false;
  }
  else {
    isLeapYear = true;
  }

  return isLeapYear;
}

//연습문제 11-2 함수
function getNumOfDate(year, month){
  var numOfDate;

  switch(month){
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
      numOfDate = 31;
      break;

    case 2:
      if(checkLeapYear(year)){
        numOfDate = 29;
      }
      else {
        numOfDate = 28;
      }
      break;

    case 4:
    case 6:
    case 9:
    case 11:
      numOfDate = 30;
      break;
  }

 return numOfDate;
}

위 코드를 if문으로 나타내면 아래와 같습니다.

function getNumOfDate(year, month){
  var numOfDate;

  if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12){
    numOfDate = 31;
  }
  else if(month == 2){
    if(checkLeapYear(year)){
      numOfDate = 29;
    }
    else {
      numOfDate = 28;
    }
  }
  else if(month == 4 || month == 6 || month == 9 || month == 11){
    numOfDate = 30;
  }

 return numOfDate;
}

어떤가요? switch가 좀 더 덜 복잡해 보이지 않나요?

연습문제(11-1)

switch 문을 사용하여 컴퓨터 파일의 확장자를 구별하는 함수를 만들어 봅시다.

파일의 확장자를 구별하여 다른 일을 하는 하는 코드는 실제 프로그램을 만들 때 종종 쓰입니다. 반드시 알아둡시다.

  • 함수는 한가지 문자열을 파라메터로 받습니다.
  • 받은 문자열이 "jpg", "jpeg", "png", "gif" 인 경우 "그림파일"이라는 문자열을 return합니다.
  • 받은 문자열이 "wav", "mp3", "mid"인 경우 "음악파일"이라는 문자열을 return합니다.
  • 받은 문자열이 "mp4", "avi", "mkv"인 경우 "영상파일"이라는 문자열을 return합니다.
  • 이 외의 문자열인 경우 "알수 없는 파일"이라는 문자열을 return합니다.

연습문제(11-2)

연습문제 9-2에서 년도를 입력받아 윤년이면 true를 return하는 함수를 만들어 보았습니다. 그 함수와 switch문을 사용하여 입력받은 년, 월의 날짜 수를 구하는 함수를 만들어 봅시다.

  • 함수는 년, 월 두가지 수를 파라메터로 받습니다.(예: 2020년 3월 이라면 2020과 3을 파라메터로 받음)
  • 해당 년, 월의 전체 날짜 수를 return합니다.(2020, 3을 받으면 31을 return)
  • 각 월의 날짜수는 다음과 같습니다:
    1월 - 31일,
    2월 - 윤년이면 29일 아니면 28일,
    3월- 31일,
    4월- 30일
    5월- 31일
    6월- 30일
    7월- 31일
    8월- 31일
    9월- 30일
    10월- 31일
    11월- 30일
    12월- 31일

또다른 조건문인 switch 문에 대해 배워봅시다.

switch

switch문은 때때로 if문보다 가독성이 높은 조건문입니다. 하지만 if문에 비해 조건이 한정적입니다.

switch(주어진_값){

  case 데이터1:
    주어진_값데이터1과 같은 경우 이곳의 코드가 실행됨
    break;

  case 데이터2:
    주어진_값데이터2와 같은 경우 이곳의 코드가 실행됨
    break;

  case 데이터3:
    주어진_값데이터3과 같은 경우 이곳의 코드가 실행됨
    break;

  default:
    주어진_값이 어떠한 데이터와도 같지 않을 경우 이곳의 코드가 실행됨

}

- default 부분은 생략가능합니다. default 부분이 생략된 경우, 값이 어떠한 case에도 맞지 않는 경우 아무일을 하지 않고 switch문이 종료됩니다.
- case는 원하는 만큼 만들 수 있습니다. 단, 가장 먼저 만족된 case의 코드가 실행됩니다.
- switch문에 사용된 switch, case, break는 예약어입니다.

if 문은 조건의 참, 거짓을 판단하여 코드를 실행하지만, switch 문은 주어진 값과 case의 데이터를 비교한 후 두 값이 같은 경우에 해당 case의 코드를 실행합니다. 위 switch 문을 if 문으로 변경하면 다음과 같습니다.

if(주어진_값 == 데이터1){
  주어진_값데이터 1과 같은 경우 이곳의 코드가 실행됨
}
else if(주어진_값 == 데이터2){
  주어진_값데이터 2와 같은 경우 이곳의 코드가 실행됨
}
else if(주어진_값 == 데이터3){
  주어진_값데이터 3과 같은 경우 이곳의 코드가 실행됨
}
else {
  주어진_값이 어떠한 데이터와도 같지 않을 경우 이곳의 코드가 실행됨
}

반대로 if 문을 switch 문으로 변경하려면 if 문이 반드시 위와 같은 형태일 때만 switch로 변경할 수 있습니다. if 문이 == 이외의 연산자를 사용하는 경우, 하나의 값에 대한 비교가 아닌 경우는 switch로 변경할 수 없습니다.

또 한가지 switch만의 특징은 break 의 사용에 있습니다. switch 문에서 한번 case의 조건이 만족되면 그 다음의 case들의 조건은 무시되고 break가 나올 때까지 코드가 실행됩니다. 즉 다음과 같은 코드를 만들 수 있습니다.

function colorCalendar(day){
  var color;

  switch(day){
    case "mon":
    case "tue":
    case "wed":
    case "thu":
    case "fri":
      color = "white";
      break;

    case "sat":
      color = "blue";
      break;

    case "sun":
      color = "red";
      break;
  }

  return color;
}

colorCalendar함수는 요일("mon", "tue", "wed", "thu", "fri", "sat", "sun") 데이터를 받아 해당 요일의 달력 색깔을 return하는 함수입니다. case가 나온 후 break 없이 계속하여 다른 case들을 사용할 수 있습니다.

colorCalendar함수를 if 문으로 변경하면 다음과 같습니다.

function colorCalendar(day){
  var color;

  if(day == "mon" || day == "tue" || day == "wed" || day == "thu" || day == "fri"){
    color = "white";
  }
  else if (day == "sat"){
    color = "blue";
  } 
  else if (day == "sun"){
    color = "red";
  }

  return color;
}

위 코드를 직접 작성해 보면 알겠지만, switch를 사용하는 것이 특수문자의 사용이 적어서 훨씬 쉽고 오타도 적게 납니다. 위 코드는 분기 후 할 일이 별로 없어도 큰 차이를 못느끼겠지만, 코드가 복잡해지면 if를 사용하는 것보다 switch를 사용하는 것이 보기에도 좋으므로 switch를 쓸 수 있는 곳에는 꼭 사용하도록 합시다.

랜덤한 수 생성

자바스크립트에서는 Math.random() 함수로 0 이상 1 미만인 랜덤한 수를 만들 수 있습니다. (0은 나올 수도 있지만 1은 절대 나오지 않습니다.)

Math.random();

이런식으로 소수점이 있는 수가 생성됩니다.

이 함수를 이용해서 0 이상 10 미만인 랜덤한 수를 만들려면? 결과에 10을 곱해주면 되겠죠.

Math.random()*10;

소수점 없이 0, 1, 2, 3, 4, 5, 6, 7, 8, 9의 10가지 수 중에 하나를 얻고 싶다면 소수점 이하의 값을 버리면 됩니다.

Math.floor()함수로 소수점 이하의 값을 버릴 수 있습니다. 반올림이 아니라 소수점 이하의 값을 무조건 버리는 함수입니다.

Math.floor(Math.random()*10);

위 내용을 바탕으로 눈금이 1부터 6까지 있는 주사위 함수를 만들 수 있습니다.

function dice6(){
  return Math.floor(Math.random()*6)+1;
}

Math.floor(Math.random()*6)는 0부터 5까지의 정수가 나오므로 여기에 1을 더해주면 1부터 6까지의 값이 나오게되는 것이죠.

일반화

만약 어떤 게임을 개발하는데, 눈금이 1에서 6까지 있는 주사위와 1에서 10까지 있는 주사위 두 개를 사용한다면 함수를 어떻게 만들어야 할까요?

function dice6(){
  return Math.floor(Math.random()*6)+1;
}

function dice10(){
  return Math.floor(Math.random()*10)+1;
}

이렇게 두가지 함수를 만들어서 사용할 수도 있겠지만, 위 두가지 기능을 모두 할 수 있는 하나의 함수만 만들 수도 있습니다.

function dice(maxNumber){
  return Math.floor(Math.random()*maxNumber)+1;
}

dice(6), dice(10)로 dice6과 dice10의 기능을 할 수 있습니다. 이때 dice 함수를 dice6, dice10함수에 비해 더 일반화가 되었다라고 표현합니다.

일반화된 코드는 여러 장점이 있습니다.

  • 우선 작성해야 할 코드의 전체 길이가 줄어듭니다.
  • 확장성이 좋습니다. 만약 1에서 12까지의 눈금이 있는 새 주사위가 필요하다고 하면 dice12 함수를 새로 만들 필요 없이 dice(12)를 사용할 수 있습니다.
  • 유지보수가 간편합니다. 만약에 그럴일은 없겠지만 어떠한 이유로 Math.random함수를 사용하지 말고 다른 코드로 변경해야하는 일이 있다고 하면, 주사위 함수가 여러가지인 경우 모든 함수를 각각 수정해 주어야 합니다. 일반화된 주사위 함수 하나뿐이라면 그곳만 수정하면 됩니다.

주사위 게임

위에서 만든 dice함수를 사용해 주사위 게임 함수를 만들어 봅시다.

- 주사위는 눈금이 1에서 6까지입니다.
- 컴퓨터의 주사위 값을 구하여 "컴퓨터의 주사위는 x입니다."라고 콘솔에 출력합니다. x는 주사위 눈금의 값입니다.
- 사용자의 주사위 값을 구하여 "당신의 주사위는 x입니다."라고 콘솔에 출력합니다. x는 주사위 눈금의 값입니다.
- 컴퓨터의 주사위 값과 사용자의 주사위 값을 비교하여 "x의 승리입니다."를 출력합니다. 컴퓨터의 주사위 값이 높으면 x에 "컴퓨터", 아니라면 "당신" 이 들어갑니다.
- 비긴 경우 "비겼습니다."를 콘솔에 출력합니다.

// 주사위 값을 생성하는 함수
function dice(maxNumber){
  return Math.floor(Math.random()*maxNumber)+1;
}

// 주사위 값을 출력하는 함수
function printDice(name, num){
  console.log(name+"의 주사위는 "+num+"입니다.");
}

// 승자를 출력하는 함수
function printWinner(name){
  console.log(name+"의 승리입니다.");
}

// 비겼음을 출력하는 함수
function printDraw(){
  console.log("비겼습니다.");
}

/*
   위의 함수들은 게임의 각 부분을 담당하는 함수들이며,
   아래 게임 메인 함수는 전체적인 프로그램의 진행을 담당합니다.
*/

// 게임 메인 함수
function diceGame(){
  var computerName = "컴퓨터";
  var yourName = "당신";

  var computerDice = dice(6); // 컴퓨터의 주사위 값 을 구함
  printDice(computerName, computerDice); // 컴퓨터 주사위 값 출력

  var yourDice = dice(6); // 사용자의 주사위 값을 구함
  printDice(yourName, yourDice); // 사용자 주사위 값 출력

  if(computerDice > yourDice){ // 만약 컴퓨터의 주사위 값이 더 크면,
    printWinner(computerName); // 컴퓨터 승리 문구 출력
  }
  else if(computerDice < yourDice){ // 그렇지 않고 만약 사용자의 주사위 값이 더 크면,
    printWinner(yourName); // 사용자 승리 문구 출력
  }
  else { // 다 아니라면,
    printDraw(); // 비겼음을 출력
  }
}

위 코드에서 //, /*, */라고 표시된 부분을 주석(comment)이라고 합니다. 코드를 읽는 사람에게 도움을 주기 위해 작성한 글로 프로그램에 아무런 영향을 끼치지 않습니다.

//는 한 줄에서 // 뒷부분에 입력된 내용을 코드에 포함시키지 않는 역할을 하고, /*는 */가 나올 때까지 그 사이의 모든 내용을 무시합니다.

+ Recent posts