[2022.07.15] 리액트로 숫자야구 만들기 (class형 컴포넌트)

REASON·2022년 7월 15일
0

STUDY

목록 보기
80/127

제로초님 강의보고 따라만든 숫자야구 게임

전체 코드

import React, { Component } from 'react';

function ranmderNumber() {
  const candidate = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  const array = [];
  for (let i = 0; i < 4; i++) {
    const chose = candidate.splice(Math.floor(Math.random() * (9 - i)), 1)[0];
    array.push(chose);
  }

  return array;
}

ranmderNumber();

class NumberBaseball extends Component {
  state = {
    userInput: '',
    result: '',
    quiz: ranmderNumber(),
    tries: [],
  };

  onSubmit = (e) => {
    e.preventDefault();
    if (this.state.quiz.join('') === this.state.userInput) {
      this.setState({
        result: '홈런!',
        userInput: '',
        quiz: ranmderNumber(),
        tries: [...this.state.tries, { try: this.state.userInput, result: '홈런!' }],
      });
    } else {
      const userInputArray = this.state.userInput.split('').map((v) => parseInt(v));
      let strike = 0;
      let ball = 0;
      if (this.state.tries.length >= 9) {
        this.setState({
          result: `10번 넘게 시도했습니다. 정답은 ${this.state.quiz.join(',')} 였습니다.`,
        });
        alert('게임을 다시 시작합니다.');
        this.setState({
          userInput: '',
          quiz: ranmderNumber(),
          tries: [],
        });
      } else {
        for (let i = 0; i < 4; i++) {
          if (userInputArray[i] === this.state.quiz[i]) {
            strike += 1;
          } else if (this.state.quiz.includes(userInputArray[i])) {
            ball += 1;
          }
        }
        this.setState({
          tries: [...this.state.tries, { try: this.state.userInput, result: `${strike} 스트라이크, ${ball}볼 입니다.` }],
          userInput: '',
        });
      }
    }
  };

  onChange = (e) => {
    this.setState({
      userInput: e.target.value,
    });
  };

  render() {
    return (
      <div>
        <form onSubmit={this.onSubmit}>
          <input value={this.state.userInput} onChange={this.onChange} type="number" />
          <button>확인</button>
        </form>
        <div>시도 : {this.state.tries.length}</div>
        <ul>
          {this.state.tries.map((v, index) => {
            return (
              <li key={`${index + 1}차 시도`}>
                {v.try} : {v.result}
              </li>
            );
          })}
        </ul>
        <div>{this.state.result}</div>
      </div>
    );
  }
}

export default NumberBaseball;

확인 버튼을 누를 때마다 사용자가 입력한 4자리 숫자의 위치와 번호가 일치할 때 스트라이크, 정답의 숫자와 일치하나 자리가 다를 때는 볼을 알려주어 정답을 유추해서 푸는 게임이다.

10회 시도하고도 못 맞추면 새로운 게임이 시작된다.

tries: [...this.state.tries, { try: this.state.userInput, result: '홈런!' }]

개인적으로 가장 어렵고 아직도 이해가 잘 안되는 부분은 이 코드이다.
state에 배열을 사용할 때 원본 배열말고 복사해서 사용하는 것 까지는 알겠는데 두번째 오브젝트로 들어간 {try ~~ } 부분의 의미를 잘 모르겠다..ㅠㅠ 왜 배열의 2번째에 이 코드가 들어가는가(?)

주말에 다시 혼자 만들어보면서 다시 살펴보려고 한다. 😥 급 어려워진 리액트쨩,,


참고 자료
숫자야구 만들기

0개의 댓글