자바스크립트 기초 - CSS, HTML, 숫자 야구 게임

Minhyeok Kim·2022년 7월 29일
0
post-thumbnail

[숫자 야구 게임 만들기]

/*
1. 0~9까지의 임의의 네 자리 수를 정한다.
2. 게임 참여자는 네 자리수를 입력한다.

  • 스트라이크는 입력한 네자리 수 중에 자리와 수를 맞춘 개수를 표시한다.
    예) 정담:1234 -> 입력:1567 => 1스트라이크
  • 볼은 입력한 네자리 수 중에 수가 존재하는 개수를 표시한다.
    예) 정답:5678 -> 입력:7890 => 2볼
  1. 4스트라이크(자리수와 수를 맞춘 경우)일 때 게임이 끝난다.

개발 사항
1. 0~9 까지의 랜덤한 숫자 4개를 뽑는 함수를 만든다. (각 숫자는 중복 불가)
2. 참여자가 입력한 숫자 4개에 대한 결과를 출력한다. 예)1스트라이크, 2볼입니다.
3. 숫자 4개와 자리까지 맞춘 경우 "홈런!!!"을 출력한다. 다음 문제 자동 시작.
4. 한 문제당 작성횟수는 10회로 제한한다.
5. 횟수를 초과할 경우 "횟수 초과!! 정담은 0000"을 출력한다. 다음 문제 자동 시작
*/

/*
+가점

  • 중복된 숫자, 숫자를 3개 이하 입력시 입력 불가하다는 메시지 화면에 출력
  • 남은 횟수 화면에 출력
  • 리셋기능 버튼 추가 (리셋 범위: 문제, 남은 횟수), 리셋 되었다는 메세지 화면에 출력
  • 힌트 제공 버튼 추가(정담이 포함된 5개의 랜덤한 수를 내림차순으로 화면에 출력)
  • 스타일 변경
    */

/
유의사항
1. 오픈북, 검색 가능
2. 주변에 도움 요청 불가 (단, 강사 or 멘토의 간접적인 도움은 받을 수 있음)
3. 할 수 있는 만큼 끝까지 포기하지 않고 에러 나더라도 주석 달아 놓고 제출
/

/
제출 방법
이메일 제출 : xxxxxxxxxx
제목 : [홍길동]-자바스크립트 프로젝트
내용 : 본인만 알 수 있고 중복되지 않는 별명 작성(점수 공개를 위함)
첨부파일 : 코드 작성한 html 파일 => 별명.html
마감 : 7월 29일 금요일 17:50 까지
/

/
내가 생각하는 알고리즘의 순서
컴퓨터가 임의의 네자리 숫자를 생성한다.
입력받는 횟수를 10회로 제한한다.
사용자로부터 네자리 숫자를 입력받는다.
답이 맞는지 틀린지 평가한다.
(strike 인지 ball 인지 판단하고 갯수를 카운트해서 출력)
정답을 맞췄으면 "홈런!!!"을 출력하고 알고리즘을 리셋한다.
정답을 10회까지 못맞췄으면 "횟수 초과!!! 정답은 0000"을 출력하고 알고리즘을 리셋한다.
/

개빡셌다... HTML 이 뭔지도 모르는데 일단 구현을 해야한다.
구글신님...

<!DOCTYPE html>

