본문 바로가기
모바일 앱

ChatGPT로 수익 창출 앱 만들기 - MBTI 테스트 앱 제작하기

by 온수저 2023. 5. 18.
반응형

 

MBTI 테스트 앱 제작하기

 

이번 시간에는 MBTI 유형 분석 앱을 구상해보고 웹 앱까지 만들어보겠습니다.

 

목차

1. MBTI란?

2. 앱 요구사항

3. 기본 코드 생성하기

4. 시작화면 수정하기

5. 질문화면 수정하기

6. 결과화면 수정하기

7. 마무리

 

 

1. MBTI란?

 
MBTI는 사람의 성격 유형을 E/I, S/N, T/F, J/P 네가지로 구분합니다. 이 조합으로 총 16가지 성격 유형이 만들어집니다. 챗GTP의 답변에는 안나오지만 A/T라는 지표도 있는데 덜 중요하기 때문에 이건 생략하도록 하겠습니다.
 
잘 알려진 무료 MBTI 검사 서비스로 16personalities.com 이 있습니다. 16personalities 사이트에서 MBTI 검사를 진행해보며 캡처를 해보았습니다.

 

왼쪽부터 순서대로 검사 시작 화면, 하단 진행률 표시, 검사 결과 표시


위 사이트를 참고로 하여 우리가 만들 앱에서도 각 유형에 해당하는 질문을 하고 그에 대한 답변의 합으로 사용자의 MBTI를 유추하여 거기에 해당하는 결과 화면을 보여주는 식으로 만들면 될 것같습니다. A유형 질문에 대한 답변들의 합과 B유형 답변들의 합을 비교해서 더 큰 쪽으로 A/B 유형을 구분하는 방식입니다. 두 값이 동일한 경우는 따로 처리해야할 것 같습니다. 나중에 고민해보기로 하고 일단 앱 요구사항을 생각해 보겠습니다.
 

2. 앱 요구사항

앞에서 살펴본 서비스를 참고하여 우리가 만들 앱의 기능이나 화면 구성에 대해 고민해봅니다.
 
기능
사전에 준비된 질문을 사용자에게 순서대로 보여줍니다.
사용자는 버튼을 눌러 답변 할 수 있습니다.
답변은 매우아니다, 아니다, 모르겠다, 그렇다, 매우그렇다 다섯가지 입니다.
각각의 답변에는 -2에서 2까지의 숫자 값을 할당합니다.

질문은 30개로 MBTI유형별로 추가하거나 수정하기 쉬운 형태로 준비합니다.
모든 질문에 답변이 완료되면 테스트 결과 화면을 보여줍니다.
테스트 결과 화면에는 MBTI 유형과 "모험가"와 같은 성격 유형을 보여주고 설명을 같이 보여줍니다.
결과 화면에 성격유형과 어울리는 캐릭터나 이미지를 같이 보여주면 좋겠습니다.
 
화면구성

화면은 시작, 질문, 검사결과 화면으로 세부분으로 나뉩니다.

배경이미지가 화면 전체로 고정되어 보여집니다.

사이트 접속시 시작화면만 보입니다.

시작, 질문, 검사결과 화면은 화면 중앙에 카드스타일로 배치합니다.

 

- 시작 화면

화면 상단에 MBTI 테스트 라는 제목을 표기합니다.

로고 이미지를 배치합니다.
MBTI 테스트 앱의 사용방법을 간단하게 설명합니다.

하단에 "시작하기" 버튼을 보여줍니다.

 

- 질문 화면
상단에 질문 단계와 총 질문 개수를 표시합니다.

질문 개수 아래 MBTI 유형에 관련된 질문을 보여줍니다.

질문 아래로 매우아니다, 아니다, 모르겠다, 그렇다, 매우그렇다 답변 버튼을 배치합니다.

 

- 결과 화면

상단에 MBTI 유형을 보여줍니다.

MBTI 유형 아래로 "모험가", "중재자"와 같은 성격 유형과 관련 캐릭터 이미지를 보여줍니다.

성격 유형 아래로 MBTI 유형에 대한 설명을 보여줍니다.

하단에는 시작화면으로 되돌아가기 버튼과 공유하기 버튼을 배치합니다.

 

일단 이정도로만 생각해서 ChatGPT에게 요청해보도록 하겠습니다.

 

3. 기본 코드 생성하기

 위 요구사항대로 ChatGPT에게 코드 작성을 요청해봅니다. 먼저 ChatGPT에게 웹앱 개발 전문가라는 역할을 부여하고 위 요구사항을 그대로 넣어줍니다.

 

