Javascript & Node.js

DOM 객체 다루기 - 끝말잇기

지문어 2025. 1. 8. 16:16

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 관계 판단