24/1/5 tic tac toe( 틱택토 )

2024. 1. 8. 08:29카테고리 없음

<TicTacToe.jsx>

import React from "react";
import TicTacToeGame from "../components/TicTacToe/TicTacToeGame";

export default function TicTacToe() {
  return (
    <>
      <TicTacToeGame />
    </>
  );
}

 

<TicTacToeGame.jsx>

import React, { useRef, useState } from "react";
import circle from "../../assets/images/circle.png";
import cross from "../../assets/images/cross.png";
import styled from "styled-components";

let data = ["", "", "", "", "", "", "", "", ""];  //틱택토 ox가 들어갈 자리들이 총9개 빈 문자열로 시작한다.
export default function TicTacToeGame() {
  let [count, setCount] = useState(0);    //총 카운트를 세줄 로직
  let [lock, setLock] = useState(false);    //각 요소를 잠가놓을지 풀어놓을지 결정한다.
  let titleRef = useRef(null);
  let box1 = useRef(null);                 //useRef를 생성해 게임의 타이틀과 각 박스들을 참조할수 있게 세팅
  let box2 = useRef(null);
  let box3 = useRef(null);
  let box4 = useRef(null);
  let box5 = useRef(null);
  let box6 = useRef(null);
  let box7 = useRef(null);
  let box8 = useRef(null);
  let box9 = useRef(null);

  let boxArray = [box1, box2, box3, box4, box5, box6, box7, box8, box9];   //각 박스의태그들을 요소로갖는 배열
  const toggle = (e, num) => { // event와 숫자를 매개변수로 갖는다.
    if (lock) {       // 락상태라면 0 반환
      return 0;
    }
    if (count % 2 === 0) {      //락상태가아니고 카운트가 짝수이면  event가 발생하는 태그를
      e.target.innerHTML = `<img src='${cross}'>`;     //cross이미지를 갖는 태그로 바꾼다.
      data[num] = "x";          //data 배열에 해당 num을 인덱스로 갖는 요소를 x로한다.
      setCount(++count);         //카운트 증가
    } else {
      e.target.innerHTML = `<img src='${circle}'>`;
      data[num] = "o";
      setCount(++count);            //x의 케이스와 동일하다.
    }
    checkWin();           //토글함수 마지막에 승자가 있는지 확인
  };

  const checkWin = () => {         //승자확인로직
    if (data[0] === data[1] && data[1] === data[2] && data[2] !== "") {        //가로 세로 대각선 줄이 한줄안이 빈문자열이
      won(data[2]);                                                                                               //아니면 승자 발생
    } else if (data[3] === data[4] && data[4] === data[5] && data[5] !== "") {
      won(data[5]);                                                                                       //해당 data배열의 해당 인덱스의요소는
    } else if (data[6] === data[7] && data[7] === data[8] && data[8] !== "") {         //x나 o의 스트링을 갖는다.
      won(data[8]);
    } else if (data[0] === data[3] && data[3] === data[6] && data[6] !== "") {
      won(data[6]);
    } else if (data[1] === data[4] && data[4] === data[7] && data[7] !== "") {
      won(data[7]);
    } else if (data[2] === data[5] && data[5] === data[8] && data[8] !== "") {
      won(data[8]);
    } else if (data[0] === data[4] && data[4] === data[8] && data[8] !== "") {
      won(data[8]);
    } else if (data[0] === data[1] && data[1] === data[2] && data[2] !== "") {   //뭐지 이제보니 얘 왜 하나 더있지? ㅋ
      won(data[2]);
    } else if (data[2] === data[4] && data[4] === data[6] && data[6] !== "") {
      won(data[6]);
    }
  };

  const won = (winner) => {
    setLock(true);                    //Lock을 true로 만든다.
    if (winner === "x") {     //위에서 data[i]를 매개변수로 받아서 'x'인지 'o'인지 확인하여 title을 태그를 변경한다.
      titleRef.current.innerHTML = `축하합니다 <img src=${cross}> 승리 !`;
    } else {
      titleRef.current.innerHTML = `축하합니다 <img src=${circle}> 승리 !`;
    }
  };

  const reset = () => {           //게임  초기화 로직
    setLock(false);                          //lock을 false로 만들고
    data = ["", "", "", "", "", "", "", "", ""];         //'x'나 'o'가 들어 있는 배열을 처음 상태로 만든다.
    titleRef.current.innerHTML = `Tic Tac Toe <span>게임</span>`;  //title태그를 처음처럼 만든다.
    boxArray.map((e) => {
      e.current.innerHTML = "";       //맵함수를 돌며 해당 태그들도 빈값으로 만든다.
    });
  };
  return (
    <>
      <Container>
        <Title ref={titleRef}>Tic Tac Toe 게임</Title>  //ref속성에 useRef를 선언해둔 변수를 담아서 해당태그 참조
        <Board>
          <Row1>
            <Boxs
              ref={box1}
              onClick={(e) => {    //온클릭시 토글 이벤트 발생
                toggle(e, 0);
              }}
            ></Boxs>
            <Boxs
              ref={box2}
              onClick={(e) => {
                toggle(e, 1);
              }}
            ></Boxs>
            <Boxs
              ref={box3}
              onClick={(e) => {
                toggle(e, 2);
              }}
            ></Boxs>
          </Row1>
          <Row2>
            <Boxs
              ref={box4}
              onClick={(e) => {
                toggle(e, 3);
              }}
            ></Boxs>
            <Boxs
              ref={box5}
              onClick={(e) => {
                toggle(e, 4);
              }}
            ></Boxs>
            <Boxs
              ref={box6}
              onClick={(e) => {
                toggle(e, 5);
              }}
            ></Boxs>
          </Row2>
          <Row3>
            <Boxs
              ref={box7}
              onClick={(e) => {
                toggle(e, 6);
              }}
            ></Boxs>
            <Boxs
              ref={box8}
              onClick={(e) => {
                toggle(e, 7);
              }}
            ></Boxs>
            <Boxs
              ref={box9}
              onClick={(e) => {
                toggle(e, 8);
              }}
            ></Boxs>
          </Row3>
        </Board>
        <ResetButton
          onClick={() => {
            reset();
          }}
        >
          Reset
        </ResetButton>
      </Container>
    </>
  );
}

const Container = styled.section`
  text-align: center;
`;
const Title = styled.div`
  margin-top: 50px;
  color: white;
  font-size: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
  text-shadow: -5px 5px #ffa732, 0px 5px #ffa732, 1px 0px #ffa732,
    0px -1px #ffa732;
  margin-bottom: 30px;
  gap: 30px;

  & img {
    height: 50px;
  }
`;

const ResetButton = styled.button`
  width: 250px;
  border: none;
  outline: none;
  cursor: pointer;
  border-radius: 50px;
  background: var(--yellow);
  font-size: 26px;
  color: white;
  margin-bottom: 50px;
`;

const Boxs = styled.div`
  display: flex;
  height: 180px;
  width: 180px;
  background: var(--green);
  border: 4px solid white;
  cursor: pointer;
  & img {
    margin: 30px 30px;
  }
`;

const Board = styled.div`
  height: 600px;
  width: 564px;
  display: flex;
  margin: auto;
`;

const Row1 = styled.div``;

const Row2 = styled.div``;

const Row3 = styled.div``;