당신은 모바일 웹앱 개발 전문가 입니다. 아래 요구사항을 참고해서 MBTI 유형 분석 모바일 웹앱 코드를 작성해 주세요.

기능
사전에 준비된 질문을 사용자에게 순서대로 보여줍니다.
... 중략

- 결과 화면
... 중략
하단에는 시작화면으로 되돌아가기 버튼과 공유하기 버튼을 배치합니다.

 

아래는 몇번의 요청 후 얻은 코드 입니다. 작업 폴더 C:\myapp\mbti_01 에 각각의 파일을 생성해주세요.

 

index.html 파일

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <title>MBTI 테스트</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="start-screen" class="screen">
        <div class="card">
            <h1>MBTI 테스트</h1>
            <img src="logo.png" alt="로고 이미지">
            <p>MBTI 테스트 앱의 사용방법을 간단하게 설명합니다.</p>
            <button id="start-button">시작하기</button>
        </div>
    </div>

    <div id="question-screen" class="screen">
        <div class="card">
            <h2 id="question-counter">Question 1 of 30</h2>
            <p id="question">질문 내용</p>
            <div class="answer-buttons">
                <button class="answer-button" data-value="-2">매우 아니다</button>
                <button class="answer-button" data-value="-1">아니다</button>
                <button class="answer-button" data-value="0">모르겠다</button>
                <button class="answer-button" data-value="1">그렇다</button>
                <button class="answer-button" data-value="2">매우 그렇다</button>
            </div>
        </div>
    </div>

    <div id="result-screen" class="screen">
        <div class="card">
            <h2 id="result-type">MBTI 유형</h2>
            <img id="result-image" src="character.png" alt="캐릭터 이미지">
            <p id="result-description">MBTI 유형에 대한 설명</p>
            <button id="restart-button">시작화면으로 되돌아가기</button>
            <button id="share-button">공유하기</button>
        </div>
    </div>

    <script src="app.js"></script>
</body>
</html>

 

styles.css 파일

/* styles.css */

/* 전체 화면 스타일 */
body {
  margin: 0;
  padding: 0;
  font-family: Arial, sans-serif;
  background-image: url("background.jpg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  background-attachment: fixed; /* 배경 이미지를 고정으로 설정 */
}

/* screen 영역 스타일 */
.screen {
  display: flex;
  min-height: 100vh;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
}

.card {
  display: inline-block;
  max-width: calc(100vw - 20px); /* 최대 가로 사이즈 설정 */
  margin: 20px;
  padding: 20px;
  text-align: center;
  background-color: rgba(255, 255, 255, 0.85); /* 반투명한 배경 색상 설정 */
  border-radius: 10px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); /* 그림자 효과 추가 */
}

/* 시작 화면 스타일 */
#start-screen {}

#start-screen .card {}

#start-screen h1 {
  font-size: 24px;
  margin-bottom: 20px;
}

#start-screen img {
  width: 200px;
  margin-bottom: 20px;
}

#start-screen p {
  font-size: 16px;
  margin-bottom: 20px;
}

#start-button {
  background-color: #007bff;
  color: #fff;
  padding: 10px 20px;
  font-size: 16px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

/* 질문 화면 스타일 */
#question-screen {}

#question-screen .card {}

/* 결과 화면 스타일 */
#result-screen {}

#result-screen .card {}

/* 기타 모바일 화면에 최적화된 스타일링 */
/* 추가적인 스타일링 요구사항에 따라 구현 가능 */

 

app.js 파일

// app.js
// JavaScript 코드를 이용해 동적인 동작을 구현합니다.

// 질문 데이터
const questions = [
  {
      question: "질문 1",
      type: "A",
  },
  {
      question: "질문 2",
      type: "B",
  },
  // 나머지 질문들...
];

let currentQuestionIndex = 0;
let answers = [];

const startScreen = document.getElementById("start-screen");
const questionScreen = document.getElementById("question-screen");
const resultScreen = document.getElementById("result-screen");

// 시작 화면 보이기
startScreen.style.display = "flex";
// 질문 화면 숨기기
questionScreen.style.display = "none";
// 결과 화면 숨기기
resultScreen.style.display = "none";

const startButton = document.getElementById("start-button");
const questionCounter = document.getElementById("question-counter");
const questionElement = document.getElementById("question");
const answerButtons = document.getElementsByClassName("answer-button");
const resultType = document.getElementById("result-type");
const resultImage = document.getElementById("result-image");
const resultDescription = document.getElementById("result-description");
const restartButton = document.getElementById("restart-button");
const shareButton = document.getElementById("share-button");

// "시작하기" 버튼 클릭 시 질문 화면으로 전환
startButton.addEventListener("click", () => {
  startScreen.style.display = "none";
  questionScreen.style.display = "flex";
  showQuestion();
});

