본문 바로가기
Javascript 프로젝트/기능별 페이지

[기능별 페이지] - number guessing game

by cogito21_js 2024. 6. 10.
반응형

물론입니다. HTML, CSS, 그리고 JavaScript 파일의 코드에 대해 상세히 설명드리겠습니다.

HTML (index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="viewport" content="width=device-width, initial-scale=1.0">
    <title>Number Guessing Game</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <!-- 기존 header 내용 -->
    </header>
    <main>
        <div class="game-container">
            <h1>Number Guessing Game</h1>
            <div class="range-container">
                <label for="min">Min:</label>
                <input type="number" id="min" value="1" />
                <label for="max">Max:</label>
                <input type="number" id="max" value="100" />
                <button id="setRangeButton">Set</button>
            </div>
            <p>Guess a number between <span id="rangeDisplay">1 and 100</span>:</p>
            <input type="number" id="guessInput" />
            <button id="guessButton">Guess</button>
            <p id="message"></p>
            <button id="resetButton">Reset Game</button>
        </div>
    </main>
    <footer>
        <!-- 기존 footer 내용 -->
    </footer>
    <script src="script.js"></script>
</body>
</html>

설명

  1. DOCTYPE 선언 및 HTML 기본 구조:

    • <!DOCTYPE html>: 문서가 HTML5로 작성되었음을 명시합니다.
    • html, head, body 태그로 구성된 기본 HTML 문서 구조입니다.
  2. 메타데이터:

    • <meta charset="viewport" content="width=device-width, initial-scale=1.0">: 문서의 문자 인코딩을 UTF-8로 설정하고, 반응형 디자인을 위해 뷰포트 설정을 지정합니다.
  3. 스타일 시트 연결:

    • <link rel="stylesheet" href="styles.css">: styles.css 파일을 불러와 문서의 스타일을 정의합니다.
  4. 헤더와 푸터:

    • headerfooter 태그: 기존의 헤더와 푸터 내용을 유지합니다.
  5. 메인 콘텐츠:

    • main 태그: 페이지의 주요 콘텐츠를 감싸는 태그입니다.
    • div.game-container: 게임을 감싸는 컨테이너로, 게임의 전체 레이아웃과 스타일을 적용합니다.
    • h1: 게임 제목을 나타냅니다.
    • div.range-container: 숫자 범위를 설정할 수 있는 영역으로, 최소값(min)과 최대값(max) 입력 필드와 설정 버튼(setRangeButton)이 포함됩니다.
    • <p>Guess a number between <span id="rangeDisplay">1 and 100</span>:</p>: 사용자가 맞춰야 하는 숫자의 범위를 표시합니다.
    • <input type="number" id="guessInput" />: 사용자가 숫자를 입력할 수 있는 입력 필드입니다.
    • <button id="guessButton">Guess</button>: 사용자가 숫자를 추측하고 제출할 수 있는 버튼입니다.
    • <p id="message"></p>: 추측 결과 메시지를 표시할 영역입니다.
    • <button id="resetButton">Reset Game</button>: 게임을 리셋할 수 있는 버튼입니다.
  6. 스크립트 파일 연결:

    • <script src="script.js"></script>: script.js 파일을 불러와 게임의 동작을 정의합니다.

CSS (styles.css)

/* 기본 스타일 설정 */
body {
    font-family: 'Arial', sans-serif;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    margin: 0;
    background-color: #f4f4f9;
}

/* main 태그 스타일 설정 */
main {
    display: flex;
    justify-content: center;
    align-items: center;
    flex: 1;
    padding: 20px;
}

/* 게임 컨테이너 스타일 설정 */
.game-container {
    background: #fff;
    border-radius: 10px;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    padding: 20px;
    text-align: center;
}

/* 입력 필드 스타일 설정 */
input[type="number"] {
    padding: 10px;
    font-size: 16px;
    width: 80px;
    margin-bottom: 10px;
    margin-right: 5px;
}

/* 버튼 스타일 설정 */
button {
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
    margin: 5px;
    border: none;
    border-radius: 5px;
    background-color: #6200ea;
    color: white;
    transition: background-color 0.3s ease;
}

button:hover {
    background-color: #3700b3;
}

/* 메시지 스타일 설정 */
#message {
    margin-top: 10px;
    font-size: 18px;
}

/* 범위 설정 컨테이너 스타일 설정 */
.range-container {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: 20px;
    gap: 5px; /* 요소 사이에 간격 추가 */
}

.range-container label {
    font-size: 14px; /* 라벨의 폰트 크기를 줄임 */
}

.range-container input[type="number"] {
    width: 60px; /* 입력 필드의 너비를 줄임 */
    padding: 5px; /* 입력 필드의 안쪽 여백을 줄임 */
    font-size: 14px; /* 입력 필드의 폰트 크기를 줄임 */
}

