잿꽃's posting Garden

자바스크립트로 끝말잇기 만들기 본문

WEB/JAVASCRIPT

자바스크립트로 끝말잇기 만들기

잿꽃 2022. 4. 30. 20:08

자바스크립트로 끝말잇기 만들기

몇 명이 참가하나요?
게임을 시작하지.

나름 이쁘게 만들어보겠다고 해봤는데 괜찮은지...

 

순서도

1. 몇 명이서 게임할 것인지 확인한다.

2. 제시어가 있는지 없는지 확인한다.

- 없으면 첫 번째 사람이 제시어를 제시한다.

3. 제시어가 있으면 이전 단어와 비교한다.

4. 맞으면 3번을 반복하고 틀리면 alert 창으로 표시한다.

 

 

읽기만 해도 알 수 있는 아주 간단한 html내용

<!-- ////////////////html//////////////// -->
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
    <link rel="stylesheet" href="style.css">
    <script defer src="script.js"></script>
</head>
<body>
    <!-- 전체 감싸기 -->
    <div class="wrapper">
        <!-- 유저 표시 -->
        <div class="orderBox"><span id="order">1</span>번째 유저 : </div>
        <!-- 단어가 나타나는 곳 -->
        <div id="word"></div>
        <!-- 입력창 -->
        <div class="inputBox">
            <input type="text">
            <button>입력</button>
        </div>
    </div>
</body>
</html>

 

내 맘대로 꾸민 css

/*///////////////css///////////////*/
@charset "UTF-8";

body{
    margin: 0;
    padding: 0;
    background-color: #e5e5e5;
}
.wrapper{
    width: 300px;
    height: 600px;
    background: #ffffff;
    border-radius: 20px;
    margin: 5rem auto;
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.orderBox{
    width: 100%;
    height: 50px;
    background: #14213d;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fca311;
}
#word{
    flex: 1;
    overflow-y: scroll;
}
#word div{
    margin: 10px;
}
.inputBox{
    width: 100%;
    height: 80px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin: 0 auto;
    background: #14213d;
}
.inputBox input{
    display: block;
    height: 25px;
}
.inputBox button{
    width: 20%;
    height: 30px;
    border: none;
    color: #fff;
    background: #333;
}

 

 

JAVASCRIPT

1. 몇 명이서 게임할 것인지 확인한다.

아주 간단하게 prompt창에서 물어본다. 입력된 값은 변수에 들어가게 된다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');

 

2. 제시어가 있는지 없는지 확인한다.

- 그전에 input의 value값을 감지해야 한다. change이벤트로 input값의 변화를 감지하여 변수에 넣어준다.

1회 입력 후 2회째부터 다시 입력할 수 있게 input값을 비워주고 바로 입력이 가능하도록 input이 focus상태가 되도록 한다.

이렇게 변수에 담아서 input의 값을 알 수 있게 되었다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');

let word;
let newWord;

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

- 확인 버튼을 눌렀을 때 이전 제시어가 없으면(맨 처음 상태) 비교할 수 있는 대상이 없다.

word는 값이 할당되지 않았기에 아직 undefined이며 if문에서는 false로 나타난다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');

let word;
let newWord;

submitBtn.addEventListener('click', ()=> {
    // 제시어가 없으면
    if(!word){
       
    // 제시어가 있는 상태   
    }else{
        
        }
    }
});

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

- 제시어가 없으면 새로운 input의 value내용이 word에 들어가게 된다. 이 값은 HTML에 나타나게 할 것이다.

만약 동일한 자리에 글자를 나타내고 싶다면 +=를 =로 수정하면 될 것이다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');
// 입력한 값을 보여줌
const showText = document.querySelector('#word');


let word;
let newWord;


submitBtn.addEventListener('click', ()=> {
    // 제시어가 없으면
    if(!word){
        // 입력한 내용을 현재 값에 담고 나타냄
        word = newWord;
        showText.innerHTML += `<div>제시어 : ${word}</div>`;
    }else{
        
    }
});

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

3. 제시어가 있으면 이전 단어와 비교한다.

- 이전의 단어와 마지막 단어를 비교하기 위해서 word의 마지막 글자의 위치인 [length-1]과 새 글자의 첫 번째 글자의 위치인 [0]의 값을 비교한다.

4. 일치하지 않는다면 alert창을 통해 일치하지 않는다고 나타낸다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');
// 입력한 값을 보여줌
const showText = document.querySelector('#word');

let word;
let newWord;

