DOM 객체 다루기 - 끝말잇기
0. 순서도 그리기 (프로그래밍 사고력 기르기)
모든 프로그램을 만들 땐 순서도를 먼저 작성해야 함!
1) 프로그램은 항상 '고정된 절차'로 돌아가야 함 (모든 예시가 성립할 수 있도록)
- 절차 수, 내용이 항상 같아야 함 -> '몇'이나 '어떤' 같은 불특정 수식어 사용
- '예'는 절차를 다 만들고 검증할 때 사용
2) 모든 가능성 고려 : 틀렸을 경우까지
3) 처음부터 완벽할 필요는 없다! 시행착오를 겪으며 보완하기
1. 화면 만들고 참가자 수 입력받기
프로그램은 크게 두 가지, '화면이 있는 프로그램'과 '화면이 없는 프로그램'으로 나눌 수 있음
- 화면 있는 경우
- 화면 그리는 과정도 순서도에 포함해야 함
- 웹브라우저에서 돌아가는 프로그램은 HTML, CSS, 자바스크립트라는 세가지 언어 사용
- HTML: 화면 요소 담당, CSS: 화면 요소의 디자인 담당, 자바스크립트: 프로그램의 동작 담당
- -> HTML과 CSS로 화면 만들고 자바스크립트에 동작 맡기
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>끝말잇기</title>
</head>
<body>
<div><span id="order">1</span>번째 참가자</div>
<div>제시어: <span id="word"></span></div>
<input type="text">
<button>입력</button>
<script>
##자바스크립트 동작 코드는 이 곳에 작성##
</script>
</body>
</html>
- 참가자 수 입력받기
※ 입력창을 여는 방법: input 태그 사용 또는 prompt 메서드 사용
const number = Number(prompt('참가자는 몇 명인가요?'));
#prompt() 메서드로 입력창 열기 -> 참가자가 몇 명인지 입력받아 number 변수에 저장
#(Number()로 문자열을 숫자로 변환)
2-1. 첫 번째 참가자인지 판단하기
- 몇 명이 참가할지 선택한 후, 참가자들의 순서는 참여하는 순서에 따라 자동으로 부여되므로 따로 코딩할 필요는 없음
- 이제 단어를 입력한 사람이 첫 번째 참가자인지 아닌지를 판단해야 함
(이를 판단해야 하는 이유: 첫 번째 참가자인지 아닌지에 따라 수행할 동작이 달라지기 때문. 단어를 입력하는 프로세스는 돌고 돌아 반복되어야 하기 때문에 모든 순서의 참가자에게 적용되어야 함.)
※ 그 전에 HTML 태그에 단어를 입력하는 input 이벤트와 입력 버튼을 클릭하는 click 이벤트를 먼저 달아준다.. (왜 이걸 해야 하는지 아직은 모르겠지만 비동기를 알아야 할 것 같음)
➡️ 함수를 만들고 각 이벤트를 함수와 연결
그리고 입력한 단어를 저장할 newWord 변수 선언
const number = Number(prompt('참가자는 몇 명인가요?')); #참가자 수 입력받기
const $input = document.querySelector('input'); #<입력 필드> input 태그 선택 -> $input 변수에 저장
const $button = document.querySelector('button'); #<버튼> button 태그 선택 -> $button 변수에 저장
let newWord; #현재 단어(사용자가 입력한 단어)
const onInput = (event) => {
newWord = event.target.value; #입력한 단어를 newWord에 저장 (현재 단어 = 이벤트가 발생한 대상 객체의 단어)
};
#단어를 입력을 감지하는 onInput 함수 만들기
const onClickButton = () => {
};
#입력 버튼 클릭을 감지하는 onClickButton 함수 만들기
$input.addEventListener('input', onInput); #input 이벤트 발생 시 onInput 함수 호출 ($input(태그)에 onInput 함수 연결)
$button.addEventListener('click', onClickButton); #click 이벤트 발생 시 onClickButton 함수 호출 ($button(태그)에 onClickButton 함수 연결)
(아직 태그의 개념을 잘 모르겠는데 HTML의 영역인가?)
2-2. 제시어가 비어 있는지 판단하기
빈 값을 가진 #word 태그 이용(제시어 넣기) - 절차 수정: '첫 번째 참가자인가?' -> '제시어가 비어 있는가?'
let newWord;
let word; #제시어
const onInput = (event) => {
newWord = event.target.value;
};
const onClickButton = () => {
if (!word) { #제시어가 비어 있는가?(!word = true)
#비어 있음
} else {
#비어 있지 않음
}
};
#비어 있음 -> 입력한 단어가 제시어가 된다(입력한 단어를 제시어에 저장한다 + 제시어를 화면에 표시한다)
const $word = document.querySelector('#word'); #제시어가 되었음을 보여주기 위해 #word태그를 통해 화면에 표시
let newWord; #현재 단어
let word; #제시어
const onInput = (event) => {
newWord = event.target.value; #입력한 단어를 현재 단어로 저장
};
const onClickButton = () => {
if (!word) { #제시어가 비어 있는가?
word = newWord; #입력한 단어가 제시어가 됨
$word.textContent = word; #화면에 제시어 표시
} else {
#비어 있지 않음
}
};
#비어 있지 않음 -> 제시어에 맞는 단어인가?
const onClickButton = () => {
if (!word) { #제시어가 비어 있는가?
word = newWord; #입력한 단어가 제시어가 됨
$word.textContent = word; #화면에 제시어 표시
} else {
if (word.at(-1) === newWord[0]) { #제시어에 맞는 단어인가?
#맞는 단어
word = newWord; #현재 단어를 제시어에 저장
$word.textContext = word; #화면에 제시어 표시
} else { #틀린 단어
}
}
};
#맞는 단어 -> 현재 단어를 제시어에 저장, 화면에 제시어 표시 -> 다음 참가자에게 차례를 넘긴다
(제시어가 비어 있는 경우에도 똑같이 추가)
const $order = document.querySelector('#order'); #1. #order태그를 선택해 order 변수에 저장
const onClickButton = () => {
if (!word) { #제시어가 비어 있는가?
word = newWord; #입력한 단어가 제시어가 됨
$word.textContent = word; #화면에 제시어 표시
const order = Number($order.textContent); #2. 현재 순서 파악(order태그 내부의 값을 꺼내 숫자로 변환하고 이를 order 변수에 저장)
if (order + 1 > number) {
$order.textContent = 1;
} else {
$order.textContent = order + 1;
}
} else { #비어 있지 않음
if (word.at(-1) === newWord[0]) { #제시어에 맞는 단어인가?
#맞는 단어
word = newWord; #현재 단어를 제시어에 저장
$word.textContext = word; #화면에 제시어 표시
const order = Number($order.textContent); #2. 현재 순서 파악(order태그 내부의 값을 꺼내 숫자로 변환하고 이를 order 변수에 저장)
if (order + 1 > number) {
$order.textContent = 1;
} else {
$order.textContent = order + 1;
}
} else { #틀린 단어
}
}
};
#틀린 단어 -> 화면에 틀린 단어라고 표시
} else { #비어 있지 않음
if (word.at(-1) === newWord[0]) { #제시어에 맞는 단어인가?
#맞는 단어
word = newWord; #현재 단어를 제시어에 저장
$word.textContext = word; #화면에 제시어 표시
const order = Number($order.textContent); #현재 순서 파악(order태그 내부의 값을 꺼내 숫자로 변환하고 이를 order 변수에 저장)
if (order + 1 > number) {
$order.textContent = 1;
} else {
$order.textContent = order + 1;
}
} else { #틀린 단어
alert('틀린 단어입니다!');
}
}
};
3. 실행해보고 수정
- 이전 참가자가 입력하고 다음 참가자로 넘어간 후
$input.value = ''; #입력창을 비움
$input.focus(); #커서를 위치시킴
const onClickButton = () => {
if (!word) { #제시어가 비어 있는가?
word = newWord; #입력한 단어가 제시어가 됨
$word.textContent = word; #화면에 제시어 표시
const order = Number($order.textContent);
if (order + 1 > number) {
$order.textContent = 1;
} else {
$order.textContent = order + 1;
}
$input.value = ''; #입력창을 비움
$input.focus(); #커서를 위치시킴
} else { #비어 있지 않음
if (word.at(-1) === newWord[0]) { #제시어에 맞는 단어인가?
#맞는 단어
word = newWord; #현재 단어를 제시어에 저장
$word.textContext = word; #화면에 제시어 표시
const order = Number($order.textContent); #2. 현재 순서 파악(order태그 내부의 값을 꺼내 숫자로 변환하고 이를 order 변수에 저장)
if (order + 1 > number) {
$order.textContent = 1;
} else {
$order.textContent = order + 1;
}
$input.value = ''; #입력창을 비움
$input.focus(); #커서를 위치시킴
} else { #틀린 단어
alert('틀린 단어입니다!');
$input.value = ''; #입력창을 비움
$input.focus(); #커서를 위치시킴
}
}
};
4. 순서도 최적화하기
1) 순서도에서 중복되는 부분 최적화
2) 순서도에서는 중복되지 않으나 코드에서 중복되는 부분 최적화
3) 끝말잇기에서는 단어가 틀렸더라도 다시 기회 줌. 따라서 끝을 나타내는 표시 필요하지 않음
4) 합칠 수 있는 부분은 합쳐서 절차 줄이기 - 표를 만들어서 OR 관계, AND 관계 판단