// 답변 버튼 클릭 시 다음 질문 또는 결과 화면으로 전환
for (let i = 0; i < answerButtons.length; i++) {
  answerButtons[i].addEventListener("click", () => {
      const value = parseInt(answerButtons[i].dataset.value);
      answers.push(value);

      if (currentQuestionIndex < questions.length - 1) {
          currentQuestionIndex++;
          showQuestion();
      } else {
          showResult();
      }
  });
}

// 질문을 보여줍니다.
function showQuestion() {
  const question = questions[currentQuestionIndex];
  questionCounter.textContent = `Question ${currentQuestionIndex + 1} of ${questions.length}`;
  questionElement.textContent = question.question;
}

// 결과 화면을 보여줍니다.
function showResult() {
  questionScreen.style.display = "none";
  resultScreen.style.display = "flex";

  // 결과 계산 및 처리
  const result = calculateResult(); // 결과 계산 함수 구현 필요
  resultType.textContent = result.type;
  resultImage.src = result.image;
  resultDescription.textContent = result.description;
}

// "시작화면으로 되돌아가기" 버튼 클릭 시 시작 화면으로 전환
restartButton.addEventListener("click", () => {
  resultScreen.style.display = "none";
  startScreen.style.display = "flex";
  resetTest();
});

// "공유하기" 버튼 클릭 시 공유 기능 구현 (예: SNS 공유 링크 생성)
shareButton.addEventListener("click", () => {
  // 공유 기능 구현
});

// 테스트 초기화
function resetTest() {
  currentQuestionIndex = 0;
  answers = [];
}

// 결과 계산 함수 구현
function calculateResult() {
  // 결과 계산 및 처리 로직 구현
  // MBTI 유형, 캐릭터 이미지, 설명 등을 반환
}

 

ChatGPT가 자바스크립트 파일의 코드중 함수 몇개는 직접 구현 해보라고 알려주지 않았네요. 나중에 다시 물어보고 채우도록 하겠습니다.

 

background.jpg와 logo.png 파일을 index.html 파일과 동일한 경로에 넣어주고 브라우저를 열어 확인해 보겠습니다. 예제에 사용된 이미지는 글 하단의 첨부파일을 참고해주세요.

F12 키를 눌러 개발자 도구를 열어서 모바일 화면으로 확인합니다.

 

첫 코드 테스트 화면

 

그럴싸하게 만들어졌습니다만 아직 제대로 작동은 하지 않습니다. 시작 화면 부터 질문, 결과 화면까지 코드를 수정해 보겠습니다.

 

 

4. 시작화면 코드 수정하기

먼저 시작화면의 설명 부분을 수정하겠습니다.  Visual Studio Code에서 index.html 파일을 열어줍니다. 전체 파일 경로는 C:\myapp\mbti_01\index.html 입니다. 14 라인의 <p> 와 </p> 사이에 있는 기존 설명문구를 적당히 바꿔 줍니다.

 

 

그리고 로고이미지를 원형으로 바꾸고 움직이는 효과를 주면 좋겠습니다. 로고이미지의 css 코드를 ChatGPT에게 제시하고 수정 요청을 해보겠습니다. 시작화면의 로고에 해당하는 부분은 styles.css 파일 46 ~ 49 번 줄 코드 입니다.

 

 

그런데 이 코드를 적용해보니 로고가 너무 빨리 움직여서 조금 수정을 해야할 것 같습니다.. ChatGPT가 친절히 주석을 달아줘서 어떤 의미인지 유추가 가능하기에 아래와 같이 수정해서 적용 해보았습니다.

 

로고 이미지 원형, 애니메이션 효과 적용

 

수정사항을 저장하고 브라우저를 새로고침 해봅니다.

 

시작화면 수정 완료

 

시작화면 수정이 완료 되었습니다. 이어서 질문화면 코드를 수정해 보겠습니다. 시작하기 버튼을 눌러 질문하기 화면으로 넘어갑니다.

 

 

4. 질문화면 코드 수정하기 (어려움 주의)

 

 

현재 질문 데이터가 제대로 작성되어 있지 않아 제대로 표시가 되지 않고 있습니다. 질문을 30개 정도 추가하고 현재 질문 번호를 표시하는 부분 글자 배치와 크기를 좀 줄여 보겠습니다. 그리고 답변 버튼도 좀 키우고 세로로 배치 해보죠.

 

 

질문 번호 표시부분 수정하기

 

먼저 질문 번호 표시 부분을 수정해봅니다. 코드를 수정하기에 앞서 브라우저에서 먼저 적용되는 화면을 보면서 수정을 해보겠습니다.

 

 

