본문 바로가기
React

[React] React로 가위 바위 보 게임 만들기 2

by IT 정복가 2023. 2. 8.
728x90

https://conquer-it.tistory.com/191

React로 가위 바위 보 게임 만들기 1


우선, 버튼을 클릭했을 때 유저 박스의 사진이 바뀌는 것까지는 구현이 되었다.

다음 할 일은 컴퓨터 박스를 구현 하는 것이다.

 

3. 컴퓨터가 랜덤한 아이템 선택하기

우선 1판할때마다 UI가 바껴야하기 때문에 state를 사용해야 한다.

또한 유저가 랜덤한 버튼을 클릭할 때 컴퓨터가 랜덤한 아이템을 출력시켜야 하기때문에

play함수 안에서 실행시켜야 한다.

 

우선 완성된 코드부터 살펴보자.

App.js

import { useState } from "react";
import "./App.css";
import Box from "./component/Box";

const choice={
  rock:{
    name: "Rock",
    img:"https://cdn.pixabay.com/photo/2014/03/25/15/26/rock-paper-scissors-296854_960_720.png" 
  },
  scissors:{
    name:"Scissor",
    img:"https://cdn.pixabay.com/photo/2014/03/25/15/26/rock-paper-scissors-296853_1280.png"
  },
  paper:{
    name:"Paper",
    img:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvciv57AXv5krjeGZ2dBEtESuvSk33dpvT_-AebVrCx5Flo2ME_F-r9vw7Ayqdx9oq10s&usqp=CAU"
  }
}
function App() {
  const [userSelect, setUserSelect] = useState(null);
  const [computerSelect, setComputerSelect] = useState(null);
  const paly = (userChoice) => {
    setUserSelect(choice[userChoice]);

    let computerChoice = randomChoice();
    setComputerSelect(computerChoice);
  };

  const randomChoice = () => {
    let itemArray = Object.keys(choice); // 객체에 키값만 뽑아 배열로 만들어 주는 함수
    let randomItem = Math.floor(Math.random() * itemArray.length);
    let final = itemArray[randomItem];
    return choice[final];
  };
  return (
    <>
      <div className="main">
        <Box title="You" item={userSelect} />
        <Box title="Computer" item={computerSelect} />
      </div>
      <div className="main">
        <button onClick={() => paly("scissors")} className="btn">
          <img src="https://nehalhazem.github.io/rockPaperScissors.io/img/scissors.png" />
        </button>
        <button onClick={() => paly("rock")} className="btn">
          <img src="https://nehalhazem.github.io/rockPaperScissors.io/img/rock.png" />
        </button>
        <button onClick={() => paly("paper")} className="btn">
          <img src="https://nehalhazem.github.io/rockPaperScissors.io/img/paper.png" />
        </button>
      </div>
    </>
  );
}

export default App;
  • Math.random(): 0~1까지 랜덤한 수를 출력 함수
  • Math.floor(): 소수점 버림 함수
  • Object.keys(): 객체의 키값을 배열로 만들어주는 함수 
randomChoice라는 함수를 만들어 그 안에서
choice 객체를 배열화 시켜 인덱스 번호를 얻게 한 후
randomItem이라는 변수에 랜덤한 값을 넣어
객체에 랜덤하게 접근할 수 있게 만들어 준다.
choice[final]를 리턴하면 값이 computerChoice로 들어가게 되고
그 후 setComputerSelect가 실행되면서 컴퓨터 박스의 랜덤한 사진이 출력된다.
 

결과

랜덤한 값이 잘 출력되는 것을 볼 수 있다.

 

4.  승패 가리기

지금 우리는 유저가 선택한 값과 컴퓨터가 선택한 값을 알고 있다.

이것을 통해 승패 가리기 코드를 작성하면 된다.

 

우선 결과를 보여주는 state를 만들어 주어야 한다.

그 후에 버튼이 클릭될 때마다 승패를 가려야 하기 때문에

play 함수 안에서 judgement 함수를 실행시키는데 매개변수로 유저의 값과 컴퓨터의 값을 보내준다.

 

judgement 함수에서는 가위바위보로 승패를 가르는 코드를 작성해 준다.

가위바위보의 로직은 아래와 같다.

1. 유저 == 컴퓨터 >> 비김

2. 유저가 주먹이면서 컴퓨터가 가위일 경우 >> 이김

3. 유저가 주먹이면서 컴퓨터가 보인 경우 >> 짐

