쉰여섯 번째 수업

정혅·2024년 7월 9일

더 조은 아카데미

목록 보기
60/76
post-thumbnail

오전문제

버튼게임 만들기

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Number Button Game</title>
    <style>
         h3 {
            text-align: center;
        }

        .number-btn {
            padding: 20px 40px;
            font-size: 24px;
            margin: 5px;
            cursor: pointer;
            width: 100px;
            height: 100px;
            border: 2px solid black;
        }

        .button-row {
            display: flex;
        }

        #number-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-top: 100px;
        }
    </style>
</head>
<body>
    <div id = "number-container">
        <h3>숫자 버튼 게임</h3>
        <div class="button-row" id = "buttonRow1"></div>
        <div class="button-row" id = "buttonRow2"></div>
        <div class="button-row" id = "buttonRow3"></div>
        <button onclick="restartGame()">Restart</button>
    </div>
    <script>
        let NUMBER_BTN = [];

        function createSuffleButtons(){
            const buttonRow1 = document.getElementById("buttonRow1");
            const buttonRow2 = document.getElementById("buttonRow2");
            const buttonRow3 = document.getElementById("buttonRow3");

            NUMBER_BTN = [];//얘를 넣어야 초기화가 되서 restart를 했을 때 문제가 없음
            for(let i = 0; i < 9; i++){
                const button = document.createElement('button');
                button.textContent = i === 0 ? '' : i;//i가 0이면 공백 아니면 숫자
                button.className = 'number-btn'; //위 생성한 button의 클래스 이름 생성
                // button.onclick = swapButton(this); 함수 호출의 값을 할당해야함
                button.onclick = function() {swapButton(this)};
                NUMBER_BTN.push(button);
            }
            const SHUFFLED_BTN = shuffle(NUMBER_BTN)

            for(let i = 0; i < 9; i++){
                if(i < 3){
                    buttonRow1.appendChild(SHUFFLED_BTN[i]);
                }
                else if(i < 6){
                    buttonRow2.appendChild(SHUFFLED_BTN[i]);
                }
                else{
                    buttonRow3.appendChild(SHUFFLED_BTN[i]);
                }
             }
        }
        //배열 요소 셔플
        function shuffle(array){
            for(let i = array.length -1 ; i > 0 ; i--){
                let j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
            return array;
        }


        function findEmptyButton(){//클래스가 number-btn이고 내용이 비어있는 요소가 존재한다면 그 요소를 반환
            return document.querySelector('.number-btn:empty');
        }
        function isAdjcent(button1, button2){
            const btn1Index = NUMBER_BTN.indexOf(button1);
            const btn2Index = NUMBER_BTN.indexOf(button2);
            const rowDiff = Math.abs(Math.floor(btn1Index / 3) - Math.floor(btn2Index / 3));
            const colDiff = Math.abs(btn1Index % 3 - btn2Index % 3);
            return ((rowDiff === 1 && colDiff === 0) || (rowDiff === 0 && colDiff === 1));        }

        function swapButton(clickedButton){
            const emptyButton = findEmptyButton();
            if(isAdjcent (clickedButton, emptyButton)){
                const clickedText = clickedButton.textContent;
                clickedButton.textContent = emptyButton.textContent;
                emptyButton.textContent = clickedText
                checkSuccess();
            }
        }
        function checkSuccess(){
            //.map을 사용해 NUMBER_BTN배열의 각 요소에서 textContent를 추출하고 join을 사용해 하나의 문자열로 결합하고 공백 제거
            //.map()은 버튼의 텍스트 내용을 추출하고 그 값을 새로운 배열에 추가하는 작업을 반복하기 위해 사용
            const buttonValues = NUMBER_BTN.map(a => a.textContent).join('').trim();
            let success = true;
            if(buttonValues !== '123456780'){
                success = false;
            }
            if(success) alert("성공하셨습니다!!!!");
        }

        //초기화 함수
        function restartGame(){
            const buttonsRows = document.querySelectorAll('.button-row');
            //button행들 삭제
            buttonsRows.forEach(a => a.innerHTML = '');//querySelectorAll은 nodeList로 반환하기 때문에 forEach()나 for..of로 접근
            //새로 생성
            createSuffleButtons();
        }
        //초기 게임 설정
        createSuffleButtons();
    </script>
</body>
</html>

배열관련 삽입, 삭제, 부분 출력

  1. 배열의 모든 요소 출력
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        let text = fruits.join();
        document.getElementById("demo").innerHTML = text;
    </script>
</body>
</html>

  1. const fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits의 모든 요소를 다음의 형태로 출력.
    Banana Orange Apple * Mango
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        let text = fruits.join(' * ');
        document.getElementById("demo").innerHTML = text;
    </script>
</body>
</html>

  1. fruits의 마지막 요소를 제거하고 그 제거한 요소 출력.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        let text = fruits.pop();
        document.getElementById("demo").innerHTML = text;
        //Mango
    </script>
</body>
</html>

  1. fruits의 마지막에 "Kiwi"를 추가하고 fruits의 길이를 추가.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.push("Kiwi");
        let text = fruits.length;
        document.getElementById("demo").innerHTML = text;
        //5
    </script>
</body>
</html>

  1. fruits의 첫번째 요소를 제거하고 그 요소를 출력
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        let text = fruits.shift();
        document.getElementById("demo").innerHTML = text;
        //Banana
    </script>
</body>
</html>

  1. fruits의 첫번째에 "Lemon"을 추가하고 fruits의 길이를 출력
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.unshift("Lemon");
        let text = fruits.length;
        document.getElementById("demo").innerHTML = text;
        //5
    </script>
</body>
</html>

  1. fruits의 length property를 이용하여 fruits의 마지막에 "Kiwi"를 추가
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits[fruits.length] = "kiwi";
        let text = fruits.join();
        document.getElementById("demo").innerHTML = text;
        //Banana,Orange,Apple,Mango,kiwi
    </script>
</body>
</html>

  1. myGirls 배열과 myBoys 배열을 합쳐서 새로운 배열을 만드시오.
    const myGirls = ["Cecilie", "Lone"];
    const myBoys = ["Emil", "Tobias", "Linus"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const myGirls = ["Cecilie", "Lone"];
        const myBoys = ["Emil", "Tobias", "Linus"];
        let text = myGirls.concat(myBoys);
        document.getElementById("demo").innerHTML = text;
        //Cecilie,Lone,Emil,Tobias,Linus
    </script>
</body>
</html>

  1. 다음 3개의 배열을 합치시오.
    const arr1 = ["Cecilie", "Lone"];
    const arr2 = ["Emil", "Tobias", "Linus"];
    const arr3 = ["Robin", "Morgan"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const myGirls = ["Cecilie", "Lone"];
        const myBoys = ["Emil", "Tobias", "Linus"];
        const arr3 = ["Robin", "Morgan"];
        let text = myGirls.concat(myBoys, arr3);
        document.getElementById("demo").innerHTML = text;
        //Cecilie,Lone,Emil,Tobias,Linus,Robin,Morgan
    </script>
</body>
</html>

  1. arr1 배열과 "Peter" 문자열을 합쳐서 하나의 배열로 만드시오.
    const arr1 = ["Emil", "Tobias", "Linus"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <title>Event Handling</title>

</head>
<body>
    <p id="demo"></p>
    <script>
    const arr1 = ["Emil", "Tobias", "Linus"];
    const arr2 = ["Peter"];
    document.getElementById("demo").innerHTML = arr1.concat(arr2);
    //    Emil,Tobias,Linus,Peter
    </script>
</body>
</html>

  1. 다음 배열의 요소가 다음과 같이 되도록 하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
    Banana,Orange,Lemon,Kiwi,Apple,Mango
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.splice(2, 0, "Lemon", "Kiwi");
        document.getElementById("demo").innerHTML = fruits;
        //Banana,Orange,Lemon,Kiwi,Apple,Mango
    </script>
</body>
</html>

  1. 다음 배열의 요소를 다음과 같이 되도록 하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
    Banana,Orange,Lemon,Kiwi
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.splice(2, 2, "Lemon", "Kiwi");
        document.getElementById("demo").innerHTML = fruits;
        //Banana,Orange,Lemon,Kiwi
    </script>
</body>
</html>

  1. 다음 배열에서 "Apple"을 삭제하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.splice(2, 1);
        document.getElementById("demo").innerHTML = fruits;
        //Banana,Orange,Mango
    </script>
</body>
</html>

  1. 다음 배열에서 인덱스상 1번째요소에서 마지막까지 잘라서 새로운 배열을 만드시오.
    const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
        document.getElementById("demo").innerHTML = fruits.slice(1);
        //Orange,Lemon,Apple,Mango
    </script>
</body>
</html>

  1. 다음 배열에서 인덱스상 1번째요소에서 2번째 요소까지 잘라서 새로운 배열을 만드시오.
    const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
        const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
        document.getElementById("demo").innerHTML = fruits.slice(1, 3);
        //Orange,Lemon
    </script>
</body>
</html>

배열 정렬 , 큰값 작은값

  1. 다음을 알파벳 순으로 정렬하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.sort();
        document.getElementById("demo").innerHTML = fruits;
        //Apple,Banana,Mango,Orange
    </script>
</body>
</html>

  1. 다음을 알파벳 역순으로 정렬하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const fruits = ["Banana", "Orange", "Apple", "Mango"];
        fruits.sort();
        fruits.reverse();
        document.getElementById("demo").innerHTML = fruits;
        //Orange,Mango,Banana,Apple
    </script>
</body>
</html>

  1. 다음을 숫자의 크기 순으로 정렬하시오.
    const points = [40, 100, 1, 5, 25, 10];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const points = [40, 100, 1, 5, 25, 10];
        points.sort((a, b) => a-b);
        document.getElementById("demo").innerHTML = points;
        //1,5,10,25,40,100
    </script>
</body>
</html>

4.다음을 숫자의 크기 내림차순으로 정렬하시오.
const points = [40, 100, 1, 5, 25, 10];

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const points = [40, 100, 1, 5, 25, 10];
        points.sort((a, b) => b-a);
        document.getElementById("demo").innerHTML = points;
        //100,40,25,10,5,1
    </script>
</body>
</html>

  1. 다음 배열을 서로 섞으시오.
    const points = [40, 100, 1, 5, 25, 10];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const points = [40, 100, 1, 5, 25, 10];

       for(let i = 0; i < points.length; i++){
        let j = Math.floor(Math.random() * (i + 1));
        [points[i], points[j]] = [points[j], points[i]];
       }
        document.getElementById("demo").innerHTML = points;
        //40,100,1,10,5,25
    </script>
</body>
</html>

  1. 다음 배열에서 가장 큰값을 구하시오.
    const points = [40, 100, 1, 5, 25, 10];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const points = [40, 100, 1, 5, 25, 10];
        points.sort((a, b) => b - a);
        document.getElementById("demo").innerHTML = points[0];
        //100
    </script>
</body>
</html>

  1. 다음 배열에서 가장 작은 값을 구하시오.
    const points = [40, 100, 1, 5, 25, 10];
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id = "demo"></p>
    <script>
       const points = [40, 100, 1, 5, 25, 10];
        points.sort((a, b) => a - b);
        document.getElementById("demo").innerHTML = points[0];
        //1
    </script>
</body>
</html>

배열 새로운 배열 생성, 인덱스, 참거짓 출력

다음 문제들을 Array 메소드를 이용하여 코딩하시오.

  1. const numbers = [45, 4, 9, 16, 25];
    배열의 모든 요소를 출력하시오.
  2. 다음 배열의 각 요소를 2배 곱해서 새로운 배열을 만드시오.
    const numbers1 = [45, 4, 9, 16, 25];
  3. 다음 배열에서 18이상인것만을 가지고 새로운 배열을 만드시오.
    const numbers = [45, 4, 9, 16, 25];
  4. 다음 배열의 모든 요소를 더해서 출력하시오.
    const numbers = [45, 4, 9, 16, 25];
  5. 다음 배열을 초기값을 100으로 해서 모든 요소를 더해서 출력하시오.
    const numbers = [45, 4, 9, 16, 25];
  6. 다음 배열을 오른쪽에서 왼쪽으로 모두 더하시오.
    const numbers = [45, 4, 9, 16, 25];
  7. 다음 배열의 모든 요소가 참이면 true를 아니면 false를 출력하시오.
    const numbers = [45, 4, 9, 16, 25];
  8. 다음 배열의 요소들 중 18을 넘는 요소가 있다면 true를 아니면 false를 출력하시오.
    const numbers = [45, 4, 9, 16, 25];
  9. 다음 배열에서 "Apple"이 있다면 그 인덱스를 출력하시오.(왼쪽에서 부터 검색. 첫번째로 찾은 요소)
    const fruits = ["Apple", "Orange", "Apple", "Mango"];
  10. 다음 배열에서 "Apple"이 있다면 그 인덱스를 출력하시오.(오른쪽에서 부터 검색. 첫번째로 찾은 요소)
    const fruits = ["Apple", "Orange", "Apple", "Mango"];
  11. 다음 배열에서 18이 넘는 첫번째 요소를 찾아서 그 요소를 출력하시오.
    const numbers = [4, 9, 16, 25, 29];
  12. 다음 배열에서 처음으로 18을 넘는 첫번째 요소의 인덱스를 출력하시오.
    const numbers = [4, 9, 16, 25, 29];
  13. 다음 문자열을 배열로 만드시오.
    "ABCDEFG"
  14. 다음 배열로 부터 Array Iterator object 를 만들어서 각 요소를 출력하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
  15. 다음 배열에서 key와 value로 이루어진 Array Iterator를 만들어서 각 요소를 출력하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
  16. 다음 배열이 "Mango"을 포함하고 있으면 true 아니면 false를 출력하시오.
    const fruits = ["Banana", "Orange", "Apple", "Mango"];
  17. 다음 배열들을 Spread 연산자를 이용하여 하나의 배열로 만드시오.
    const q1 = ["Jan", "Feb", "Mar"];
    const q2 = ["Apr", "May", "Jun"];
    const q3 = ["Jul", "Aug", "Sep"];
    const q4 = ["Oct", "Nov", "May"];

행맨 게임 만들기

선생님 코드

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hangman</title>
</head>
<body>
    <script>
        let arr = ['hello', 'monkey', 'candy', 'pancake'];
        let word = arr[Math.floor(Math.random()*arr.length)];
        let flag = true;

        let wordArr = new Array(word.length);
        wordArr.fill('_')

        while(wordArr.indexOf('_') !== -1) {
            let answer = prompt('글자를 입력하세요. 취소를 누르면 게임을 멈춥니다.');
            if(answer === null){
                alert('안타까워요 정답은 ' + word + '입니다.');
                flag = false;
                break;
            }
            if(answer.length !== 1) {
                alert('한글자만 입력하세요.');
                continue;
            }
            let idx  = 0;
            while( (idx =word.indexOf(answer, idx)) !== -1) wordArr[idx++] = answer;
            alert(wordArr.join(" "));
        }
        if(flag) alert('정답입니다.');
    </script>
</body>
</html>
  • indexOf(answer, idx) : answer문자가 word의 어느 인덱스에 존재하는지, 그리고 단어의 뒤에도 해당 스펠링이 있는지 확인

내가 푼거는 아직 미완성.. 함수 이용해서 풀었는데 잘 작동이 안됌

내가 푼거 완성!!

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Game</title>
</head>
<body>
    <script>
        // 게임에 사용되는 단어 목록
        let words = ["monkey", "candy", "dog", "korea", "programming"];
        // 게임에 사용될 무작위 단어 선정
        let randomWord;
        // 사용자가 맞추어야 하는 단어
        let guessedWord;
        // 추측 횟수
        let remainingGuesses;

        // 게임 초기화 함수
        function initializeGame() {
            randomWord = words[Math.floor(Math.random() * words.length)];
            remainingGuesses = 6;
            guessedWord = "_".repeat(randomWord.length).split('').join(' ');
            displayGameState();
        }

        // 남은 횟수 알려주는 함수
        function displayGameState() {
            alert("남은 횟수 : " + remainingGuesses + "\n" + guessedWord + "\n" + "스펠링을 입력해주세요. 취소를 누르면 게임이 멈춥니다.");
        }
        function correctDisplay(){
            alert("남은 횟수 : " + remainingGuesses + "\n" + guessedWord + "\n" + " 맞습니다! 다음 스펠링을 입력해주세요.")
        }
        function wrongDisplay(){
            alert("남은 횟수 : " + remainingGuesses + "\n" + guessedWord + "\n" + "틀리셨습니다. 다른 스펠링을 입력해주세요.")
        }

        // 사용자가 제출한 알파벳이랑 정답 비교
        function handleGuess(guess) {
            let found = false;
            for (let i = 0; i < randomWord.length; i++) {
                if (randomWord[i] === guess) {
                    guessedWord = guessedWord.substring(0, i * 2) + guess + guessedWord.substring(i * 2 + 1);
                    found = true;
                }
            }
            // 스펠링이 맞았을 때만 게임 상태 표시
            if (found) {
                // 게임 종료 조건
                if (guessedWord.replace(/ /g, "") === randomWord) {
                    alert("축하합니다. 정답을 맞추셨습니다. 정답은 " + randomWord);
                    initializeGame();
                }
                correctDisplay();
            } else {
                // 만약 추측한 알파벳이 없으면 횟수 감소
                remainingGuesses--;
                // 게임 종료 조건
                if (remainingGuesses === 0) {
                    alert("더 이상 남은 기회가 없습니다.. 실패하셨어요 정답은 " + randomWord + " 였습니다.");
                    initializeGame();
                    return; // 게임 종료 후 함수 종료
                } else {//입력받은 스펠링이 틀렸을 때
                    wrongDisplay();
                    let userInput = prompt("다른 알파벳을 입력하세요.");

                    if (userInput === null) {
                        alert("게임을 종료합니다.");
                        return; // 사용자가 취소 버튼을 누르면 함수 종료
                    }
                    handleGuess(userInput.toLowerCase()); // 대소문자 구분하지 않음
                }
            }
        }

        initializeGame();
        // 사용자 입력 받기
        while (remainingGuesses > 0 && guessedWord !== randomWord) {
            // 게임 시작
            let userInput = prompt("알파벳을 입력하세요.");
            if (userInput === null) {
                alert("게임을 종료합니다.");
                break; // 사용자가 취소 버튼을 누르면 반복문 종료
            }
            handleGuess(userInput.toLowerCase()); // 대소문자 구분하지 않음
        }
    </script>
</body>
</html>
  1. 취소를 누르면 종료
  2. 하나의 스펠링을 받아서 비교
  3. 틀리면 남은 횟수와 현재까지 진행된 단어를 보여주며 틀렸다고 표시
  4. 맞았으면 맞았다고 위와 같이 표시
  5. 종료되면 랜덤 단어 생성해 재시작

mysql 문제 - 데이터 형변환 및 join

  1. 괄호 안을 채우세요

데이터 형식          바이트 수      숫자 범위
( TINY INT )      1              -128 ~ 127
( SMALL INT )   2              -32,768 ~ 32,767
( INT )              4           약 -21억 ~ + 21억
( BIG INT )          8          약 -900경 ~ +900경


  1. 위 숫자 범위를 양수로 범위를 하려 한다면
  • UNSIGNED

  1. VARCHAR가 CHAR보다 공간을 효율적으로 운영할 수 있지만, MySQL 내부적으로
    성능(빠른 속도)면에서는 ( CHAR )로 설정하는 것이 조금 더 좋다.

  1. 실수형
    실수형은 소수점이 있는 숫자를 저장할 때 사용한다.
    데이터 형식             바이트 수 설명
    ( FLOAT )                      4             소수점 아래 7자리까지 표현
    ( DOUBLE )                8             소수점 아래 15자리까지 표현

  1. 날짜형
    날짜형은 날짜 및 시간을 저장할 때 사용한다.
    데이터 형식         바이트 수          설명
    ( DATE )             3              날짜만 저장. YYYY-MM-DD 형식으로 사용
    ( TIME )              3              시간만 저장. HH:MM:SS 형식으로 사용
    ( DATE TIME )         8 날짜 및 시간을 저장 YYYY-MM-DD HH:MM:SS 형식으로 사용

  1. 변수 두 개를 설정하고 그 변수 두개를 더한 값을 출력하자.
    SELECT @myVar1 + @myVar2;
    실행 결과 : 8
set @myVar1 = 4;
set @myVar2 = 4;
SELECT @myVar1 + @myVar2 AS sum;

  1. 실행 결과가 다음과 같이 나오도록 변수 @txt와 @height를 설정하시오.
    @height는 166으로 설정한다.
set @txt = '가수 이름 ==>';
set @height = 166;
SELECT @txt, mem_name FROM member join buy WHERE height > @height; 


  1. limit 변수 에러

LIMIT에는 변수를 사용할 수 없기 때문에 문법상 오류이다.

SET @count = 3;
SELECT mem_name, height FROM member ORDER BY height LIMIT @count;    -- 에러
  • 이를 해결하는 것이 PREPARE와 EXECUTE이다. PREPARE은 실행하지 않고 SQL 문만 준비해 놓고 EXECUTE에서 실행하는 방식이다.
SET @count = 3;
PREPARE mySQL FROM 'SELECT mem_name, height FROM member ORDER BY height LIMIT ?';
EXECUTE mySQL USING @count;
  1. @count변수에 3이라는 값을 할당

  2. prepare문에 from절은 쿼리를 준비 >> LIMIT ? 부분은 변수로 대체된다.

  3. EXECUTE문을 사용해 준비된 쿼리문을 실행한다.

  4. USING @count구문은 위에서 LIMIT ? 부분을 @count변수의 값을 대체한다.


  1. 구매(buy) 테이블의 평균 가격(price)을 정수로 출력하시오.(두 가지 방법)

cast()나 convert()함수 안에 올 수 있는 데이터 형식은 CHAR,
SIGNED, SIGNED, UNSIGNED, DATE, TIME, DATETIME등

SIGNED는 부호가 있는 정수, UNSIGNED는 부호가 없는 정수

cast

select cast(avg(price)AS SIGNED) as '평균 가격' from buy;

143


convert

select convert(avg(price), SIGNED) as '평균 가격' from buy;

143


  1. 이번에는 날짜를 확인해 보겠다. 다양한 구분자를 날짜형으로 변경할 수도 있다.
SELECT CAST('2022$12$12' AS DATE);
SELECT CAST('2022/12/12' AS DATE);
SELECT CAST('2022%12%12' AS DATE);
SELECT CAST('2022@12@12' AS DATE);

  1. 구매(buy)테이블에서 번호(num), 가격(price)을 문자로, 'X', 수량(amount)을 문자로, '=' 전자 4개를 더한다.
    그리고 별칭은 '가격X수량' 이라고 하고, 별칭 "구매액" (price*amount)을 출력한다.
select num, concat(cast(price as char), 'X', cast(amount as char), '=') '가격x수량', price*amount '구매액' from buy;


  1. 암시적인 변환
    암시적인 변환은 CAST()나 CONVERT() 함수를 사용하지 않고도 자연스럽게 형이 변환되는 것을 말한다.
SELECT '100' + '200';
-- 실행 결과
300

SELECT CONCAT('100', '200');
-- 실행 결과
100200

SELECT CONCAT(100, '200')
-- 100200

SELECT 100 + '200';
-- 300

  1. ( INNER JOIN )이란 두 개의 테이블을 서로 묶어서 하나의 결과를 만들어 내는 것을 말한다.

  1. 구매(buy) 테이블과 회원(member) 테이블로 부터 구매 테이블의 회원 아이디(mem_id)와 회원 테이블의 회원 아이디(mem_id)가
    같고 구매 테이블의 회원 아이디가 'GRL'인 회원의 모든 데이터를 출력해라.
select * FROM buy b 
inner join member m on b.mem_id = m.mem_id where m.mem_id = 'GRL';

  1. 구매(buy) 테이블과 회원(member)테이블로 부터 구매 테이블의 회원 아이디(mem_id)와 회원 테이블 회원 아이디(mem_id)가 같은 것의
    회원 아이디(mem_id), 회원 이름(mem_name), 제품 이름(prod_name), 주소(addr), 전화번호(PHONE1, PHONE2 별칭 '연락처')를 출력하시오.
select b.mem_id, m.mem_name, b.prod_name, m.addr, concat(m.PHONE1, m.PHONE2) '연락처'
 FROM buy b inner join member m on m.mem_id = b.mem_id;


  1. 구매 테이블(buy)과 회원 테이블(member)에서 구매 테이블의 회원 아이디(mem_id)와 회원 테이블의 회원 아이디(mem_id)가 같은 것들의
    회원 아이디(mem_id), 회원 이름(mem_name), 회원 주소(addr)을 회원 아이디(mem_id) 오름 차순으로 출력하시오.
select m.mem_id, m.mem_name, m.addr 
from buy b inner join member m on b.mem_id = m.mem_id 
order by m.mem_id;


  1. 내부 조인은 두 테이블에 모두 데이터가 있어야만 결과가 나온다. 이와 달리 (외부조인)은 한쪽에만 데이터가 있어도 결과가 나온다. ==Outer Join

  1. 회원 테이블(member)과 구매 테이블(buy)로 부터 회원 테이블의 아이디(mem_id)와 구매 테이블의 아이디(mem_id)과 같은 것들의
    전체 회원의 구매 기록(구매 기록이 없는 회원의 정보도 함께) 출력하는데, 회원 아이디(mem_id), 회원 이름(mem_name), 제품 이름(prod_name), 주소(addr)를 회원 아이디(mem_id) 오름차순으로 출력하자.
select m.mem_id, m.mem_name, b.prod_name, m.addr 
from buy b right outer join member m 
on  m.mem_id = b.mem_id 
order by m.mem_id;


  1. 회원 테이블(member)과 구매 테이블(buy)로 부터 회원 테이블의 회원 아이디(mem_id)와 구매 테이블의 회원 아이디(mem_id)과
    같은 것들중에 한번도 구매한 적 없는 회원 들의 회원 아이디(mem_id), 제품 이름(prod_name), 회원 이름(mem_name), 주소(addr)을
    회원 아이디 오름 차순으로 출력하시오.
select distinct m.mem_id, b.prod_name, m.mem_name, m.addr 
from buy b right join member m 
on b.mem_id = m.mem_id
where b.prod_name is null
ORDER BY m.mem_id;


  1. (FULL OUTER JOIN )은 왼쪽 외부 조인과 오른쪽 외부 조인이 합쳐진 것이라고 생각하면 된다. 왼쪽이든 오른쪽이든 한쪽에 들어 있는 내용이면 출력한다.

  1. (CROSS JOIN) )은 한쪽 테이블의 모든 행과 다른 쪽 테이블의 모든 행을 조인시키는 기능을 말한다. 그래서 상호 조인 결과의 전체 행 개수는 두 테이블의 각 행의 개수를 곱한 개수가 된다.
  • 카티션 곱이라고도 한다. CARTESIAN PRODUNT

  1. 회원 테이블(member)과 구매 테이블(buy)를 상호 조인 하시오.
SELECT * FROM buy CROSS JOIN member;
  • ON 구문을 사용할 수 없다.
  • 결과의 내용은 의미가 없다. 랜덤으로 조인하기 때문이다.
  • 상호 조인의 주 용도는 테스트하기 위해 대용량의 데이터를 생성할 때이다.

  1. sakila.inventory 테이블과 world.city테이블을 상호 조인한후 행의 개수를 출력하시오.
SELECT COUNT(*) "데이터 개수" FROM sakila.inventory CROSS JOIN world.city;

  1. sakila.actor테이블과 world.country를 상호 조인한 cross_table을 만드시오.
CREATE TABLE cross_table SELECT * FROM sakila.actor -- 200건
CROSS JOIN world.country; -- 239건

  1. 내부 조인, 외부 조인, 상호 조인은 모두 2개의 테이블을 조인했다. ( )은 자신이
    자신과 조인한다는 의미이다. 그래서 ( )은 1개의 테이블을 사용한다. 또 별도의 문법이 있는
    것은 아니고 1개로 조인하면 ( )이 되는 것이다.
  • 자체조인

  1. 직원 테이블(emp_table)로 부터 경리부장인 직원의 직원(emp), 직속상관(emp), 직속상관연락처(phone)을 출력하시오.
SELECT A.emp "직원", B.emp "직속상관", B.phone "직속상관연락처"
FROM emp_table A
INNER JOIN emp_table B
ON A.manager = B.emp
WHERE A.emp = '경리부장';

  1. cross_table의 5건의 모든 열의 데이터를 출력하시오.
SELECT * FROM cross_table LIMIT 5;

mysql 문제 - 스토어드 프로시저

  1. ifProc1 스토어드 프로시저가 존재 하면 삭제한다.
    ifProc1 스토어드 프로시저를 다음의 내용으로 만든다.
    100이 100과 같다면
    '100은 100과 같습니다.'라고 출력한다.
    ifProc1을 호출한다.
drop procedure if exists ifProc1;
delimiter $$
create procedure ifProc1()
begin 
    if 100 = 100 
        then select '100은 100과 같습니다.';
    end if;
end $$
delimiter ; --띄어쓰기 해야함
call ifProc1();


  1. ifProc2 스토어드 프로시저가 존재하면 삭제한다.
    ifProc2 스토어드 프로시저를 다음 내용으로 만든다.
    myNum 변수를 int로 선언한다.
    myNum 변수에 200을 대입한다.
    myNum이 100과 같으면 '100입니다.'라고 출력한다.
    그렇지 않으면 '100이 아닙니다.'라고 출력한다.
    ifProc2를 호출한다.
drop procedure if EXISTS ifProc2;
delimiter $$
create procedure ifPro2()
begin
    declare myNum int;
    set myNum = 200;
    if myNum = 100 
        then select '100입니다.';
    else
        select '100이 아닙니다';
    end if;
end $$
delimiter ;
call ifProc2();

--100이 아닙니다 출력 

  1. ifProc3 스토어드 프로시저가 있으면 삭제한다.
    다음 내용으로 ifProc3 스토어드 프로시저를 만든다.
    APN(에이핑크)인 회원의 데뷔 일자가 5년이 넘었는지 확인해보고 넘었으면
    '데뷔한 지 (며칠)일이나 지났습니다. 핑순이들 축하합니다!' 라고 출력하고
    그렇지 않으면
    '데뷔한 지 (며칠)일밖에 안되었네요. 핑순이들 화이팅~'이라고 출력하자.
drop procedure if exists ifProc3;
delimiter $$
create procedure ifProc3()
begin
        declare debuteDate Date;
        declare curDate Date;
        declare days int;

        select debut_date into debuteDate from market_db.member where mem_id = 'APN';

    SET curDate = current_date();
    set days = datediff(curDate, debuteDate);
    if(days/365) >= 5
         then select concat('데뷔한 지 ', days, '일이나 지났습니다. 핑순이들 축하합니다!');
    ELSE
        select ('데뷔한 지 ' + days + '일 밖에 안되었네요. 핑순이들 화이팅~');
        end if;
    end $$
    delimiter ;
    call ifProc3();


  1. 날짜 관련 함수
    ( ) : 오늘 날짜를 알려준다.
    ( ) : 오늘 날짜 및 시간을 함께 알려준다.
    ( ) : 날짜2부터 날짜1까지 일수로 몇일인지 알려준다.
  • CURRENT_DATE()

  • CURRENT_TIMESTAMP()

  • DATEDIFF(날짜 1, 날짜 2)


  1. 오늘 날짜와 '2021-12-31', '2000-1-1', 앞의 두 날짜의 차를 출력한다.
SELECT CURRENT_DATE(), DATEDIFF('2021-12-31', '2000-1-1') '날짜 차이';


  1. HAHA 프로시저가 있다면 삭제한다.
    HAHA 프로시저를 다음의 내용으로 만든다.
    100이 100이랑 같으면 100이라고 출력한다.
    200이 200이랑 같으면 200이라고 출력한다.
    300이 300이랑 같으면 300이라고 출력한다.
    그렇지 않으면 그 밖에 숫자라고 출력한다.
    위에 조건이 맞으면 밑에 조건은 출력하지 않는다.
    HAHA 프로시저를 호출한다.
DROP PROCEDURE IF EXISTS HAHA;
DELIMITER $$
CREATE PROCEDURE HAHA()
BEGIN
    IF 100 = 100
        THEN SELECT '100';
    ELSEIF 200 = 200
        THEN SELECT '200';
    ELSEIF  300 = 300
        THEN SELECT '300';
    ELSE
        SELECT '그 밖에 숫자';
    END IF;
END $$
CALL HAHA();


7.caseProc 스토어드 프로시저가 있으면 삭제한다.
다음 내용으로 caseProc 스토어드 프로시저를 만든다.
point INT, credit CHAR(1)로 두 개의 변수를 선언한다.
point 변수에 88을 대입한다.
case 문으로
point가 90 이상이면 credit에 A를
point가 80 이상이면 credit에 B를
point가 70 이상이면 credit에 C를
point가 60 이상이면 credit에 D를
그렇지 않으면 credit에 F를 대입한다.
그리고 다음과 같이 출력하자
취득점수==>88 학점==>B

DROP PROCEDURE IF EXISTS caseProc;
DELIMITER $$
CREATE PROCEDURE caseProc()
BEGIN
    DECLARE point INT;
    DECLARE credit CHAR(1);
    SET point = 88;

    CASE
        WHEN point >= 90
            THEN SET credit = 'A';
        WHEN point >= 80
            THEN SET credit = 'B';
        WHEN point >= 70
            THEN SET credit = 'C';
        WHEN POINT >= 60
            THEN SET credit = 'D';
        ELSE
            SET credit = 'F';
    END CASE;
    SELECT CONCAT('취득점수 ==>', point), CONCAT('학점====>', credit);
    END $$
    DELIMITER ;
    CALL caseProc();


  1. 구매(buy) 테이블과 회원(member)테이블로부터 회원 아이디(mem_id), 회원 이름(mem_name)
    총 구매액(price*amount),
    총 구매액이 1500이상이면 최우수고객
    1000이상이면 우수고객
    1이상이면 일반고객
    구매이력이 없으면 유령고객이라고 출력하자. 컬럼 별칭은 '회원등급'으로 하자.
    정렬은 총 구매액 내림차순으로 하자.
SELECT m.mem_id, m.mem_name, SUM(price*amount) "총 구매액",
    CASE
        WHEN (SUM(price*amount) >= 1500) THEN '최우수 고객'
        WHEN (SUM(price*amount) >= 1000) THEN '우수 고객'
        WHEN (SUM(price*amount) >= 1) THEN '일반 고객'
        ELSE '유령 고객'
    END "회원등급"
    FROM buy b right outer join member m
        on b.mem_id = m.mem_id 
    GROUP BY m.mem_id
    ORDER BY SUM(price*amount) DESC;
    SELECT * FROM buy;
  • 구매이력이 없는 애들 까지 출력하려고 하니까 member테이블을 기준으로 Right outer join을 해야하는 것

  1. whileProc라는 스토어드 프로시저가 있으면 삭제한다.
    다음의 내용으로 whileProc 스토어드 프로시저를 만든다.
    1부터 100까지 더한 후, 그 값을 출력한다.
    whileProc 스토어드 프로시저를 호출한다.
DROP PROCEDURE IF EXISTS whileProc;
DELIMITER $$
CREATE PROCEDURE whileProc()
BEGIN
    DECLARE i INT;
    DECLARE hap INT;
    SET i = 1;
    SET hap = 0;

    WHILE(i <= 100) DO
        SET hap = hap + 1;
        SET i = i + 1;
        END WHILE;
    SELECT '1부터 100까지의 합 -->', hap;
END $$
DELIMITER ;
CALL whileProc();


  1. ( ) : 지정한 레이블로 가서 계속 진행한다.
    ( ) : 지정한 레이블을 빠져나간다. 즉 WHILE 문이 종료된다.
  • ITERATE

  • LEAVE


  1. 1부터 순차적으로 1씩 증가시킨 값을 합산하는데 4의 배수는 합산하지 않고
    1000을 넘는 최초의 수를 구하자. ITERATE와 LEAVE를 활용해서 풀어보자.
DROP PROCEDURE IF EXISTS whileProc2;
DELIMITER $$
CREATE PROCEDURE whileProc2()
BEGIN
    DECLARE i INT;
    DECLARE hap INT;
    SET i = 1;
    SET hap = 0;

    myWhile:
    WHILE(i <= 1000) DO
        IF (i % 4 = 0) 
            THEN  SET i = i + 1;
            ITERATE mywhile;
            END IF;
        SET hap = hap + 1;
        IF(hap > 1000)
            THEN LEAVE myWhile;
            END IF;
        SET i = i + 1;
        END WHILE;
    SELECT '1부터 100까지의 합 (4의 배수 제외), 1000 넘으면 종료 ==>', hap;
    END $$
    DELIMITER ;
    CALL whileProc2();


  1. 쿼리문 SELECT * FROM member WHERE mem_id = "BLK"를 동적으로 실행 되게 하자.
use market_db;
PREPARE myQuery FROM 'SELECT * FROM member WHERE mem_id = "BLK"';
EXECUTE myQuery;
DEALLOCATE PREPARE myQuery;

  1. gate_table이 있다면 삭제한다.

    다음 내용을 가지고 테이블을 만든다.
    id INT 자동증가
    entry_time DATETIME

    현재 날짜와 시간을 동적으로 넣도록 하자.
    그리고 그 결과를 확인하자.

DROP TABLE IF EXISTS gate_table;
CREATE TABLE gate_table(id INT AUTO_INCREMENT PRIMARY KEY, entry_time DATETIME);

SET @curDate = CURRENT_TIMESTAMP();        -- 현재 날짜와 시간 

PREPARE myQuery FROM 'INSERT INTO gate_table VALUES(NULL, ?)';
EXECUTE myQuery USING @curDate;
deallocate PREPARE myQuery;

SELECT * FROM gate_table;
  • deallocate 문은 준비된 문을 해제하는데 사용된다. >> prepare문과 함께 사용

0개의 댓글