FE (Front End) (구)/javascript

js chatbot 챗 봇 만들기 기초 연습

B_Tae 2022. 3. 27. 21:09

연습용 챗봇 만들기

서버를 다루지 못해 js코드만 사용했다. 

 

함수 외 선언

    let count = 0; // 조건문을 선택하는 길잡이
    let container = document.getElementById('container');
    let retext = document.getElementById('retext'); // 봇 대답 텍스트
    let addQuestion; // 등록 질문
    let addAnswer; // 등록 답변
    let commend = [ // 질문과 답변에 배열
      {
        'question' : '안녕',
        'answer' : '안녕 냥~',
      },
      {
        'question' : '잘가',
        'answer' : '잘가라 냥~',
      },
      {
        'question' : '불꺼줘',
        'answer' : function(){
          retext.innerHTML = '불을 꺼줬다 냥'
          retext.style.color = '#fff'
          container.style.backgroundColor = '#000';
        },
      },
      {
        'question' : '불켜줘',
        'answer' : function(){
          retext.innerHTML = '불을 켜줬다 냥';
          retext.color = '#000';
          container.style.backgroundColor = '#fff';
        },
      },
      {
        'question' : '따',
        'answer' : '안녕 냥~',
      },
      ]

하나의 함수 내에 상황에 따라 여러 조건문을 사용하기 위한 길잡이 역할의 변수 count를 선언 

변경될 html태그를 가져오기 container , retext

추가로 질문과 답변을 등록하기 위한 임의의 변수 선언(등록되지 않은 대화를 배우기 위한) addQuestion , addAnswer

기본적으로 등록한 대화를 객체형태의 배열로 선언 commend 

객체형태의 배열이 아닌 따로 조건문을 사용하여 실행해도 무방함 ( 이렇게 사용할 경우 조건의 ||(or)등을 사용하여 대화의 다체로운 변화를 주기가 용이하다.)

 

 

 

함수 내부 1

function chat(){
      let value = document.getElementById('chat_text'); // 입력하는 input태그

      for(let i = 0; i < commend.length ; i ++){
        if(value.value == commend[i].question){ // 배열을 순회하여 조건 찾기
         if(typeof(commend[i].answer) == 'string'){ 
           retext.innerHTML = commend[i].answer; // 답이 문자열이면 그대로 내용 변경
           value.value = ""; // 작성 칸 초기화
           return; // 해당되면 해당 값 반환 후 함수 종료
         }else{
           let fn = commend[i].answer;
           fn();                                //  답이 함수면, 함수 실행
           value.value = ""; // 작성 칸 초기화
           return; // 해당되면 해당 값 반환 후 함수 종료
         }        
        }
      }
      retext.innerHTML = '모르겠어요 <br> 말을 가르쳐 주실래요? (네, 아니요)'; // 값을 찾지 못하면 실행되는 질문

      /*(조건 코드 생략)*/

      count = 1;  // 다음 실행에는 조건문 1에 해당
      addQuestion = value.value;  // 전에 작성한 질문 저장
      value.value = "";  // 작성 칸 초기화
    }

기본 구조는 위에 코드를 갖는다. 

 

입력 받은(질문 받은) 값을 미리 정한 대화에 있는지 배열을 순회하여 찾기

값의 답을 찾고 그 값이 문자열이라면 대답 text에 표시, 만약 함수라면 함수를 실행 ( 숫자나 불린 등 다른 문자열은 사용 안했지만, 조건문을 추가로 활용 할 수 있다.)

 

만일 정해둔 답에 값이 없다면, 위에 텍스트를 작성하고, 생략된 다음 조건문에 부합할 수 있도록 count를 1로 재선언 

및 답이 없던 질문을 새로운 변수에 할당[addQuestion] ( 질문을 등록하기 위함)

 

 

위 코드에 생략된 함수 내 코드

      if(count === 1){
        if(value.value === '네'){
          retext.innerHTML = `(${addQuestion})에 해당되는 답을 작성해 주세요` // 전에 작성한 진문에 대한 답 요구
          count = 2; // 다른 조건문으로 연결
          value.value = ""; // 작성 칸 초기화
          return;
          
        }else if(value.value === '아니요'){
          retext.innerHTML = '아쉽다 냥~'
          count =0; // 처음 상태
          value.value = ""; // 작성 칸 초기화
          return;
        }else{
          alert('대답을 하지 않으셨습니다.');
        }
      }

      if(count === 2){
        addAnswer = value.value;
        retext.innerHTML = `${addQuestion}이라는 질문에<br>${addAnswer}의 답변이 등록 됐습니다.`
        commend.push({question: addQuestion , answer: addAnswer + ` 냥 ~ `});
        count = 0;
        value.value = ""; // 작성 칸 초기화
        return;
      }

