'끝말잇기 놀이' 절차적인 사고력 훈련하기😁
(✨순서도 그리고 점차적으로 수정·보완하기!)
순서도는 일단 손으로 그리는 것이 좋고, 대략적으로 그려서 코드로 옮기다가 막히는 부분이 있다면 막힌 절차를 다시 세부 순서도로 쪼개보기;>
📌 how to study
자바스크립트 언어만 파고들지 말고, 전체적인 흐름과 순서도 그리는 연습을 중점적으로 학습하기!
생각한 절차를 어떻게 코드로 구현할 것인가 생각하는 연습하기!
✨ 순서도 Tip!
input 대기창에 글자를 입력하기 전까지는 대기 상태가 발생하고, 글자를 입력하면 프로그램이 재개된다.
프로그램에 '대기 상태'가 항상 존재하기 때문에 버튼 클릭이나 이벤트 발생할 때는 순서도 중간에 끊어주는 것이 필요하다. 이것은 순서도를 보고 코드로 옮겨주기 편하다.
제시어 여부에 따라 시작 전 또는 진행 중임을 판단할 수 있다.
제시어가 없다면 => 게임을 처음 시작하는 상황이므로 첫 번째 참가자이다!
제시어가 있다면 => 이전 사람이 말한 단어가 저장되어 있으므로 첫번째 참가자가 아니다!
데이터를 바꿨다면 데이터가 표시되는 화면도 바꿔줘야 한다. (둘이 짝꿍!💑)
const $input = document.querySelector('input'); // 입력창
const $word = document.querySelector('#word'); // 제시어 js 선택자
let word; // 제시어
let newWord; // 새로 입력한 단어
const onClickButton = () => {
if (!word) { // 제시어가 비어 있는 경우
word = newWord; // 입력한 단어가 제시어가 된다.
$word.textContent = word; // 화면에 제시어 표시
$input.value = ''; // input 입력창 빈칸으로 설정
} else { // 제시어가 비어있지 않은 경우
// 올바른 단어인지 판단하기
}
};
2-1. 조건: 제시어의 마지막 글자와 새로 입력한 단어의 첫번째 글자가 같은지 비교
2-2. 올바른 단어임을 확인했으므로 현재 참가자는 게임 종료, 다음 사람에게 순서를 넘겨 계속해서 게임을 진행한다.
다음 사람에게 순서를 넘기기 전, 현재 몇 번째 참가자인지 확인이 필요하다.
예를 들어 참가자가 3명인 경우, 1->2->3 순으로 진행되는데 3번 다음에 다시 1번으로 되돌아가야 한다.
조건: 참가자 인원과 현재 참가자 순번을 비교
const $input = document.querySelector('input'); // 입력창
const $word = document.querySelector('#word'); // 제시어 js 선택자
const $order = document.querySelector('#order'); // 참가자 순서 js 선택자
let word; // 제시어
let newWord; // 새로 입력한 단어
const onClickButton = () => {
if (!word) {
... // 1. 첫번째 사람인지 판단하기 참고
const order = Number($order.textContent); // 숫자로 형변환한 참가자 순서를 변수에 저장
if (order + 1 > number) { // 2-2. 현재 참가자 순서 확인하기(order === number 조건도 가능)
$order.textContent = 1; // 🤔 변수를 대신 order로 사용하면 안될까?
} else {
$order.textContent = order + 1; // 🤔 order += 1;은 안될까?
}
} else { // 제시어가 비어있지 않은 경우
if (word[word.length - 1] === newWord[0]) { // 2-1. 올바른 단어인 경우
word = newWord; // 입력한 단어가 제시어가 된다.
$word.textContent = word; // 화면에 제시어 표시
$input.value = ''; // input 입력창 빈칸으로 설정
$input.focus(); // input 입력창 커서를 두어 바로 입력할 수 있도록 함
// 제시어가 있고, 올바른 경우에도 해당 코드 실행
const order = Number($order.textContent);
if (order + 1 > number) {
$order.textContent = 1;
} else {
$order.textContent = order + 1;
}
} else { // 올바르지 않은 단어인 경우
alert('올바르지 않은 단어입니다!'); // 틀렸을 때 화면에 오류 표시
$input.value = '';
$input.focus();
}
}
};
제시어가 비어있는 경우와 올바른 단어인 경우 실행되는 코드가 동일하다.
(순서도를 토대로 코드를 작성했기 때문에 동일함을 확인할 수 있다.)
이후에 중복된 코드 제거하여 최종적으로 코드 정리!
값을 잠깐 저장해두기 위함과 순서를 비교하기 위한 숫자 형태의 값으로 변환하여 변수에 저장한다.
textContent는 항상 문자열이므로 parseInt 또는 Number를 이용해 숫자로 형변환해줘야 한다.
<태그의 내부 값을 가져올 때 사용하는 속성>
입력태그.focus() : 입력창을 하이라이트함으로써 입력태그 내부에 커서가 위치하게 되어 다음에 사용자가 입력하기 편함
➕ 단축키 Shift + Alt + F : 들여쓰기 정렬
여러개의 분기(순서도에서 '예/아니오'에 따라 코드가 달리 실행되는 마름모 모양) 결과값이 동일한 코드를 실행하는 경우, 중복되는 코드를 줄이기 위해 분기를 합쳐 순서도 최적화하기
// 원래 코드
if (!word) {
...
}
if (word[word.length - 1] === newWord[0]) {
... // 위의 if문에서 실행되는 코드와 동일한 코드
}
/* -------------------------------------------- */
// 두 개의 분기 합쳐 중복 제거한 코드
if (!word || word[word.length - 1] === newWord[0]) {
... // 조건을 하나로 합쳐 실행되는 코드를 한번만 작성
}
'제시어가 비어 있는가?'의 조건과 '올바른 단어인가?'의 조건 각각 '예'인 경우, 동일한 코드가 실행되므로 조건을 논리 연산자 OR(||)로 합칠 수 있다. (많은 훈련이 필요😭)
=> A 경우이거나 B 경우일 때 실행되므로 '또는' 관계를 가지는 형태가 되어 하나의 분기로 합칠 수 있음을 이해!
이에 따라, A 경우와 B 경우 모두 아닐 때 다른 코드가 실행된다.
쿵쿵따 게임 (끝말잇기 심화)
추가 조건: ① 제시어는 세글자의 단어만 가능
② 참가 인원 작성하는 prompt창에 입력하지 않고 취소버튼을 누르면, 단어 입력하지 못하고 실행 종료
① '올바른 단어인지 판단'하는 원래 조건에 추가하여 두가지 조건을 모두 만족하도록 논리 연산자 AND(&&)를 사용해 조건을 작성
let word; // 제시어
let newWord; // 새로 입력한 단어
// 논리연산자 우선순위: not(!) > AND(&&) > OR(||)
// 제시어가 비어있는가 OR (단어가 올바른가 AND 단어가 세글자인가)
// => 제시한 단어가 비어있거나 단어가 올바르고 세글자인가?
// OR 보다 AND의 우선 순위가 높으므로 괄호를 사용해 이해하기 쉽게 표현!😊
if(!word || (word[word.length - 1] === newWord[0] && newWord.length === 3))
② 취소버튼을 누르면 prompt 함수값은 null이 되고,
숫자형으로 변환하는 Number 함수에 들어가면 NaN이 된다.
즉, NaN은 if문에 들어가면 항상 false로 취급되므로 조건문 실행 불가
const number = Number(prompt('참가 인원은 몇명입니까?'));