크롬 브라우저 개발자 도구에서 1번의 요소 선택기를 클릭하고 2번 질문 개수 글자 부분을 클릭합니다. 그러면 3번 요소창에서 <h2 id="question-counter">Question 1 of 2</h2> 요소가 선택 되고 이 h2 요소에 적용된 스타일이 4번 부분에 표시 됩니다. h2 태그는 스타일을 설정하지 않아도 브라우저 자체적으로 기본적으로 적용되는 스타일이 있습니다. 그 내용이 4번 부분에 표시 되는데요. 캡쳐 이미지에서 보듯이 h2 태그는 기본 적용되는 스타일 때문에 h2 태그를 그대로 사용할 경우 수정할 부분이 많아 집니다. h2 태그를 div 태그로 바꿔 봅니다. 3번 부분에서 <h2 글자를 더블 클릭하면 HTML 편집 모드로 바뀝니다.

 

 

이 상태에서 h2를 div로 변경하고 주변 다른 부분을 클릭하면 끝에 </h2>도 자동으로 </div>로 바뀝니다. 그러면 h2 태그에 적용되었던 스타일이 해제되면서 아래 캡쳐 이미지와 같은 모양이 됩니다.

 

 

 

이어서 "Question 1 of 2" 글자도 "1 / 2"로 단순하게 변경해 보겠습니다. 앞에서 h2태그를 div로 바꾼 것 처럼 요소 창에서 "Question 1 of 2" 글자 부분을 더블 클릭해서 "1 / 2"로 수정합니다. 따옴표는 제외하고 입력하시면 됩니다.

 

그리고 질문번호를 좌측 정렬하기 위해 스타일을 적용해 봅니다. 1번 #question-counter div 요소를 클릭한 뒤에 2번 element.style { } 부분의 빈곳을 클릭하면 추가 입력모드로 전환이 되는데  text-align: left;  를 입력합니다. 그럼 3번 처럼 좌측 정렬이 되는것을 볼 수 있습니다.

 

질문번호 수정은 이정도로만 하겠습니다. 수정한 내용은 브라우저 상에서 임시로 적용되기 때문에 파일의 코드를 수정해야합니다. 먼저 h2 태그를 div로 수정하고 번호 표기 문구도 바꾸기 때문에 index.html 파일을 엽니다. 경로는 C:\myapp\mbti_01\index.html 입니다.

 

 

21번 라인 코드를 수정하였습니다. 이어서 styles.css 파일을 열어서 수정합니다.

 

 

#question-counter 부분이 없기때문에 94~96 라인을 추가해 주었습니다.

이렇게 수정하고 새로고침해서 확인해보면 좌측 정렬은 되었지만 문구는 여전히 "Question 1 of 2" 식으로 표기됩니다.

 

 

JavaScript 에서 question-counter 요소 내용을 동적으로 변경하고 있기 때문인데요. C:\myapp\mbti_01\app.js 파일을 열어 showQuestion 함수를 수정합니다.

 

questionCounter.textContent = `Question ${currentQuestionIndex + 1} of ${questions.length}`;

 

66번라인의 기존 코드를 아래와 같이 바꿔줍니다.

 

questionCounter.textContent = `${currentQuestionIndex + 1} / ${questions.length}`;

 

해당 부분의 코드는 아래와 같습니다.

 

파일의 변경 내용을 저장하고 브라우저 페이지를 새로 고침해봅니다.

 

 

이제 정상적으로 반영이 된것을 확인할 수 있습니다.

바로 버튼 수정을 해보겠습니다. styles.css 파일에서 #question-counter {} 아래에 다음 코드를 추가합니다.

 

button.answer-button {  display: block;  margin: 20px auto;  padding: 5px;  font-size: 1.1rem;  min-width: 200px;}

 

버튼부분도 수정이 되었습니다.

 

이번에는 질문을 추가해보겠습니다. MBTI 유형 EINSTFJP 각각에 해당하는 질문을 10개씩 준비해두고 유형별로 4개씩 뽑아서 총 32개의 질문을 할 수 있게 코드를 변경합니다. 먼저 질문과 관련 코드를 ChatGPT에게 요청합니다. 그리고 기존에 app.js 코드에서 questions 코드가 {question: 질문, type: "A"} 형식이었기 때문에 해당 형식으로 맞춰줄것을 요청합니다.

 

const questions = [
    {
        question: "질문 1",
        type: "A",
    },
    {
        question: "질문 2",
        type: "B",
    },
    // 나머지 질문들...
  ];

 