<html lang="ko">
  <head>
    <link rel="stylesheet" href="codename007.css" />
    <meta charset="UTF-8" />
    <title>숫자 야구 게임</title>
    <style></style>
  </head>
  <body>
    <form>
      <script>
        // 1. 화면구성
        // 게임 이름
        let title = document.createElement("h1");
        title.textContent = "숫자 야구 게임";
        document.body.append(title);
        // 전송 폼
        let form = document.createElement("form");
        document.body.append(form);
        // 입력창
        let input = document.createElement("input");
        input.maxLength = 4;
        // input.minLength = 4;
		// 4자리미만 입력시 HTML의 자동경고창 말고
		// 내가 원하는 내용 띄우기 위해 숨김처리
        form.append(input);
        // 입력 버튼
        let btn = document.createElement("button");
        btn.textContent = "Submit your lucky numbers!!";
        form.append(btn);
        // 입력 버튼
        let hintBnt = document.createElement("button");
        hintBnt.textContent = "힌트 구걸하기 ^____^";
        document.body.append(hintBnt);

        let resetBnt = document.createElement("button");
        resetBnt.textContent = "재시작";
        document.body.append(resetBnt);

        // 결과조회
        let result = document.createElement("div");
        document.body.append(result);

        // 2.숫자뽑기 함수 선언부
        // 이하 코드 작성

        let numbers = []; // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        let chosenNum = []; // 숫자4개를 무작위로 중복없이 골라서 넣을 배열
        let roundCheck = [];
        let imposter = [];
        let hintCheck;
        reset();

        function reset() {
          numbers = []; // supposed to be : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
          chosenNum = []; // 숫자4개를 무작위로 중복없이 골라서 넣을 배열
          roundCheck = [];
          imposter = [];
          for (let n = 0; n < 10; n++) {
            numbers.push(n); // numbers 안에 n 값을 하나하나 집어넣어서 0~9 숫자의 배열 생성
          }
          console.log(numbers); // 10개가 잘 들어 갔는지

          function selectNum() {
            // 숫자선정 4번 반복할
            for (let i = 0; i < 4; i++) {
              const forNum = numbers.splice(
                Math.floor(Math.random() * numbers.length - i),
                1
              )[0]; // 랜덤으로 나온 배열 [0] 을,
              chosenNum.push(forNum); // chosenNum 배열에 담는다.
            }
            console.log(chosenNum); // 선택된 4자리수
            console.log(numbers); // 남은 배열
            whoIsImposter();
            console.log(imposter);
          }

          function whoIsImposter() {
            const impo = numbers.splice(
              Math.floor(Math.random() * numbers.length),
              1
            )[0];
            imposter.push(impo);
            hintCheck = chosenNum.concat(imposter);
          }

          selectNum();
        }
        console.log(hintCheck);
        /*
        4번을 반복하면서 chosenNum 이라는 배열을 정의
        for 함수에서 실행하는 내용은,
        numbers 배열에서 splice 메서드를 활용하여 임의의 숫자를 제거
        "splice 는 splice(start, deleteCount, item1, item2, itemN) 으로 사용된다."
        "인덱스번호를 랜덤으로 받고, 1개만 제거하게끔 코드를 짜야한다."
        "두 정수 사이의 임의의 정수 추출이 필요한데, 이때 아래의 코드를 활용한다."
        "return Math.floor(Math.random()*(max - min + 1) + min);"
        "undefined 값이 출력되는 것을 막기 위해 i 값을 인수에서 빼서 계산한다."
        push 메서드를 이용하여 forNum 의 값을 인수로 받아 chosenNum 배열에 집어 넣는다.
        chosenNum 를 출력해서 확인한다.
        */

        // 배열 numbers [] : 0부터 9까지 순자를 모아둔 배열
        // 배열 chosenNum [] : numbers 에서 숫자 4개를 무작위로 골라낸 배열
        // 함수 selectNum () : 4번 반복하는 반복문, 랜덤숫자를 뽑아서 forNum 으로 넣고 이를 chosenNum 배열로 push 하는 함수
        // 함수 checkInput () : input 값을 받아서 값의 길이가 4자리인지, 중복된 숫자가 있는지 체크하는 함수
        // 변수 luckyNum : input 값을 선언하고 할당한 변수
        // 배열 luckyArray [] : luckyNum 값을 가지고 배열로 만든 것
        // 함수 ballCount () : 배열 luckyArray [] 와 배열 chosenNum[] 을 비교하여 스트라이크와 볼의 개수를 체크하는 함수
        // 배열 roundCheck [] : 입력한 값을 배열로 추가해서 길이를 계속 늘려
        // 배열 ... 

        // 3.참여자가 입력한 숫자 전송부

        hintBnt.addEventListener("click", function (event) {
          event.preventDefault();
          hintCheck.sort(function (a, b) {
            return b - a;
          });
          console.log(hintCheck);
          alert(`구걸한 힌트: 😜${hintCheck}😜 ☜(゚ヮ゚☜)`);
        });

        resetBnt.addEventListener("click", function (event) {
          event.preventDefault();

          function myReload() {
            window.location.reload();
            alert(`게임이 재시작되었습니다.`);
          }
          myReload();
        });

        form.addEventListener("submit", function (event) {
          event.preventDefault(); // 기본 동작 막기 (초기화되는거 막아)
          /*
          인터페이스의 addEventListener(type, listener, options(선택));
          */
          //
          const luckyNum = input.value; // 입력받은 값을 변수에 할당
          const luckyArray = luckyNum.split(""); // 값을 배열로 만들어
          console.log(luckyNum); // check : 입력값 확인
          console.log(luckyArray); // check : 입력값이 배열로 들어갔는지 확인
          console.log(chosenNum.join("")); // check : chosenNum 배열을 하나의 string으로
          input.value = ""; // 입력칸 초기화 (입력후 칸을 비워주기)

          function checkInput(input) {
            if (!Number.isInteger(Number(input))) {
              return alert("Not a number");
              // 문자열이 들어가 있을 경우 경고
            }
            if (input.length !== 4) {
              // 4 자리 숫자가 아닐 때 경고
              return alert("Must be 4 digits!!");
            }
            if (new Set(input).size !== 4) {
              return alert("Duplicated number!!");
              // 중복숫자가 있을경우 경고
            }

            roundCheck.push(luckyNum); // roundCheck 에 요소를 집어넣어서 몇회인지 카운트하게
            console.log(roundCheck); // check : 요소가 잘 추가되었는지 확인
            return true;
          }

          cycle();

          function cycle() {
            if (!checkInput(luckyNum)) {
              // 입력값을 체크한번해 4자리 숫자인지, 중복된 숫자는 없는지
              // 아무이상 없으면 false 로 나와서 else if 실행
            } else if (chosenNum.join("") === luckyNum) {
              result.innerHTML =
                "입력한 값: " +
                "[" +
                luckyNum +
                "]" +
                " ⚾홈런❗❗❗⚾ 다음게임이 시작됩니다." +
                "<br/>" +
                "<br/>";
              input.value = "";
              reset();
              // 홈런인지 아닌지 체크하고 홈런이면 게임 끝
              // reset 으로 바로 다음게임 open
              return; // 종료
            } else if (roundCheck.length >= 10) {
              // 입력값을 받아 요소로 추가하던 roundCheck 배열을 가지고 횟수 판단
              // 10회가 되면 게임 끝
              result.innerHTML =
                "횟수 초과❗❗ 아웃👊❗❗ 정답은 " +
                chosenNum +
                "였습니다. 다음게임이 시작됩니다." +
                "<br/>" +
                "<br/>";
              input.value = "";
              reset();
              return; // 종료
            } else {
              console.log("홈런 or 아웃 함수 체크"); // check : 홈런 or 아웃 함수 실행 확인
              ballCount(); // 홈런도, 아웃도 아니면 ballCount 함수 실행
            }
            return;
          }

          function ballCount() {
            let strike = 0;
            let ball = 0;
            console.log("ballCount 함수 실행"); // check : ballCount 함수 실행 확인
            for (i = 0; i < 4; i++) {
              if (Number(luckyArray[i]) === chosenNum[i]) {
                // 같은 자리인지 확인
                strike += 1;
              } else if (chosenNum.indexOf(Number(luckyArray[i])) > -1) {
                // 같은 자리는 아니지만 들어있는지 확인
                ball += 1;
              }
            }
            result.innerHTML +=
              roundCheck.length +
              " 회차" +
              "[" +
              luckyNum +
              "] " +
              strike +
              "스트라이크 " +
              ball +
              "볼 ▶ " +
              (10 - roundCheck.length) +
              " 회 남으셨습니다." +
              "<br/>";
            input.value = "";
          }
        });

        // indexOf 를 활용해서 포함되어 있는지 확인후, 어디에 있는지 확인
        // 포함되어 있으면 일단 ball 이상
        // 자리수 까지 같으면 strike
        // '2345'.indexOf(3) === 1;
        // '2345'.indexOf(6) === -1;
        // '2345'.indexOf(4) === 2;
        // 고로 indexOf 값이 >= 0 이면 존재는 한다는 뜻

        // 이하 코드 작성
        result.innerHTML =
          "입력한 숫자가 표시됩니다." +
          "<br/>" +
          "한 게임당 10번 도전 가능합니다." +
          "<br/>" +
          "<br/>";
      </script>
    </form>
  </body>
</html>

앞으로 HTML 이랑 CSS 를 배우면 한번 더 연습삼아 해보면 좋겠다...

0개의 댓글