기존 단어 선택 시 선택지가 중복인 부분 해결(5. 단어 게임 오류)

개발공부·2023년 1월 20일
0

* 5. 단어 게임(시간이내에 문제 풀기)

* 결과

1) 단어 선택 후 게임 1 ~ 3

2) 게임 4 ~ 8

3) 게임 9 ~ 10

* 무엇이 문제였나?

▶ 단어 선택 후 게임으로 들어갈 때, 중복되는 것을 피하기 위해 답안 생성

* 원하는 목표

문제가 "커피"라면 답안은 ["coffee", "answer1", "answer2", "answer3"]로 나와야 함

* 문제 상황

문제가 "커피"라면 답안이
1) ["coffee", "", "answer2", "answer3"]
2) ["coffee", "", "", "answer3"] 이런 식으로 나옴

* 답안을 만들기 위한 과정

  • 랜덤 값을 만들기 위한 함수
 const shuffleArray = (array) => {
        for (let i = array.length - 1; i > 0; i--) {
          // 무작위로 index 값 생성 (0 이상 i 미만)
          let j = Math.floor(Math.random() * (i + 1));
          [array[i], array[j]] = [array[j], array[i]];
        }
      };
 shuffle(해당값)

1) 게임을 위해서는 10개의 값이 필요(result.length가 10개 전까지는 계속 돌림)
2) 10개를 랜덤으로 생성하면서 동시에 답안도 랜덤 생성

const answer = [1,2,3,4]
shuffleArray(answer)
3) 선택된 값(checkedData) 이외의 사용자가 만든 단어들(allData)도 랜덤 생성

* 중요한 점

allData에서 이미 답안으로 선택된 값(data.english)와 영어단어가 겹치지 않고, 동시에 한글 단어가 겹치지 않아야 함
▶ data.english !== all.english && data.korean !== all.korean

한글 단어가 겹치지 않아야 하는 이유 : "한국어기초사전" API로 검색한 단어가 같은 뜻인데 여러 단어를 생성하기 때문
ex) "검색"이란 단어의 경우 "inspection", "check" 두 가지 존재

  • 오류

    objects are not valid as a react child (found: object with keys {id, english, korean, type, status, createdat, updatedat, userid, user}). if you meant to render a collection of children, use an array instead.

▶ 데이터를 리덕스로 전달 시 배열 안에 객체를 넣었는데, 객체의 개별 값들을 넣어야 하는데 객체 전체 값을 넣음

// 수정 전
result.push({
              question: data.korean,
              answer: 1,
              choices: Array.from(
                new Set([
                  allDataLists[0],
                  data.english,
                  allDataLists[1],
                  allDataLists[2],
                ])
              ),
            });
            
//수정 후
result.push({
              question: data.korean,
              answer: 2,
              choices: Array.from(
                new Set([
                  allDataLists[0].english,
                  data.english,
                  allDataLists[1].english,
                  allDataLists[2].english,
                ])
              ),
            });

* 코드

 const { wordLists, checkedWordList } = useSelector((state) => state.word);
  const checkedData = [...checkedWordList];
  const allData = [...wordLists];
  const answer = [1, 2, 3, 4];

const onStartGame = useCallback(() => {
    if (checkedWordList.length < 10) {
      setAlert(true);
      setGameStart(false);
      setOpen(true);
    } else {
      const shuffleArray = (array) => {
        for (let i = array.length - 1; i > 0; i--) {
          // 무작위로 index 값 생성 (0 이상 i 미만)
          let j = Math.floor(Math.random() * (i + 1));
          [array[i], array[j]] = [array[j], array[i]];
        }
      };
      shuffleArray(allData);
      shuffleArray(checkedData);
      checkedData.splice(10, checkedData.length); //10개만 남기기

      if (result.length !== 10) {
        checkedData.map((data) => {
          shuffleArray(answer);
          const allDataLists = [];
          if (answer[0] === 1) {
            allData.map((all) => {
              if (data.english !== all.english && data.korean !== all.korean) {
                allDataLists.push(all);
              }
            });

            result.push({
              question: data.korean,
              answer: 1,
              choices: Array.from(
                new Set([
                  data.english,
                  allDataLists[0].english,
                  allDataLists[1].english,
                  allDataLists[2].english,
                ])
              ),
            });
          } else if (answer[0] === 2) {
            allData.map((all) => {
              if (data.english !== all.english && data.korean !== all.korean) {
                allDataLists.push(all);
              }
            });

            result.push({
              question: data.korean,
              answer: 2,
              choices: Array.from(
                new Set([
                  allDataLists[0].english,
                  data.english,
                  allDataLists[1].english,
                  allDataLists[2].english,
                ])
              ),
            });
          } else if (answer[0] === 3) {
            allData.map((all) => {
              if (data.english !== all.english && data.korean !== all.korean) {
                allDataLists.push(all);
              }
            });

            result.push({
              question: data.korean,
              answer: 3,
              choices: Array.from(
                new Set([
                  allDataLists[0].english,
                  allDataLists[1].english,
                  data.english,
                  allDataLists[2].english,
                ])
              ),
            });
          } else if (answer[0] === 4) {
            allData.map((all) => {
              if (data.english !== all.english && data.korean !== all.korean) {
                allDataLists.push(all);
              }
            });
            result.push({
              question: data.korean,
              answer: 4,
              choices: Array.from(
                new Set([
                  allDataLists[0].english,
                  allDataLists[1].english,
                  allDataLists[2].english,
                  data.english,
                ])
              ),
            });
          }
        });
      }

      dispatch(startGameRequest(result));
      setGameStart(true);
      setOpen(false);
    }
  }, [result]);
profile
개발 블로그, 티스토리(https://ba-gotocode131.tistory.com/)로 갈아탐

0개의 댓글