728x90
NumberBaseball.jsx
import React, { Component, createRef } from 'react';
import Try from './Try';
// 숫자 네 개를 겹치지 않고 랜덤하게 뽑는 함수
function getNumbers() {
const candidate = [1,2,3,4,5,6,7,8,9];
const array = [];
for (let i = 0; i < 4; i += 1) {
const chosen = candidate.splice(Math.floor(Math.random() * (9 - i)), 1)[0];
array.push(chosen);
}
return array;
}
class NumberBaseball extends Component {
state = {
result: '',
value: '',
answer: getNumbers(), // ex: [1,3,5,7]
tries: [],
};
onSubmitForm = (e) => {
const { value, tries, answer } = this.state;
e.preventDefault();
if (value === answer.join('')) {
this.setState((prevState) => {
return {
result: '홈런!',
tries: [...prevState.tries, { try: value, result: '홈런!' }],
}
});
alert('게임을 다시 시작합니다!');
this.setState({
value: '',
answer: getNumbers(),
tries: [],
});
this.inputRef.current.focus();
} else { // 답 틀렸으면
const answerArray = value.split('').map((v) => parseInt(v));
let strike = 0;
let ball = 0;
if (tries.length >= 9) { // 10번 이상 틀렸을 때
this.setState({
result: `10번 넘게 틀려서 실패! 답은 ${answer.join(',')}였습니다!`,
});
alert('게임을 다시 시작합니다!');
this.setState({
value: '',
answer: getNumbers(),
tries: [],
});
this.inputRef.current.focus();
} else {
for (let i = 0; i < 4; i += 1) {
if (answerArray[i] === answer[i]) {
strike += 1;
} else if (answer.includes(answerArray[i])) {
ball += 1;
}
}
this.setState((prevState) => {
return {
tries: [...prevState.tries, { try: value, result: `${strike} 스트라이크, ${ball} 볼입니다`}],
value: '',
};
});
this.inputRef.current.focus();
}
}
};
onChangeInput = (e) => {
console.log(this.state.answer);
this.setState({
value: e.target.value,
});
};
inputRef = createRef(); // this.inputRef
render() {
const { result, value, tries } = this.state;
return (
<>
<h1>{result}</h1>
<form onSubmit={this.onSubmitForm}>
<input ref={this.inputRef} maxLength={4} value={value} onChange={this.onChangeInput} />
</form>
<div>시도: {tries.length}</div>
<ul>
{tries.map((v, i) => {
return (
<Try key={`${i + 1}차 시도 :`} tryInfo={v} />
);
})}
</ul>
</>
);
}
}
export default NumberBaseball; // import NumberBaseball;
Try.jsx
import React, { memo } from 'react';
const Try = memo(({tryInfo}) => {
return (
<li>
<div>{tryInfo.try}</div>
<div>{tryInfo.result}</div>
</li>
);
});
export default Try;
function getNumbers() {
const candidate = [1,2,3,4,5,6,7,8,9];
const array = [];
for (let i = 0; i < 4; i += 1) {
const chosen = candidate.splice(Math.floor(Math.random() * (9 - i)), 1)[0];
array.push(chosen);
}
return array;
}
NumberBaseball.jsx파일에서 getNumbers()함수는 숫자 4개를 겹치지 않게 생성하는 함수입니다.
숫자야구 게임에서 정답을 생성하는 함수라고 할수 있습니다.
onSubmitForm = (e) => {
const { value, tries, answer } = this.state;
e.preventDefault();
if (value === answer.join('')) {
this.setState((prevState) => {
return {
result: '홈런!',
tries: [...prevState.tries, { try: value, result: '홈런!' }],
}
});
alert('게임을 다시 시작합니다!');
this.setState({
value: '',
answer: getNumbers(),
tries: [],
});
this.inputRef.current.focus();
} else { // 답 틀렸으면
const answerArray = value.split('').map((v) => parseInt(v));
let strike = 0;
let ball = 0;
if (tries.length >= 9) { // 10번 이상 틀렸을 때
this.setState({
result: `10번 넘게 틀려서 실패! 답은 ${answer.join(',')}였습니다!`,
});
alert('게임을 다시 시작합니다!');
this.setState({
value: '',
answer: getNumbers(),
tries: [],
});
this.inputRef.current.focus();
} else {
for (let i = 0; i < 4; i += 1) {
if (answerArray[i] === answer[i]) {
strike += 1;
} else if (answer.includes(answerArray[i])) {
ball += 1;
}
}
this.setState((prevState) => {
return {
tries: [...prevState.tries, { try: value, result: `${strike} 스트라이크, ${ball} 볼입니다`}],
value: '',
};
});
this.inputRef.current.focus();
}
}
};
onSubmitForm함수의 경우 랜덤으로 생성한 숫자를 맞추었을 경우 게임을 새롭게 시작하고 틀렸을 경우에는 자리수와 숫자를 모두 맞춘 숫자만큼은 Strike로 계산하고 자리수는 틀리고 숫자만 맞았을 경우 ball로 계산하여 출력해줍니다.
...prevState.tries
또 중간에 이런부분이 있는데 배열의 [ ]를 없애고 값들을 다시 넣어준다고 보시면 됩니다.
예를들어 let arr = [1, 2, 3];
let arr2 = [...arr, 4, 5];
라고 친다면 arr2에는 [1, 2, 3, 4, 5]가 들어가있다고 보시면됩니다.
render부분에서 const { result, value, tries } = this.state;는 아래쪽에서 result, value, tries를 사용할떄 this.state.result 이런 식으로 쓰면 번거로워서 구조분해를 해준 것입니다.
728x90
'SPA > React' 카테고리의 다른 글
[React] 게임으로 배우는 리액트 - JSX에서 주석 (0) | 2022.06.03 |
---|---|
[React] 게임으로 배우는 리액트 - 컴포넌트 분리와 props (0) | 2022.06.02 |
[React] 게임으로 배우는 리액트 - 반복문 (map, key) (0) | 2022.06.01 |
[React] 게임으로 배우는 리액트 - import와 require 비교 (0) | 2022.05.31 |
[React] 게임으로 배우는 리액트 - Webpack(웹팩) (0) | 2022.05.30 |