.range-container button {
    padding: 5px 10px; /* 버튼의 패딩을 줄임 */
    width: auto; /* 버튼의 너비를 자동으로 설정 */
    font-size: 14px; /* 버튼의 폰트 크기를 줄임 */
}

설명

  1. body 스타일:

    • font-family: 기본 폰트를 'Arial'로 설정합니다.
    • display: flex: Flexbox 레이아웃을 사용합니다.
    • flex-direction: column: Flexbox 방향을 열 방향으로 설정합니다.
    • min-height: 100vh: 최소 높이를 뷰포트의 100%로 설정하여 전체 화면을 채우도록 합니다.
    • margin: 0: 기본 마진을 제거합니다.
    • background-color: #f4f4f9: 배경색을 연한 회색으로 설정합니다.
  2. main 스타일:

    • display: flex: Flexbox 레이아웃을 사용합니다.
    • justify-content: center: 가로 방향으로 중앙 정렬합니다.
    • align-items: center: 세로 방향으로 중앙 정렬합니다.
    • flex: 1: Flexbox의 남은 공간을 모두 차지하도록 설정합니다.
    • padding: 20px: 안쪽 여백을 20px로 설정합니다.
  3. game-container 스타일:

    • background: #fff: 배경색을 흰색으로 설정합니다.
    • border-radius: 10px: 모서리를 둥글게 만듭니다.
    • box-shadow: 그림자를 추가하여 입체감을 줍니다.
    • padding: 20px: 안쪽 여백을 20px로 설정합니다.
    • text-align: center: 텍스트를 중앙 정렬합니다.
  4. 입력 필드 스타일:

    • padding: 10px: 안쪽 여백을 10px로 설정합니다.
    • font-size: 16px: 폰트 크기를 16px로 설정합니다.
    • width: 80px: 입력 필드의 너비를 80px로 설정합니다.
    • margin-bottom: 10px: 아래쪽 여백을 10px로 설정합니다.
    • margin-right: 5px: 오른쪽 여백을 5px로 설정합니다.
  5. 버튼 스타일:

    • padding: 10px 20px: 안쪽 여백을 10px 20px로 설정합니다.
    • font-size: 16px: 폰트 크기를 16px로 설정합니다.
    • cursor: pointer: 커서를 포인터로 변경하여 클릭 가능함을 나타냅니다.
    • margin: 5px: 모든 방향에 5px의 여백을 설정합니다.
    • border: none: 테두리를 제거합니다.
    • border-radius: 5px: 모서리를 둥글게 만듭니다.
    • background-color: #6200ea: 배경색을 보라색으로 설정합니다.
    • color: white: 텍스트 색상을 흰색으로 설정합니다.
    • transition: background-color 0.3s ease: 배경색 전환을 부드럽게 만듭니다.
  6. 버튼 호버 효과:

    • button:hover:

    마우스를 버튼에 올렸을 때 배경색을 더 어두운 보라색으로 변경합니다.

  7. 메시지 스타일:

    • margin-top: 10px: 위쪽 여백을 10px로 설정합니다.
    • font-size: 18px: 폰트 크기를 18px로 설정합니다.
  8. 범위 설정 컨테이너 스타일:

    • display: flex: Flexbox 레이아웃을 사용합니다.
    • justify-content: center: 가로 방향으로 중앙 정렬합니다.
    • align-items: center: 세로 방향으로 중앙 정렬합니다.
    • margin-bottom: 20px: 아래쪽 여백을 20px로 설정합니다.
    • gap: 5px: 요소 사이에 5px의 간격을 추가합니다.
  9. 라벨 스타일:

    • font-size: 14px: 라벨의 폰트 크기를 14px로 줄입니다.
  10. 입력 필드 스타일:

    • width: 60px: 입력 필드의 너비를 60px로 줄입니다.
    • padding: 5px: 입력 필드의 안쪽 여백을 5px로 줄입니다.
    • font-size: 14px: 입력 필드의 폰트 크기를 14px로 줄입니다.
  11. 버튼 스타일:

    • padding: 5px 10px: 버튼의 안쪽 여백을 5px 10px로 줄입니다.
    • width: auto: 버튼의 너비를 자동으로 설정합니다.
    • font-size: 14px: 버튼의 폰트 크기를 14px로 줄입니다.

JavaScript (script.js)

// 초기 변수 설정
let randomNumber;
let attempts;
let minRange = 1;
let maxRange = 100;