submitBtn.addEventListener('click', ()=> {
    // 제시어가 없으면
    if(!word){
        // 입력한 내용을 현재 값에 담고 나타냄
        word = newWord;
        // console.log(newWord);
        showText.innerHTML += `<div>제시어 : ${word}</div>`;
    }else{
        if(word[word.length-1] === newWord[0]){
            word = newWord; 
            showText.innerHTML += `<div>제시어 : ${word}</div>`;
        }else{
            alert('올바른 단어가 아닙니다');
        }
    }
});

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

 

OPTION

작업은 다 되었지만 높은 완성도를 위해 세부적으로 제작한 내용

1. 몇 번째 사람이 어떤 단어를 말했는지 알 수가 없기 때문에 몇 번째 사람이 진행하고 있는지 나타낸다.

현재 html태그에 맨 처음 값인 1이라는 숫자가 들어가 있는 상태이다. 이 값을 문자열이 아닌 숫자로 변환하고 이 숫자가 맨 처음에 알림 창으로 입력했던 값과 비교해서 1번부터 마지막 사람까지 끝말잇기를 진행하고 다시 1번으로 돌아갈 수 있게 한다.

(중복으로 되는 함수를 넣기 귀찮아서 익명 함수를 따로 만들어 변수에 담아줬다.)

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');
// 입력한 값을 보여줌
const showText = document.querySelector('#word');
// 사람의 순서를 나타내기 위함
const orderNum = document.querySelector('#order');


let word;
let newWord;

// 게임에 참가하는 순서를 나타내는 함수
const orderNum__comfirm = (order)=>{
    // 태그에 입력된 수를 숫자로 변환
    const Num = Number(order.textContent);
    if(Num == number){
        order.textContent = 1;
    }else{
        order.textContent = Num + 1;
    }
}

submitBtn.addEventListener('click', ()=> {
    // 제시어가 없으면
    if(!word){
        // 입력한 내용을 현재 값에 담고 나타냄
        word = newWord;
        // console.log(newWord);
        showText.innerHTML += `<div>제시어 : ${word}</div>`;
        // 게임에 참가하는 순서를 나타내는 함수
        orderNum__comfirm(orderNum);
    }else{
        if(word[word.length-1] === newWord[0]){
            word = newWord; 
            showText.innerHTML += `<div>제시어 : ${word}</div>`;
            
            orderNum__comfirm(orderNum);
        }else{
            alert('올바른 단어가 아닙니다');
        }
    }
});

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

 

2. 중복되는 코드가 많으므로 줄여본다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');
// 입력한 값을 보여줌
const showText = document.querySelector('#word');
// 사람의 순서를 나타내기 위함
const orderNum = document.querySelector('#order');


let word;
let newWord;

// 게임에 참가하는 순서를 나타내는 함수
const orderNum__comfirm = (order)=>{
    // 태그에 입력된 수를 숫자로 변환
    const Num = Number(order.textContent);
    if(Num == number){
        order.textContent = 1;
    }else{
        order.textContent = Num + 1;
    }
}

submitBtn.addEventListener('click', ()=> {
    // 제시어가 없거나 일치하면
    if(!word || word[word.length-1] === newWord[0]){
        // 입력한 내용을 현재 값에 담고 나타냄
        word = newWord;
        // console.log(newWord);
        showText.innerHTML += `<div>제시어 : ${word}</div>`;
        // 게임에 참가하는 순서를 나타내는 함수
        orderNum__comfirm(orderNum);
    }else{
            alert('올바른 단어가 아닙니다');
    }
});

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

3. 게임이 길어질 것을 대비해 화면이 넘어서 단어가 입력될 경우 스크롤을 맨 아래로 내린다.

showText.scrollTo(0, showText.offsetHeight);

위의 코드를 if문 참일 경우의 맨 아래에 넣어주면 된다.

 

4. input창에서 enter를 하여도 작동되도록 한다.

- 보통 pc에서는 버튼을 누르진 않고 엔터 기능을 더 많이 사용하므로 enter도 가능하게 만들어 보았다.

input에 onkeyup이벤트를 추가해서 키 코드가 엔터 키 코드(=13)와 동일하다면 위의 내용과 동일하게 실행할 수 있게 하였다.

- 또는 form태그를 만들어서 감싸면 submit이라는 이벤트를 통해 버튼을 클릭하지 않아도 enter를 누르면 결과를 제출할 수 있다.

// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');
// 입력한 값을 보여줌
const showText = document.querySelector('#word');
// 사람의 순서를 나타내기 위함
const orderNum = document.querySelector('#order');


let word;
let newWord;