아래는 ChatGPT에게 연달아 요청한 프롬프트 입니다. 이제 ChatGPT에게 질문하는 방법이 익숙해졌으리라고 보고 질문과 결과 코드만 보여드리겠습니다.

 

MBTI 유형 코드 EINSTFJP 각각에 해당하는 질문들이 10개씩 있는데 유형 코드별로 임의로 4개씩 뽑는 방법. 자바스크립트 코드로 구현하세요

각 유형 코드에 대해 4개의 랜덤 질문을 뽑은 결과를 섞는 방법

allSelectedQuestions 에 {question: "질문", type: "E"} 형식의 질문 목록이 저장되게 수정

 

이렇게 받은 코드를 data.js 파일을 새로 만들어서 저장합니다.

 

C:\myapp\mbti_01\data.js 파일

// 각 유형 코드에 해당하는 질문들을 배열에 저장합니다.
const allQuestions = {
  E: [
    "당신은 사람들과 함께 있을 때 에너지를 얻는 편인가요?",
    "사회적인 행사에서 어떤 역할을 맡거나 주도적으로 참여하시는 편인가요?",
    "외부 환경과 사건들에 대한 관심과 호기심을 가지고 있나요?",
    "타인과 함께 일하면서 의사소통과 협업을 즐기시나요?",
    "새로운 사람들과 쉽게 친구가 되는 경향이 있나요?",
    "활동적인 환경에서 일하는 것을 선호하시나요?",
    "다른 사람들의 의견과 아이디어를 경청하고 반영하는 것을 좋아하시나요?",
    "타인과의 상호작용을 통해 아이디어와 에너지를 얻는 편인가요?",
  ],
  I: [
    "혼자만의 시간을 보내는 것을 즐기시나요?",
    "조용하고 고요한 장소에서 에너지를 얻는 편인가요?",
    "내면적인 세계와 개인적인 경험에 대한 관심이 많나요?",
    "혼자서 과제를 수행하거나 사고를 깊게 하는 것을 선호하시나요?",
    "깊은 관계를 형성하는 데 시간이 걸리지만 오래 유지하는 편인가요?",
    "조용하고 평온한 환경에서 일하는 것을 선호하시나요?",
    "자신만의 생각과 아이디어를 중요시하는 경향이 있나요?",
    "혼자 있는 동안에도 내적으로 풍부한 상상력과 아이디어를 가지고 있나요?",
  ],
  N: [
    "미래에 대한 비전과 가능성에 관심과 흥미를 가지고 있나요?",
    "추상적인 개념과 이론에 대해 탐구하고 이해하려는 경향이 있나요?",
    "새로운 아이디어와 가능성에 열린 마음을 가지고 있나요?",
    "상상력을 기반으로 창의적인 해결책을 찾는 것을 좋아하시나요?",
    "현재의 상황보다는 미래의 가능성과 경향성에 관심이 많나요?",
    "다양한 관점과 패턴을 연결시키는 것에 재능을 가지고 있나요?",
    "실제 사실보다는 의미와 심미성에 더욱 집중하는 경향이 있나요?",
    "복잡한 문제에 대해 다양한 해결 방안을 고려하고 시도해 보는 편인가요?",
  ],
  S: [
    "현재의 상황과 사실에 집중하고 세부 사항을 중요시하시나요?",
    "경험과 실제 경험에 의존하여 문제를 해결하는 편인가요?",
    "실제적이고 구체적인 정보를 기반으로 판단하시나요?",
    "사실적인 관찰력과 기억력을 가지고 있나요?",
    "현재의 상황에서 바로 적용 가능한 해결책을 선호하시나요?",
    "실제적인 세부 사항과 사물에 대한 관심과 관찰력이 뛰어나시나요?",
    "일상적이고 실용적인 문제를 해결하는 것을 좋아하시나요?",
    "실제 사실에 기반을 둔 계획과 목표를 세우는 것을 선호하시나요?",
  ],
  T: [
    "문제를 해결할 때 객관적인 분석과 논리적인 사고를 중요시하시나요?",
    "객관적인 원칙과 규칙에 따라 판단하시나요?",
    "감정보다는 분석과 사실에 의존하여 결정을 내리시나요?",
    "논리적인 사고와 인과관계를 통해 문제를 해결하시나요?",
    "정확한 정보와 명확한 사실에 기반하여 판단하시나요?",
    "객관적인 판단과 논리적인 근거를 제시하는 것을 좋아하시나요?",
    "논리와 분석을 통해 문제에 접근하고 해결하는 것을 선호하시나요?",
    "객관적인 판단과 원칙을 기반으로 결정을 내리는 것을 중요시하시나요?",
  ],
  F: [
    "다른 사람들의 감정과 필요를 고려하는 것을 좋아하시나요?",
    "상대방의 감정에 민감하게 대응하고 공감하는 편인가요?",
    "자신의 가치관과 타인의 가치관을 중요시하고 존중하시나요?",
    "조화롭고 화합적인 분위기를 조성하는 것을 좋아하시나요?",
    "타인의 의견과 감정을 고려하여 의사결정을 내리시나요?",
    "다른 사람들의 필요를 이해하고 도움을 주는 것을 즐기시나요?",
    "갈등 상황에서 감정적인 해결책을 찾는 것을 선호하시나요?",
    "자신의 감정을 중요시하고, 감정적인 결정을 내리는 경향이 있나요?",
  ],
  J: [
    "일정과 계획을 따르는 것을 선호하시나요?",
    "구조화된 환경에서 일하고 계획을 세우는 것을 좋아하시나요?",
    "일을 끝내고 마무리하는 것을 중요시하시나요?",
    "계획에 따라 진행되는 것을 좋아하시나요?",
    "결정을 내리고 실행하기 전에 충분한 정보와 계획을 수립하시나요?",
    "조직적이고 체계적으로 일하는 것을 선호하시나요?",
    "일을 완수하고 목표를 달성하는 것에 만족감을 느끼시나요?",
    "일의 순서와 계획에 따라서 진행하는 것을 좋아하시나요?",
  ],
  P: [
    "유연하고 적응력이 높은 편인가요?",
    "새로운 정보와 경험에 대해 호기심을 가지고 있나요?",
    "계획보다는 즉흥적으로 일을 처리하는 편인가요?",
    "상황에 따라 계획을 변경하거나 새로운 방향으로 나아가는 것을 좋아하시나요?",
    "다양한 옵션과 가능성을 탐색하고 결정을 미루는 경향이 있나요?",
    "새로운 정보와 변화에 민감하게 반응하고 즐기시나요?",
    "자유로운 사고와 융통성을 가지고 일하시나요?",
    "일을 미루는 것을 좋아하지 않고 신속하게 처리하는 편인가요?",
  ],
};