함수를 한 번 실행하게되면 count 값은 1이 되고, 그 다음 함수를 실행하면 (실행 후 기존 답이 없다는 가정하에) 

대답이 '네'인 경우 기존에 할당한 질문에 대한 답을 요구하고 count 2로 재선언하여 새로운 조건문에 부합을 시킨다.

대답이 '아니요'인 경우에는 count를 0으로 선언하여 초기화한다.

 

'네' 대답 후 다시 함수를 실행시키게 되면, count가 2임으로 질문과 답변을 기존 배열에 추가한다. 

 

 

여기서 서버에 저장하지 않기 때문에 새로고침을 하면 저장한 내용이 초기화된다. 

 

 

 


아주 기본만 알고 기본기만 사용하여 작성한 코드입니다. 많은 오류가 있을 것 같네요..... 기회가 된다면 더 깔끔하고 오류 없는 코드로 돌아오겠습니다.


전체 코드

    let count = 0; // 조건문을 선택하는 길잡이
    let container = document.getElementById('container');
    let retext = document.getElementById('retext'); // 고양이 대답 글
    let addQuestion; // 등록 질문
    let addAnswer; // 등록 답변
    let commend = [ // 질문과 답변에 배열
      {
        'question' : '안녕',
        'answer' : '안녕 냥~',
      },
      {
        'question' : '잘가',
        'answer' : '잘가라 냥~',
      },
      {
        'question' : '불꺼줘',
        'answer' : function(){
          retext.innerHTML = '불을 꺼줬다 냥'
          retext.style.color = '#fff'
          container.style.backgroundColor = '#000';
        },
      },
      {
        'question' : '불켜줘',
        'answer' : function(){
          retext.innerHTML = '불을 켜줬다 냥';
          retext.color = '#000';
          container.style.backgroundColor = '#fff';
        },
      },
      {
        'question' : '따',
        'answer' : '안녕 냥~',
      },
      ]
    function chat(){
      let value = document.getElementById('chat_text'); // 입력하는 input태그

      for(let i = 0; i < commend.length ; i ++){
        if(value.value == commend[i].question){ // 배열을 순회하여 조건 찾기
         if(typeof(commend[i].answer) == 'string'){ 
           retext.innerHTML = commend[i].answer; // 답이 문자열이면 그대로 내용 변경
           value.value = ""; // 작성 칸 초기화
           return; // 해당되면 해당 값 반환 후 함수 종료
         }else{
           let fn = commend[i].answer;
           fn();                                //  답이 함수면, 함수 실행
           value.value = ""; // 작성 칸 초기화
           return; // 해당되면 해당 값 반환 후 함수 종료
         }        
        }
      }
      retext.innerHTML = '모르겠어요 <br> 말을 가르쳐 주실래요? (네, 아니요)'; // 값을 찾지 못하면 실행되는 질문

      
      if(count === 1){
        if(value.value === '네'){
          retext.innerHTML = `(${addQuestion})에 해당되는 답을 작성해 주세요` // 전에 작성한 진문에 대한 답 요구
          count = 2; // 다른 조건문으로 연결
          value.value = ""; // 작성 칸 초기화
          return;
          
        }else if(value.value === '아니요'){
          retext.innerHTML = '아쉽다 냥~'
          count =0; // 처음 상태
          value.value = ""; // 작성 칸 초기화
          return;
        }else{
          alert('대답을 하지 않으셨습니다.');
        }
      }

      if(count === 2){
        addAnswer = value.value;
        retext.innerHTML = `${addQuestion}이라는 질문에<br>${addAnswer}의 답변이 등록 됐습니다.`
        commend.push({question: addQuestion , answer: addAnswer + ` 냥 ~ `});
        count = 0;
        value.value = ""; // 작성 칸 초기화
        return;
      }
      
      count = 1;  // 다음 실행에는 조건문 1에 해당
      addQuestion = value.value;  // 전에 작성한 질문 저장
      value.value = "";  // 작성 칸 초기화
    }

    const act = document.getElementById('act');
    act.addEventListener('click', chat);