// 게임에 참가하는 순서를 나타내는 함수
const orderNum__comfirm = (order)=>{
    // 태그에 입력된 수를 숫자로 변환
    const Num = Number(order.textContent);
    if(Num == number){
        order.textContent = 1;
    }else{
        order.textContent = Num + 1;
    }
}

// 버튼을 클릭하였을 때
submitBtn.addEventListener('click', ()=> {
    // 제시어가 없거나 현재 값이 맞을 때
    if(!word || word[word.length-1] === newWord[0]){
        // 입력한 내용을 현재 값에 담고 나타냄
        word = newWord;
        showText.innerHTML += `<div>제시어 : ${word}</div>`;
        
        // 게임에 참가하는 순서를 나타내는 함수
        orderNum__comfirm(orderNum);
        showText.scrollTo(0, showText.offsetHeight);
    }else{
        alert('올바른 단어가 아닙니다');
    }
});

// input상자에서 enter를 눌렀을 때
inputSelect.onkeyup = (e) =>{
    if(e.keyCode == 13){
        // 제시어가 없거나 현재 값이 맞을 때
        if(!word || word[word.length-1] === newWord[0]){
            // 입력한 내용을 현재 값에 담고 나타냄
            word = newWord;
            showText.innerHTML += `<div>제시어 : ${word}</div>`;
            
            // 게임에 참가하는 순서를 나타내는 함수
            orderNum__comfirm(orderNum);
            showText.scrollTo(0, showText.offsetHeight);
        }else{
            alert('올바른 단어가 아닙니다');
        }
    }
}

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

 

이렇게 해서 최종 javascript 코드가 완성되었다.

 

 

>>>>> 2022.05.04 수정

최종 코드에서 버튼 click과 input의 key이벤트 내에 함수가 동일하기 때문에 좀 더 줄여서 표현할 수 있을 거라 생각했다. 그래서 새로운 함수를 만들었고 적용해보았으나 잘 되지 않았다.

두 가지의 문제였다. 첫 번째는 이미 전역변수로 정의된 변수가 있는데 함수 내에 파라미터를 전달하고 그 값을 넣으려고 하니까 작동이 안 되었고 console.log로 찍어보니 자꾸만 undefined가 나왔다. 굳이 파라미터로 전달을 안 해도 이미 전역변수이기 때문에 정의할 필요가 없었다(쓸데없는 코드를 작성했다.) 두 번째는 오타였다...... 왜인지 모르겠지만 word.length에서 황당하게 .을 빼먹었다;;

사실 submit을 쓰면 따로 함수를 만들 필요가 없지만 이렇게 두 가지로 만드는 과정을 통해서 새로운 함수를 만들 때에 실수를 발견할 수 있었다.


// 게임에 참가 할 사람 수를 담는 변수
const number = prompt('몇 명이 참가하나요?');
// input값을 감지하기 위함
const inputSelect = document.querySelector('input');
// 확인버튼
const submitBtn = document.querySelector('button');
// 입력한 값을 보여줌
const showText = document.querySelector('#word');
// 사람의 순서를 나타내기 위함
const orderNum = document.querySelector('#order');


let word;
let newWord;

// 게임에 참가하는 순서를 나타내는 함수
const orderNum__comfirm = (order)=>{
    // 태그에 입력된 수를 숫자로 변환
    const Num = Number(order.textContent);
    if(Num == number){
        order.textContent = 1;
    }else{
        order.textContent = Num + 1;
    }
}

// input의 변화 값을 가져옴 
inputSelect.addEventListener('change', (e)=>{
    // 변화 값을 새로운 변수에 담음
    newWord = e.target.value;
    // input의 값 초기화
    e.target.value ='';
    // input 포커스
    inputSelect.focus();
})

// 제시어를 비교하고 나타내는 함수
const compareValue = () => {
    // 제시어가 없거나 현재 값이 맞을 때
    if(!word || (word[word.length-1] === newWord[0])){
        // 입력한 내용을 현재 값에 담고 나타냄
        word = newWord;
        showText.innerHTML += `<div>제시어 : ${word}</div>`;
        
        // 게임에 참가하는 순서를 나타내는 함수
        orderNum__comfirm(orderNum);
        text.scrollTo(0, showText.offsetHeight);
    }else{
        alert('올바른 단어가 아닙니다');
    }
}

// 버튼을 클릭하였을 때
submitBtn.addEventListener('click', ()=> {
    compareValue();
});

// input상자에서 enter를 눌렀을 때
inputSelect.onkeyup = (e) =>{
    if(e.keyCode == 13){
        compareValue();
    }
}

 

728x90
Comments