// 유형 코드별로 4개의 랜덤 질문을 뽑는 함수
function getRandomQuestions(typeCode) {
  const typeQuestions = allQuestions[typeCode]; // 해당 유형 코드에 대한 모든 질문들
  const selectedQuestions = [];

  // 무작위로 4개의 질문을 선택합니다.
  while (selectedQuestions.length < 4) {
    const randomIndex = Math.floor(Math.random() * typeQuestions.length);
    const randomQuestion = typeQuestions[randomIndex];

    // 이미 선택된 질문인지 확인합니다.
    if (!selectedQuestions.includes(randomQuestion)) {
      selectedQuestions.push(randomQuestion);
    }
  }

  return selectedQuestions.map(question => ({ question, type: typeCode }));
}

// 각 유형 코드에 대해 4개의 랜덤 질문을 뽑습니다.
const selectedEQuestions = getRandomQuestions("E");
const selectedIQuestions = getRandomQuestions("I");
const selectedNQuestions = getRandomQuestions("N");
const selectedSQuestions = getRandomQuestions("S");
const selectedTQuestions = getRandomQuestions("T");
const selectedFQuestions = getRandomQuestions("F");
const selectedJQuestions = getRandomQuestions("J");
const selectedPQuestions = getRandomQuestions("P");

// 모든 선택된 질문들을 하나의 배열로 합칩니다.
const allSelectedQuestions = [
  ...selectedEQuestions,
  ...selectedIQuestions,
  ...selectedNQuestions,
  ...selectedSQuestions,
  ...selectedTQuestions,
  ...selectedFQuestions,
  ...selectedJQuestions,
  ...selectedPQuestions,
];

// 결과를 섞기 위해 Fisher-Yates 알고리즘을 사용합니다.
for (let i = allSelectedQuestions.length - 1; i > 0; i--) {
  const j = Math.floor(Math.random() * (i + 1));
  [allSelectedQuestions[i], allSelectedQuestions[j]] = [
    allSelectedQuestions[j],
    allSelectedQuestions[i],
  ];
}

// console.log("Shuffled questions:", allSelectedQuestions);

const questions = allSelectedQuestions;

 

그리고 data.js 파일을 불러올 수 있게 index.html 파일 하단에 43번 라인에 해당 코드를 추가 하였습니다.

 

 

이제 app.js 파일에서 질문 데이터 부분(const questions = ...) 은 필요없으므로 제거합니다. 그럼 app.js 파일의 상단 코드는 아래와 같은 모양이 됩니다.

 

 