// DOM 요소를 가져옴
const guessInput = document.getElementById('guessInput');
const guessButton = document.getElementById('guessButton');
const resetButton = document.getElementById('resetButton');
const setRangeButton = document.getElementById('setRangeButton');
const message = document.getElementById('message');
const rangeDisplay = document.getElementById('rangeDisplay');
const minInput = document.getElementById('min');
const maxInput = document.getElementById('max');

// 이벤트 리스너 설정
guessButton.addEventListener('click', checkGuess);
resetButton.addEventListener('click', resetGame);
setRangeButton.addEventListener('click', setRange);

// 게임 시작
initializeGame();

// 게임 초기화 함수
function initializeGame() {
    randomNumber = Math.floor(Math.random() * (maxRange - minRange + 1)) + minRange;
    attempts = 0;
    message.textContent = '';
    guessInput.disabled = false;
    guessButton.disabled = false;
    guessInput.value = '';
    guessInput.focus();
    rangeDisplay.textContent = `${minRange} and ${maxRange}`;
}

// 추측을 확인하는 함수
function checkGuess() {
    const userGuess = parseInt(guessInput.value);

    // 입력이 숫자가 아닌 경우 에러 메시지 표시
    if (isNaN(userGuess)) {
        message.textContent = 'Please enter a valid number.';
        message.style.color = 'red';
        guessInput.value = '';
        guessInput.focus();
        return;
    }

    // 입력이 범위 내에 있지 않은 경우 에러 메시지 표시
    if (userGuess < minRange || userGuess > maxRange) {
        message.textContent = `Please enter a number between ${minRange} and ${maxRange}.`;
        message.style.color = 'red';
        guessInput.value = '';
        guessInput.focus();
        return;
    }

    attempts++;
    if (userGuess === randomNumber) {
        message.textContent = `Congratulations! You guessed the number in ${attempts} attempts.`;
        message.style.color = 'green';
        guessInput.disabled = true;
        guessButton.disabled = true;
    } else if (userGuess > randomNumber) {
        message.textContent = 'Too high. Try again!';
        message.style.color = 'red';
    } else {
        message.textContent = 'Too low. Try again!';
        message.style.color = 'red';
    }
    guessInput.value = '';
    guessInput.focus();
}

// 범위를 설정하는 함수
function setRange() {
    const newMin = parseInt(minInput.value);
    const newMax = parseInt(maxInput.value);

    // 입력이 숫자가 아닌 경우 에러 메시지 표시
    if (isNaN(newMin) || isNaN(newMax)) {
        message.textContent = 'Please enter valid numbers for the range.';
        message.style.color = 'red';
        return;
    }

    // 최소값이 최대값보다 큰 경우 에러 메시지 표시
    if (newMin >= newMax) {
        message.textContent = 'Minimum value must be less than maximum value.';
        message.style.color = 'red';
        return;
    }

    minRange = newMin;
    maxRange = newMax;
    initializeGame();
}

// 게임을 리셋하는 함수
function resetGame() {
    minInput.value = minRange;
    maxInput.value = maxRange;
    initializeGame();
}

설명

  1. 변수 설정:

    • randomNumber, attempts, minRange, maxRange 변수를 선언합니다. minRangemaxRange의 초기값은 1과 100입니다.
  2. DOM 요소 가져오기:

    • 필요한 DOM 요소를 변수에 저장합니다.
  3. 이벤트 리스너 설정:

    • 추측 버튼, 리셋 버튼, 범위 설정 버튼에 대한 클릭 이벤트 리스너를 추가합니다.
  4. 게임 초기화 함수 (initializeGame):

    • 새로운 랜덤 숫자를 생성하고 시도 횟수를 초기화합니다.
    • 입력 필드와 버튼의 상태를 초기화하고, 현재 범위를 표시합니다.
  5. 추측을 확인하는 함수 (checkGuess):

    • 사용자의 입력을 확인하여 유효한 숫자인지, 지정된 범위 내에 있는지 검증합니다.
    • 입력이 유효하지 않으면 에러 메시지를 표시합니다.
    • 유효한 입력이면 추측이 정답인지 확인하고, 맞으면 축하 메시지를, 틀리면 힌트를 제공합니다.
  6. 범위를 설정하는 함수 (setRange):

    • 사용자가 입력한 최소값과 최대값을 검증하고, 유효하지 않으면 에러 메시지를 표시합니다.
    • 유효한 범위이면 새로운 범위를 설정하고 게임을 초기화합니다.
  7. 게임을 리셋하는 함수 (resetGame):

    • 입력 필드를 현재 범위로 설정하고 게임을 초기화합니다.

이렇게 하면 사용자가 숫자 범위를 지정하고, 범위 내에서 숫자를 맞추는 게임을 즐길 수 있으며, 유효하지 않은 입력에 대해서는 에러 메시지를 표시하여 올바른 입력을 유도할 수 있습니다.

반응형