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

[기능별 페이지] memory matching game1

by cogito21_js 2024. 6. 10.
반응형

알겠습니다. 사용자가 게임의 크기를 선택할 수 있도록 크기 선택 기능을 추가하고, 총 카드 개수를 짝수 개로 유지하도록 하겠습니다.

HTML (index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Memory Matching Game</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>Memory Matching Game</h1>
    </header>
    <main>
        <div class="game-container">
            <label for="boardSize">Select Board Size:</label>
            <select id="boardSize">
                <option value="4">4x4</option>
                <option value="6">6x6</option>
                <option value="8">8x8</option>
            </select>
            <div class="board" id="board"></div>
            <button id="resetButton">Reset Game</button>
        </div>
    </main>
    <script src="script.js"></script>
</body>
</html>

CSS (styles.css)

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

header {
    margin-top: 20px;
}

h1 {
    font-size: 2em;
}

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;
}

.board {
    display: grid;
    grid-gap: 10px;
    margin-top: 20px;
}

.card {
    width: 100px;
    height: 100px;
    background-color: #333;
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border-radius: 5px;
    font-size: 2em;
    transition: transform 0.5s;
}

.card.flipped {
    background-color: #fff;
    color: black;
    transform: rotateY(180deg);
}

button {
    margin-top: 20px;
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
    border: none;
    border-radius: 5px;
    background-color: #6200ea;
    color: white;
    transition: background-color 0.3s ease;
}

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

label, select {
    margin-top: 10px;
    margin-bottom: 20px;
    font-size: 1em;
}

JavaScript (script.js)

document.addEventListener('DOMContentLoaded', () => {
    const board = document.getElementById('board');
    const resetButton = document.getElementById('resetButton');
    const boardSizeSelect = document.getElementById('boardSize');

    let firstCard = null;
    let secondCard = null;
    let lockBoard = false;
    let cards = [];

    function initializeGame() {
        board.innerHTML = '';
        const boardSize = parseInt(boardSizeSelect.value);
        const totalCards = boardSize * boardSize;
        if (totalCards % 2 !== 0) {
            alert('The total number of cards must be even.');
            return;
        }
        cards = generateCards(totalCards);
        shuffle(cards);
        createBoard(boardSize);
    }

    function generateCards(totalCards) {
        const cardValues = [];
        const pairCount = totalCards / 2;
        for (let i = 0; i < pairCount; i++) {
            const value = String.fromCharCode(65 + i); // A, B, C, ...
            cardValues.push(value, value);
        }
        return cardValues;
    }

    function createBoard(boardSize) {
        board.style.gridTemplateColumns = `repeat(${boardSize}, 100px)`;
        board.style.gridTemplateRows = `repeat(${boardSize}, 100px)`;
        cards.forEach(createCard);
    }

    function createCard(cardValue) {
        const cardElement = document.createElement('div');
        cardElement.classList.add('card');
        cardElement.dataset.value = cardValue;
        cardElement.addEventListener('click', handleCardClick);
        board.appendChild(cardElement);
    }

    function handleCardClick(event) {
        if (lockBoard) return;
        const clickedCard = event.target;

        if (clickedCard === firstCard) return;

        clickedCard.classList.add('flipped');
        clickedCard.textContent = clickedCard.dataset.value;

        if (!firstCard) {
            firstCard = clickedCard;
        } else {
            secondCard = clickedCard;
            checkForMatch();
        }
    }

    function checkForMatch() {
        const isMatch = firstCard.dataset.value === secondCard.dataset.value;
        isMatch ? disableCards() : unflipCards();
    }

    function disableCards() {
        firstCard.removeEventListener('click', handleCardClick);
        secondCard.removeEventListener('click', handleCardClick);
        resetBoard();
    }

    function unflipCards() {
        lockBoard = true;
        setTimeout(() => {
            firstCard.classList.remove('flipped');
            secondCard.classList.remove('flipped');
            firstCard.textContent = '';
            secondCard.textContent = '';
            resetBoard();
        }, 1500);
    }

    function resetBoard() {
        [firstCard, secondCard, lockBoard] = [null, null, false];
    }

    function shuffle(array) {
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
    }

    resetButton.addEventListener('click', initializeGame);
    boardSizeSelect.addEventListener('change', initializeGame);

    initializeGame();
});

설명

HTML (index.html)

  1. HTML 기본 구조: 문서 타입 선언 및 기본 설정.
  2. 헤더: 페이지 제목을 표시합니다.
  3. 메인 콘텐츠: 게임 컨테이너와 게임 보드, 크기 선택 드롭다운 및 리셋 버튼을 포함합니다.
  4. 스크립트 파일 연결: JavaScript 파일을 포함합니다.

CSS (styles.css)

  1. 기본 스타일 설정: 페이지의 기본 폰트, 레이아웃, 배경색 등을 설정합니다.
  2. header: 상단 헤더 스타일을 설정합니다.
  3. h1: 제목의 폰트 크기를 설정합니다.
  4. main: 메인 콘텐츠를 중앙에 배치합니다.
  5. game-container: 게임 컨테이너의 스타일을 설정합니다.
  6. board: 그리드 레이아웃을 사용하여 카드들을 배치합니다.
  7. card: 각 카드의 기본 스타일을 설정합니다. 카드가 뒤집힐 때의 애니메이션도 설정합니다.
  8. card.flipped: 뒤집힌 카드의 스타일을 설정합니다.
  9. button: 리셋 버튼의 스타일을 설정합니다.
  10. button:hover: 리셋 버튼에 마우스를 올렸을 때의 스타일을 설정합니다.
  11. label, select: 크기 선택 드롭다운의 스타일을 설정합니다.

JavaScript (script.js)

  1. DOMContentLoaded 이벤트 리스너: DOM이 완전히 로드되었을 때 초기화 작업을 수행합니다.
  2. 게임 초기화 함수 (initializeGame): 보드를 초기화하고, 카드를 생성하여 셔플 후 보드를 구성합니다.
  3. 카드 생성 함수 (generateCards): 짝을 이루는 카드 값을 생성합니다.
  4. 보드 생성 함수 (createBoard): 보드의 그리드 레이아웃을 설정하고 카드를 추가합니다.
  5. 카드 생성 함수 (createCard): 각 카드를 생성하여 보드에 추가합니다.
  6. 카드 클릭 처리 함수 (handleCardClick): 카드 클릭 시 처리 작업을 수행합니다.
  7. 매칭 확인 함수 (checkForMatch): 두 카드의 매칭 여부를 확인합니다.
  8. 카드 비활성화 함수 (disableCards): 매칭된 카드를 비활성화합니다.
  9. 카드 뒤집기 함수 (unflipCards): 매칭되지 않은 카드를 다시 뒤집습니다.
  10. 보드 리셋 함수 (resetBoard): 보드 상태를 초기화합니다.
  11. 카드 셔플 함수 (shuffle): 카드 배열을 랜덤하게 섞습니다.
  12. 리셋 버튼 및 크기 선택 이벤트 리스너: 리셋 버튼 및 크기 선택 드롭다운 변경 시 게임을 초기화합니다.

이 코드는 사용자가 게임 보드의 크기를

선택할 수 있으며, 선택한 크기에 따라 적절한 짝수 개수의 카드를 생성하여 메모리 매칭 게임을 할 수 있도록 합니다.

반응형