질문은 잘 추가되었는데 답변을 저장하는 부분의 코드도 여기에 맞게 수정을 조금 해줘야합니다.

 

위 캡쳐 이미지를 참고하여 app.js 파일의 5번 라인을 아래와 같이 수정합니다.

 

let answers = {};

 

app.js 파일 하단부의 resetTest 함수 내부의 answers = []; 부분도 answers = {}; 으로 수정합니다.

 

 

그리고 35 ~ 48 라인의  "답변 버튼 클릭 시 다음 질문 또는 결과 화면으로 전환" 부분코드를 아래와 같이 수정합니다.

 

 

 

 

MBTI 유형 결과 데이터도 너무 길기때문에 앞서 작성했던 data.js.파일 하단에 mbtiTypes 라는 변수를 정의 하겠습니다. 일단 아래와 같은 형식으로 작성합니다.

 

const mbtiTypes = {
    ENTJ: {role: "ENTJ역할", mate: "ENTJ어울리는MBTI유형", img: "images/ENTJ.jpg", desc: "ENTJ설명"},
    ENTP: {role: "ENTP역할", mate: "ENTP어울리는MBTI유형", img: "images/ENTP.jpg", desc: "ENTP설명"},
    ENFJ: {role: "ENFJ역할", mate: "ENFJ어울리는MBTI유형", img: "images/ENFJ.jpg", desc: "ENFJ설명"},
    ENFP: {role: "ENFP역할", mate: "ENFP어울리는MBTI유형", img: "images/ENFP.jpg", desc: "ENFP설명"},
    ESTJ: {role: "ESTJ역할", mate: "ESTJ어울리는MBTI유형", img: "images/ESTJ.jpg", desc: "ESTJ설명"},
    ESTP: {role: "ESTP역할", mate: "ESTP어울리는MBTI유형", img: "images/ESTP.jpg", desc: "ESTP설명"},
    ESFJ: {role: "ESFJ역할", mate: "ESFJ어울리는MBTI유형", img: "images/ESFJ.jpg", desc: "ESFJ설명"},
    ESFP: {role: "ESFP역할", mate: "ESFP어울리는MBTI유형", img: "images/ESFP.jpg", desc: "ESFP설명"},
    INTJ: {role: "INTJ역할", mate: "INTJ어울리는MBTI유형", img: "images/INTJ.jpg", desc: "INTJ설명"},
    INTP: {role: "INTP역할", mate: "INTP어울리는MBTI유형", img: "images/INTP.jpg", desc: "INTP설명"},
    INFJ: {role: "INFJ역할", mate: "INFJ어울리는MBTI유형", img: "images/INFJ.jpg", desc: "INFJ설명"},
    INFP: {role: "INFP역할", mate: "INFP어울리는MBTI유형", img: "images/INFP.jpg", desc: "INFP설명"},
    ISTJ: {role: "ISTJ역할", mate: "ISTJ어울리는MBTI유형", img: "images/ISTJ.jpg", desc: "ISTJ설명"},
    ISTP: {role: "ISTP역할", mate: "ISTP어울리는MBTI유형", img: "images/ISTP.jpg", desc: "ISTP설명"},
    ISFJ: {role: "ISFJ역할", mate: "ISFJ어울리는MBTI유형", img: "images/ISFJ.jpg", desc: "ISFJ설명"},
    ISFP: {role: "ISFP역할", mate: "ISFP어울리는MBTI유형", img: "images/ISFP.jpg", desc: "ISFP설명"},
}

각 유형별로 이미지를 준비하고 설명도 맞춰서 채워야 합니다. 각 유형별로 대표하는 역할과 설명, 그리고 어울리는 상대 MBTI 유형을 ChatGPT에게 물어봅니다. 전부 한꺼번에 물어보면 축약형으로 대답해주기 때문에 이부분은 하나씩 물어보면서 채워 나갑니다.

 

그리고 app.js 파일에서 결과 계산 함수(calculateResult)와 결과 화면을 보여주는 함수(showResult) 를 아래와 같이 수정합니다.

 

 

브라우저에서 확인해보면 질문 32개가 잘 표시 됩니다.

 

 

이제 답변을 눌러서 결과 화면으로 넘어가봅니다.

 

 

5. 결과화면 코드 수정하기

 

MBTI 유형과 해당 유형에 대한 설명이 표시 됩니다. 이미지는 아직 준비하지 않아서 img 태그의 alt 속성 값인 "캐릭터 이미지" 글자가 표시 되고 있습니다. 이 부분은 MBTI 유형에 해당하는 캐릭터 이미지를 준비해서 images 폴더에 넣어주면 됩니다.

 

연관 직업과 상대방 MBTI 유형 표시하기

