From b9ebb3eef13584917bd2761e7c6451f3847c02ce Mon Sep 17 00:00:00 2001 From: haerong22 Date: Mon, 8 Mar 2021 19:32:34 +0900 Subject: [PATCH] =?UTF-8?q?react=20web=20game=20:=20=EB=A1=9C=EB=98=90?= =?UTF-8?q?=EC=B6=94=EC=B2=A8=EA=B8=B0=20Hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RSP-class.jsx | 0 .../{5, 로또 추첨기 => 5, 가위바위보}/RSP.jsx | 0 .../client.jsx | 0 .../index.html | 0 react_webgame/6. 로또추첨기/Ball.jsx | 23 +++++ react_webgame/6. 로또추첨기/Lotto-class.jsx | 93 +++++++++++++++++++ react_webgame/6. 로또추첨기/Lotto.jsx | 78 ++++++++++++++++ react_webgame/6. 로또추첨기/client.jsx | 6 ++ react_webgame/6. 로또추첨기/index.html | 23 +++++ 9 files changed, 223 insertions(+) rename react_webgame/{5, 로또 추첨기 => 5, 가위바위보}/RSP-class.jsx (100%) rename react_webgame/{5, 로또 추첨기 => 5, 가위바위보}/RSP.jsx (100%) rename react_webgame/{5, 로또 추첨기 => 5, 가위바위보}/client.jsx (100%) rename react_webgame/{5, 로또 추첨기 => 5, 가위바위보}/index.html (100%) create mode 100644 react_webgame/6. 로또추첨기/Ball.jsx create mode 100644 react_webgame/6. 로또추첨기/Lotto-class.jsx create mode 100644 react_webgame/6. 로또추첨기/Lotto.jsx create mode 100644 react_webgame/6. 로또추첨기/client.jsx create mode 100644 react_webgame/6. 로또추첨기/index.html diff --git a/react_webgame/5, 로또 추첨기/RSP-class.jsx b/react_webgame/5, 가위바위보/RSP-class.jsx similarity index 100% rename from react_webgame/5, 로또 추첨기/RSP-class.jsx rename to react_webgame/5, 가위바위보/RSP-class.jsx diff --git a/react_webgame/5, 로또 추첨기/RSP.jsx b/react_webgame/5, 가위바위보/RSP.jsx similarity index 100% rename from react_webgame/5, 로또 추첨기/RSP.jsx rename to react_webgame/5, 가위바위보/RSP.jsx diff --git a/react_webgame/5, 로또 추첨기/client.jsx b/react_webgame/5, 가위바위보/client.jsx similarity index 100% rename from react_webgame/5, 로또 추첨기/client.jsx rename to react_webgame/5, 가위바위보/client.jsx diff --git a/react_webgame/5, 로또 추첨기/index.html b/react_webgame/5, 가위바위보/index.html similarity index 100% rename from react_webgame/5, 로또 추첨기/index.html rename to react_webgame/5, 가위바위보/index.html diff --git a/react_webgame/6. 로또추첨기/Ball.jsx b/react_webgame/6. 로또추첨기/Ball.jsx new file mode 100644 index 00000000..a2d2bffd --- /dev/null +++ b/react_webgame/6. 로또추첨기/Ball.jsx @@ -0,0 +1,23 @@ +import React, { memo } from "react"; + +const Ball = memo(({ number }) => { + let background; + if (number <= 10) { + background = "red"; + } else if (number <= 20) { + background = "orange"; + } else if (number <= 30) { + background = "yellow"; + } else if (number <= 40) { + background = "blue"; + } else { + background = "green"; + } + return ( +
+ {number} +
+ ); +}); + +export default Ball; diff --git a/react_webgame/6. 로또추첨기/Lotto-class.jsx b/react_webgame/6. 로또추첨기/Lotto-class.jsx new file mode 100644 index 00000000..1db6cb5b --- /dev/null +++ b/react_webgame/6. 로또추첨기/Lotto-class.jsx @@ -0,0 +1,93 @@ +import React, { Component } from "react"; +import Ball from "./Ball"; + +function getWinNumbers() { + console.log("getWinNumbers"); + const candidate = Array(45) + .fill() + .map((v, i) => i + 1); + const shuffle = []; + while (candidate.length > 0) { + shuffle.push( + candidate.splice(Math.floor(Math.random() * candidate.length), 1)[0] + ); + } + const bonusNumber = shuffle[shuffle.length - 1]; + const winNumbers = shuffle.slice(0, 6).sort((p, c) => p - c); + return [...winNumbers, bonusNumber]; +} + +class Lotto extends Component { + state = { + winNumbers: getWinNumbers(), + winBalls: [], + bonus: null, + redo: false, + }; + + timeouts = []; + + runTimeouts = () => { + const { winNumbers } = this.state; + for (let i = 0; i < this.state.winNumbers.length - 1; i++) { + this.timeouts[i] = setTimeout(() => { + this.setState((prevState) => { + return { + winBalls: [...prevState.winBalls, winNumbers[i]], + }; + }); + }, (i + 1) * 1000); + } + this.timeouts[6] = setTimeout(() => { + this.setState({ + bonus: winNumbers[6], + redo: true, + }); + }, 7000); + }; + + componentDidMount() { + this.runTimeouts(); + } + + componentWillUnmount() { + this.timeouts.forEach((v) => { + clearTimeout(v); + }); + } + + componentDidUpdate(prevProps, prevState) { + if (this.timeouts.length === 0) { + this.runTimeouts(); + } + } + + onClickRedo = () => { + this.setState({ + winNumbers: getWinNumbers(), + winBalls: [], + bonus: null, + redo: false, + }); + this.timeouts = []; + }; + + render() { + const { winBalls, bonus, redo } = this.state; + return ( + <> +
당첨 숫자
+
+ {winBalls.map((v) => ( + + ))} +
+
보너스
+ {bonus && } + {redo && } + + ); + } +} + +export default Lotto; diff --git a/react_webgame/6. 로또추첨기/Lotto.jsx b/react_webgame/6. 로또추첨기/Lotto.jsx new file mode 100644 index 00000000..1877e8b6 --- /dev/null +++ b/react_webgame/6. 로또추첨기/Lotto.jsx @@ -0,0 +1,78 @@ +import React, { + useState, + useRef, + useEffect, + useMemo, + useCallback, +} from "react"; +import Ball from "./Ball"; + +function getWinNumbers() { + console.log("getWinNumbers"); + const candidate = Array(45) + .fill() + .map((v, i) => i + 1); + const shuffle = []; + while (candidate.length > 0) { + shuffle.push( + candidate.splice(Math.floor(Math.random() * candidate.length), 1)[0] + ); + } + const bonusNumber = shuffle[shuffle.length - 1]; + const winNumbers = shuffle.slice(0, 6).sort((p, c) => p - c); + return [...winNumbers, bonusNumber]; +} + +const Lotto = () => { + const lottoNumbers = useMemo(() => getWinNumbers(), []); + const [winNumbers, setWinNumbers] = useState(lottoNumbers); + const [winBalls, setWinBalls] = useState([]); + const [bonus, setBonus] = useState(null); + const [redo, setRedo] = useState(false); + const timeouts = useRef([]); + + useEffect(() => { + runTimeouts(); + return () => { + timeouts.current.forEach((v) => { + clearTimeout(v); + }); + }; + }, [timeouts.current]); + + const runTimeouts = () => { + for (let i = 0; i < winNumbers.length - 1; i++) { + timeouts.current[i] = setTimeout(() => { + setWinBalls((prevBalls) => [...prevBalls, winNumbers[i]]); + }, (i + 1) * 1000); + } + timeouts.current[6] = setTimeout(() => { + setBonus(winNumbers[6]); + setRedo(true); + }, 7000); + }; + + const onClickRedo = useCallback(() => { + setWinNumbers(getWinNumbers()); + setWinBalls([]); + setBonus(null); + setRedo(false); + timeouts.current = []; + }, [winNumbers]); + + return ( + <> +
당첨 숫자
+
+ {winBalls.map((v) => ( + + ))} +
+
보너스
+ {bonus && } + {redo && } + + ); +}; + +export default Lotto; diff --git a/react_webgame/6. 로또추첨기/client.jsx b/react_webgame/6. 로또추첨기/client.jsx new file mode 100644 index 00000000..26fc2659 --- /dev/null +++ b/react_webgame/6. 로또추첨기/client.jsx @@ -0,0 +1,6 @@ +import React from "react"; +import ReactDom from "react-dom"; + +import Lotto from "./Lotto"; + +ReactDom.render(, document.querySelector("#root")); diff --git a/react_webgame/6. 로또추첨기/index.html b/react_webgame/6. 로또추첨기/index.html new file mode 100644 index 00000000..45540d14 --- /dev/null +++ b/react_webgame/6. 로또추첨기/index.html @@ -0,0 +1,23 @@ + + + + 로또 추첨기 + + + +
+ + +