Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3주차 기본/심화/공유 과제] 숫자 게임 만들기 🔢 #4

Open
wants to merge 14 commits into
base: main
Choose a base branch
from

Conversation

chaeneey
Copy link
Contributor

@chaeneey chaeneey commented Nov 5, 2024

✨ 구현 기능 명세

💡 기본 과제

  • Context API, 전역상태 라이브러리 사용 X (ThemeProvider 제외)
  1. 헤더
  • 게임/랭킹 2개의 메뉴 선택 가능
  • 게임 선택 시 헤더 우측에 레벨 선택 Select와 타이머 표시
  • 게임 선택 시 게임 판 출력
  • 랭킹 선택 시 헤더 우측엔 아무것도 나오지 않음
  • 랭킹 선택 시 랭킹 보드 출력
  1. 게임
  • (기본) 한 종류의 레벨만 구현
  • 숫자는 항상 랜덤으로 표시됨. (초기 표시 숫자들도, 이후 열리는 숫자들도 모두 랜덤)
  • 처음에 표시되는 숫자는 클릭해야 하는 숫자의 앞에 절반임. 만약 level 1이라 118까지 클릭해야한다면, 처음에는 19까지의 숫자가 랜덤으로 보여짐
  • 게임판 위쪽에 다음으로 클릭해야할 숫자를 표시
  • 1을 누르는 순간 게임이 시작되며 헤더 우측의 타이머가 동작. 타이머는 소수점 2번째 자리까지 측정.
  • 마지막 숫자 클릭시 게임 종료
  • 게임 종료 시, 타이머를 멈추고 alert 창을 띄워주며 걸린 시간을 표시
  • 게임 종료 시, 현재 시각, 게임의 레벨, 플레이 시간 3개의 정보를 localStorage에 저장 (랭킹에서 사용)
  • 종료 창에서 확인 누르면 다시 시작할 수 있는 상태로 게임 초기화
  • 게임 중 level 변경 시 다시 시작할 수 있는 상태로 게임 초기화
  1. 랭킹
  • localStorage에서 데이터 불러오기
  • 플레이 시간 오름차순으로 보여야 함 (빨리 깬 기록이 위쪽)
  • 우측 상단의 초기화 버튼 누르면 대시보드 초기화 (localStorage도 초기화)

🔥 심화 과제

  1. 게임
  • Level 선택 가능
    Level 1: 3 x 3, Level 2: 4 x 4, Level 3: 5 x 5
  • 숫자 클릭할 때 클릭되는 것 같은 효과 (예시: 깜빡거림)
  • 게임 종료 alert 대신, React의 createPortal을 사용하여 Modal 구현
    createPortal
  1. 랭킹
  • Level 내림차순 & 시간 오름차순 정렬(정렬 기준이 2개). 높은 Level이 위쪽으로, 같은 레벨 중에선 플레이 시간이 짧은게 위쪽으로 정렬

공유과제

  • 제목: 🙄 리액트에서 배열의 값을 업데이트 하는 방법 (feat. 리액트의 불변성)

링크 첨부 : https://wave-web.tistory.com/94


❗️ 내가 새로 알게 된 점

  • ~ 부분 이렇게 구현했어요, 피드백 부탁해요!

❓ 구현 과정에서의 어려웠던/고민했던 부분

  • ~ 부분이 잘 구현한건지 잘 모르겠어요!
  • ~부분 다른 방법이 있는지 궁금해요!

🥲 소요 시간

  • 2일

🖼️ 구현 결과물

스크린샷 2024-11-05 오후 10 36 51

3주차 과제 구현 영상

Copy link

@minjeoong minjeoong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요! yb 김민정 입니다:)
코드 전체적으로 너무 깔끔하게 짜서,
딱히 코멘트 달 부분이 거의 없었어요..🥺 w
특히나, 함수로 빼는 부분을 정말 꼼꼼하게 짜신 것 같아요!!
pr 작성이 미완이라서, 그 부분 채워주시면 좋을 것 같습니다
저도 많이 배우고 갑니다,, 너무 고생 많으셨어요 👍🏻👏🏻👏🏻🍀

Comment on lines +4 to +15
const NumberCard = ({ cardNumber, handleCardClick, isVisible }) => {
return (
<>
<NumberCardLayout
onClick={() => handleCardClick(cardNumber)}
isVisible={isVisible}
>
<NumberCardTextStyle>{cardNumber}</NumberCardTextStyle>
</NumberCardLayout>
</>
);
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 카드도 컴포넌트로 해서 IsVisible 값으로 처리하는 게 깔끔하고 좋네요,,!👍🏻👍🏻

Comment on lines +25 to +29
{gameRanking
.sort(
(a, b) => formatRankingData(a.play) - formatRankingData(b.play)
)
.map((rank, index) => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오.. 랭킹 데이터를 format 하도록 함수를 뺀 거군요!! 👏🏻

setNumberArray(createRandomArray(1, 9));
setNextNumberArray(createRandomArray(10, 18));
setIsVisible(Array(9).fill(true));
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

숫자 직접 넣으셨는데,
유지보수 하기에도 그렇지만
level 에 따라 달라지는 부분 구현을 나중에 추가한다는 가정하에
state 로 관리하거나, 변수로 관리하면 좋을 것 같아요!!

JSON.parse(localStorage.getItem("ranking"))
);

const { time, startTimer, resetTimer } = useTimer();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

time 관련 함수로 따로 빼는 아이디어 너무 좋네요...
함수 빼기 장인이다,,

Copy link

@shroqkf shroqkf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

역시 채연님,, 코드 읽으면서 계속 깨달음을 얻었습니다,,, 전반적으로 함수와 스타일 컴포넌트의 분리를 잘해주셔서 읽으면서 깔끔한 코드 구조가 이런거구나 느꼈습니다 많이 배웠어요🫶

Comment on lines +6 to +12
const Header = ({ handleChangeContent, content, time }) => {
const [buttonState, setButtonState] = useState("GAME");

const handleClickButton = (content) => {
handleChangeContent(content);
setButtonState(content);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분에서 buttonStatecontent가 비슷한 역할을 하고 있는 것으로 보여서

handleChangeContent(content);
setButtonState(content); 

혹시 둘 다 작성하신 이유가 있을까요??

display: flex;
justify-content: center;
align-items: center;
visibility: ${({ isVisible }) => (!isVisible ? "hidden" : "visible")};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visibility 속성을 사용해서 슷자카드를 조정할 수 있네요!! 🤩

Comment on lines +27 to +37
const handleCardNumberChange = (number) => {
setCardNumber(number);
};

const handleCardClick = (number) => {
if (number === 1) {
startTimer();
}

if (number === cardNumber) {
handleCardNumberChange((prev) => prev + 1);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handleCardNumberChange 함수를 별도로 만들지 않고 setCardNumber((prev) => prev + 1)로 작성하면 더 직관적이지 않을까,, 생각합니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants