<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>끝말 잇기</title>
<script src="main.js"></script>
</head>
<body>
<div><span id="order">1</span>번째 참가자</div>
<div>제시어 : <span id="word"></span></div>
<input id="input" type="text">
<button id="button">입력</button>
</body>
</html>
document.addEventListener('DOMContentLoaded', () => {
let number = parseInt(prompt('몇 명이서 참가하시나요?'));
//프롬트창에서 숫자가 아닌 값을 받을때, 다시 띄울 창
while(isNaN(number)){
number = parseInt(prompt('숫자를 입력하세요'));
}
})
prompt창을 띄워서 몇명이서 참가할 것인지 입력값을 받는다.
주의할 점은 prompt 값의 입력값은 숫자를 입력하더라도 문자열로 출력이 된다.
저 parseInt를 빼고 console.log(typeof(number))를 한다면 string이 출력된다.
그래서 parseInt 를 통해 숫자열로 바꿔주었다.
그리고 프롬트 창에서 받은 값이 공백이거나, 숫자가 아닌 값을 받았을때 숫자를 입력하라는 프롬트 창을 새로 띄우고 싶었다.
처음에는 number의 값이 null 일때나 undefined 일때를 생각했었는데, NaN이 나올수도 있다는 생각이 들었다.
그리고 처음에는 number도 const로 선언을 해줬었는데, const로 하면 재선언, 재할당이 불가하므로 let으로 변경해주었다.
✔️ isNaN()이란 ?
- isNaN 메서드는 ()안에 들어간 매개변수 값이 NaN이라면 true를, 아니라면 false를 반환해주는 메서드이다.
인풋창에서 한글만 입력 받도록 해야했는데, 이걸 구현시키기 위해서는 정규표현식을 알아야했다.
let str = 123;
const regex = /^[ㄱ-ㅎ|가-힣|a-z|A-Z|0-9|]+$/; // 한글, 숫자, 영어만 입력 받기
console.log(regex.test(str)); // true
const regex = /^[ㄱ-ㅎ|가-힣]+$/ // 한글만 입력 받기
console.log(regex.test(str)); // false
const regex = /^[a-z|A-Z]+$/; // 영어만 입력 받기
console.log(regex.test(str)); // false
console.log(regex.test('abcd')); // true
const regex = /^[ㄱ-ㅎ|가-힣]+$/; // 한글만 입력 받기
console.log(regex.test('안녕하세요')); // true
정규표현식을 통해서 받은 문자가 한글이 아니라면 alert창을 띄우고, 3번 이상 잘못 입력한다면 게임이 끝났다는 alert 창을 띄웠다.
document.addEventListener("DOMContentLoaded", () => {
let number = parseInt(prompt("몇 명이서 참가하시나요?")); // 몇명 참가하는지?
const order = document.querySelector("#order"); // n번째 참가자 창
const word = document.querySelector("#word"); // 제시어 생기는 창
const input = document.querySelector("#input"); //typeof => String // 제시어 입력하는 창
const button = document.querySelector("#button"); //입력 버튼
let i = 1;
const regex = /^[ㄱ-ㅎ|가-힣]+$/; // 입력값에 한글만 받도록 하기
//프롬트창에서 숫자가 아닌 값을 받을때, 다시 띄울 창
while (isNaN(number)) {
number = parseInt(prompt("숫자를 입력하세요"));
}
button.addEventListener("click", () => {
let inputWord = document.getElementById('input').value;// 인풋에 받는 값
if (regex.test(inputWord) == false) {
// 입력값이 문자열이 아니라면
alert("단어를 다시 입력하세요" + (i++) + "/ 3");
input.value = '';
if (i > 3) {
alert("값을 잘못 입력하셨습니다. 게임이 끝났습니다."); // 아예 창이 아무것도 안뜨게 하기
}
} else {
// 입력값이 제대로 입력됐다면
// 입력받았던 값의 끝글자와 입력값의 첫글자가 이어진다면
word.append(inputWord);
input.value = '';
const lastWord = document.getElementById('word').innerHTML;
}
});
});
❗️ 여기서 문제가 발생했는데, input창에 받는 입력값을 클릭 이벤트가 발생하기 전에 전역에 선언을 해줬었는데, 이렇게 되면 DOMContentLoaded 이벤트가 발생할 당시의 input의 값인 ' ' 을 들고 오는거라서 오류가 발생했다. 저 input창의 값은 클릭을 눌렀을 당시, 즉 <끝말잇기를 이어가기 위한 단어> 를 가져와야하는 것이니까 클릭이벤트가 발생했을때 변수를 선언해주어야 했다 ❗️
❗️ 또 끝말잇기의 제일 중요한 기능인 입력한 단어의 첫글자와 그 전에 입력했던 단어의 끝글자가 서로 같은지를 판단하는 기능을 어떻게 구현하느냐가 제일 고민이 되는 부분이었다.
원래 책에서는 제시어를 담는 input 창을 따로 만들어서 원래 있던 단어와 새로 입력하는 단어를 따로따로 받아주는 식으로 만들었었는데, 그렇게 하기보다 오히려 한 span창에서 값을 판단할 수 있도록 하고 싶었다. 그래서 제시어 생기는 창의 textContent를 받아주는 preWord 라는 변수를 새로 만들어서 해결을 하려 했는데, 이렇게 하면 처음에 preWord가 비어있는 값이 되어버렸다.
그래서 생각한 방법은 빈 배열을 하나 만들어 주고, 그 배열에 단어들을 넣어줌으로써 비교를 하는 것이었다. 그리고 입력된 단어는 배열의 마지막 문자를 preWord 라는 변수에 따로 담아줘서 문자의 일치를 비교하려 했다.
❗️ 이 배열도 전역이 아닌 클릭을 눌렀을때 빈 배열을 만들어주려 했는데, 입력값을 눌렀을때 빈배열을 만들어 주는거면 값이 들어가지 않고 계속 빈 배열이 생성되는 것이므로 전역에 생성을 해줬어야 했다 ❗️
else {
// 입력값이 제대로 입력됐다면
let wordsLength = words.length; // 단어 받을 배열의 길이
if (wordsLength == 0) { // 아무런 단어도 아직 받지 않았을때
word.append(inputWord + " - "); // span창에 단어 띄우기
words.push(inputWord); // 배열에 단어 넣기
} else { // 단어를 이미 받은 후라면
let preWord = words[words.length - 1]; // 입력에 받은 마지막 단어
if (preWord.substr(-1) == inputWord.substr(0, 1)) { //글자 비교
word.append(inputWord + " - ");
words.push(inputWord);
} else {
alert("단어를 잘못 입력하셨습니다. 게임이 끝났습니다");
}
}
input.value = ""; // 인풋창 초기화
}
3명이 참가한다고 했을때, 3번째 참가자가 입력을 하고 클릭을 했을때, 다시 1로 돌아와야 하는것이니까 span창의 order의 텍스트값을 받아서 숫자로 비교해주었다.
let orderValue = Number(order.textContent); // n번째 참가자의 n
let inputWord = document.getElementById("input").value; // 인풋창에 입력되는 단어
if (orderValue == number) { // 참가자수와 n이 같다면
order.textContent = "1";
} else {
order.textContent = orderValue + 1; // 3번째 참가자라고 표시되는것이 3번째 참가자가 입력하기 전인것
}
완성된 모습이다.
<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>끝말 잇기</title>
</head>
<body>
<div><span id="order">1</span>번째 참가자</div>
<input id="input" type="text" placeholder="단어를 입력하세요">
<button id="button">입력</button>
<span id="word"></span>
</body>
<script>
document.addEventListener("DOMContentLoaded", () => {
let number = parseInt(prompt("몇 명이서 참가하시나요?")); // 몇명 참가하는지?
const order = document.querySelector("#order"); // n번째 참가자 창
const word = document.querySelector("#word"); // 제시어 생기는 창
const input = document.querySelector("#input"); //typeof => String // 제시어 입력하는 창
const button = document.querySelector("#button"); //입력 버튼
let i = 1;
const regex = /^[ㄱ-ㅎ|가-힣]+$/; // 입력값에 한글만 받도록 하기
let words = []; // 입력된 단어들 넣을 빈 배열
//프롬트창에서 숫자가 아닌 값을 받을때, 다시 띄울 창
while (isNaN(number)) {
number = parseInt(prompt("숫자를 입력하세요"));
}
button.addEventListener("click", () => {
let orderValue = Number(order.textContent); // n번째 참가자의 n
let inputWord = document.getElementById("input").value; // 인풋창에 입력되는 단어
if (orderValue == number) { // 참가자수와 n이 같다면
order.textContent = "1";
} else {
order.textContent = orderValue + 1; // 3번째 참가자라고 표시되는것이 3번째 참가자가 입력하기 전인것
}
if (regex.test(inputWord) == false) {
// 입력값이 문자열이 아니라면
alert("단어를 다시 입력하세요" + i++ + "/ 3");
input.value = "";
if (i > 3) {
alert("값을 잘못 입력하셨습니다. 게임이 끝났습니다."); // 아예 창이 아무것도 안뜨게 하기
}
} else {
// 입력값이 제대로 입력됐다면
// 입력받았던 값의 끝글자와 입력값의 첫글자가 이어진다면
let wordsLength = words.length; // 단어 받을 배열
if (wordsLength == 0) {
// 아무런 단어도 아직 받지 않았을때
word.append(inputWord + " - "); // span창에 단어 띄우기
words.push(inputWord); // 배열에 단어 넣기
} else {
// 단어를 이미 받은 후라면
let preWord = words[words.length - 1]; // 입력에 받은 마지막 단어
if (preWord.substr(-1) == inputWord.substr(0, 1)) {
word.append(inputWord + " - ");
words.push(inputWord);
} else {
alert("단어를 잘못 입력하셨습니다. 게임이 끝났습니다");
}
}
input.value = ""; // 인풋창 초기화
}
});
});
</script>
</html>
순서도 짜보는 것부터 너무 어려웠다.. 그리고 순서도도 저렇게 대략적인 부분을 짜더라도 안에 사소한 기능들을
생각해봐야 할 것들이 많아서, 순서도를 참고하면서 만들었다는 느낌보다 그냥 책을 참고하면서 만든 것 같다.
그리고 간단한 기능을 구현하는것도 시간이 꽤나 걸려서 진이 빠졌었다.
(예를 들어 참가자 숫자 변하도록 하기 같은)
그래도 난생 처음으로 무언가를 만들어보는 경험이었고, 남들에게 프로젝트라고 하기에도 창피한 수준이지만..
지금의 나에게는 프로젝트라고 할만한 정도의 난이도였다. 하지만 무조건 점점 나아질 것이다.
이런 간단한 끝말잇기를 구현하는것도 이렇게 시간이 오래 걸리는데, 현재의 세상에서는 인공지능이나 로봇 같은
지구의 게임 체인저들이 더 발전하고 새롭게 등장하고 있다니.. 그리고 이런 세상을 바꿔놓은것이 컴퓨터의 탄생
이라는 것이 너무 흥미롭다. 그리고 그 컴퓨터를 탄생시킨게 인류라는 것에 자부심과 존경심을 느낀다.