4. 유저가 가위이면서 컴퓨터가 보인 경우 >> 이김

5. 유저가 가위이면서 컴퓨터가 주먹인 경우 >> 짐

6. 유저가 보이면서 컴퓨터가 주먹인 경우 >> 이김

7. 유저가 보이면서 컴퓨터가 가위인 경우 >> 짐

위 로직대로 코드를 작성하면 아래와 같다.

 

App.js

import { useState } from "react";
import "./App.css";
import Box from "./component/Box";

const choice={
  rock:{
    name: "Rock",
    img:"https://cdn.pixabay.com/photo/2014/03/25/15/26/rock-paper-scissors-296854_960_720.png" 
  },
  scissors:{
    name:"Scissor",
    img:"https://cdn.pixabay.com/photo/2014/03/25/15/26/rock-paper-scissors-296853_1280.png"
  },
  paper:{
    name:"Paper",
    img:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvciv57AXv5krjeGZ2dBEtESuvSk33dpvT_-AebVrCx5Flo2ME_F-r9vw7Ayqdx9oq10s&usqp=CAU"
  }
}
function App() {
  const [userSelect, setUserSelect] = useState(null);
  const [computerSelect, setComputerSelect] = useState(null);
  const [result, setResult] = useState("");
  const paly = (userChoice) => {
    setUserSelect(choice[userChoice]);

    let computerChoice = randomChoice();
    setComputerSelect(computerChoice);

    setResult(judgement(choice[userChoice], computerChoice));
  };

  const judgement = (user, computer) => { //가위바위보 로직
    if (user.name == computer.name) {
      return "tie";
    } else if (user.name == "Rock")
      return computer.name == "Scissor" ? "Win" : "Lose";
    else if (user.name == "Scissor")
      return computer.name == "Paper" ? "Win" : "Lose";
    else if (user.name == "Paper")
      return computer.name == "Scissor" ? "Lose" : "Win";
  };

  const randomChoice = () => {
    let itemArray = Object.keys(choice); // 객체에 키값만 뽑아 배열로 만들어 주는 함수
    let randomItem = Math.floor(Math.random() * itemArray.length);
    let final = itemArray[randomItem];
    return choice[final];
  };
  return (
    <>
      <div className="main">
        <Box title="You" item={userSelect} result={result} />
        <Box title="Computer" item={computerSelect} result={result} />
      </div>
      <div className="main">
        <button onClick={() => paly("scissors")} className="btn">
          <img src="https://nehalhazem.github.io/rockPaperScissors.io/img/scissors.png" />
        </button>
        <button onClick={() => paly("rock")} className="btn">
          <img src="https://nehalhazem.github.io/rockPaperScissors.io/img/rock.png" />
        </button>
        <button onClick={() => paly("paper")} className="btn">
          <img src="https://nehalhazem.github.io/rockPaperScissors.io/img/paper.png" />
        </button>
      </div>
    </>
  );
}

export default App;

(삼항연산으로 코드 길이를 줄이자.)

props로 result를 전해주었기 때문에 Box.js의 결과도 바꿔주어야 한다.

 

Box.js

import React from "react";

const Box = (props) => {
  return (
    <div className="box">
      <h1>{props.title}</h1>
      <img className="item-img" src={props.item && props.item.img} />
      <h2>{props.result}</h2>
    </div>
  );
};

export default Box;

결과가 잘 나오긴 하지만 뭔가 이상하다.

유저가 이겼는데 컴퓨터도 같이 Win이 출력되는 상황이다.

이 문제에 대해서는 다음 글에서 다뤄본다.


개발 현황

완성

  • 박스 2개가 있어야 하며 그 안에는 컴퓨터와 유저를 구분해주는 텍스트와 사진, 결과가 있다.
  • 그 아래에는 가위 바위 보 버튼이 위치한다.
  • 버튼을 클릭하면 클릭한 값이 유저 박스에 보여진다.
  • 컴퓨터는 랜덤하게 아이템 선택이 된다.

미완성

  • 게임 결과를 통해 누가 이겼는지 승패를 결정한다.
  • 승패 결과에 따라 박스 테두리의 색이 바뀐다.(ex. 승: 초록, 패: 빨강, 무: 검정)
  • 이긴 횟수, 비긴 횟수, 진 횟수를 UI에 보여준다.
  • 리셋 버튼을 누르면 UI에 보여줬던 횟수가 초기화 된다.
728x90