캐릭터 이미지 아래에 MBTI 유형에 해당하는 직업을 표시해보도록 하겠습니다. index.html 파일을 열어 태그를 추가합니다. 

 

 

37, 39 라인이 추가 되었습니다. 그리고 38번 라인의 기존 p 태그를 div 태그로 변경 하였습니다. 이어서 결과 화면을 표시해주는 자바스크립트 코드 부분을 추가로 수정합니다.

 

 

app.js 상단에 25 ~ 26 라인 코드를 추가 했습니다.

 

 

이미지가 화면을 벗어나고 연관 직업과 아래 설명 글자 구분이 잘 안됩니다. 그리고 버튼도 너무 작네요. 이부분 전체적으로 수정해 보겠습니다.

 

styles.css 파일 하단에 아래 코드를 추가합니다.

 

111 ~ 139 라인이 추가 되었습니다.

 

 

40 라인 버튼 텍스트를 "다시하기"로 수정하였습니다.

 

이제 거의 완성 되었습니다.

 

마지막으로 공유하기 기능을 추가 해보겠습니다.

87 ~ 90기존 코드를 아래 코드로 변경합니다.

 

89 ~ 141 라인이 변경 되었습니다. 89번 라인 위치가 변경된 이유는 코드가 자동으로 정리 되었기 때문입니다.

 

 

6. 마무리

지금까지 MBTI 테스트 웹앱을 만들어 보았습니다. 기본 코드에서 어떻게 코드를 수정해가야하는지 접근 방법을 다뤄봤는데 코드 수정하고 캡쳐하는게 너무 번거로워 생략한 부분이 있습니다. 그래도 차근차근 해보시면 결국 자신만의 MBTI 테스트 앱을 만들 수 있으리라 생각됩니다.

이렇게 만든 앱을 다른 사람과도 같이 즐기고 싶은데 아직까지는 본인의 PC에서만 할 수 있습니다. 다음시간에는 우리가 만든 웹앱을 어디서나 접속 가능한 외부 서버에 올리는 방법을 알아보고 실제 스토어에도 등록해 보겠습니다.

 

 

예제에 사용된 이미지를 첨부합니다.

mbti_images.zip
0.21MB

 

 

ChatGPT로 수익 창출 앱 만들기 연재 글입니다.
아래 글도 같이 읽어보면 이해하는데 도움이 됩니다.

2023.05.14 - [모바일 앱] - ChatGPT로 수익 창출 앱 만들기 - 모바일 웹페이지 맛보기

 

ChatGPT로 수익 창출 앱 만들기 - 모바일 웹페이지 맛보기

ChatGPT로 수익 창출 앱 만들기 연재 글입니다. 모바일 웹페이지 맛보기 이전 시간에는 블로그 컨텐츠 주제를 생각해 보았습니다. ( 아래 포스팅 링크 참고) 2023.05.12 - [온라인 수익 창출] - 일단 해

onsuik.com

2023.05.16 - [모바일 앱] - ChatGPT로 수익 창출 앱 만들기 - 개발 환경 준비하기

 

ChatGPT로 수익 창출 앱 만들기 - 개발 환경 준비하기

목차 1. ChatGPT 가입하기 2. 작업 폴더 만들기 3. 코드 편집기 설치 4. 앱에 필요한 이미지 받는곳 5. 마무리 개발 환경 준비하기 ChatGPT로 수익 창출 앱 만들기 연재 글입니다. 2023.05.14 - [모바일 앱] -

onsuik.com

2023.05.17 - [모바일 앱] - ChatGPT로 수익 창출 앱 만들기 - 로또번호 추천 앱 제작하기

 

ChatGPT로 수익 창출 앱 만들기 - 로또번호 추천 앱 제작하기

ChatGPT로 수익 창출 앱 만들기 연재 글입니다. 2023.05.14 - [모바일 앱] - ChatGPT로 수익 창출 앱 만들기 - 모바일 웹페이지 맛보기 ChatGPT로 수익 창출 앱 만들기 - 모바일 웹페이지 맛보기 ChatGPT로 수익

onsuik.com

2023.05.22 - [모바일 앱] - HTML 설명 및 로또번호 추천 앱 코드 직접 수정해보기

 

HTML 설명 및 로또번호 추천 앱 코드 직접 수정해보기

목차 1. HTML이란? 2. HTML 기본 구조 및 설명 3. 로또번호 추천 앱 코드 살펴보기 4. 코드 수정해보기 5. 마무리 앞의 과정에서 모바일 앱 제작 방식에 따른 분류를 알아 보았습니다. 그리고 로또번호

onsuik.com

 

 

 

반응형

댓글