React

[React][Clone] Chess 게임 만들기 - 2. (1) board settings

binaryJournalist 2021. 2. 9. 11:47
반응형

이전 글

 

2021/02/09 - [React] - [React][Clone] Chess 게임 만들기 (single-player) - 1. setting

 

[React][Clone] Chess 게임 만들기 (single-player) - 1. setting

오랜만의 포스팅...! 새 프로젝트 때문에 몇 달 동안 바빴다. 할당 된 일정 중 두 개가 취소돼서 지난주 이번주 그나마 시간이 났다. 남은 시간 동안 놀고 싶지는 않아서 괜찮아 보이는 소스를 따

binaryjourney.tistory.com

 

 

Chess 게임 만들기 시리즈에서 참고하는 영상

 

www.youtube.com/watch?v=kBR7pDLcC3A

 

 

 

쉴새없이 이어지는 다음 포스팅..!

 

npm Script 에서 start 오른쪽 재생버튼을 클릭한다.

 

 

영상에 따르면 index.js 에 import 추가가 필요하다고 한다.

 

// index.js

import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

 

위를 일단 추가하고

 

 

 

DndProvider 로 App 컴포넌트를 감싸야 한다.

(뭔가 redux store provider 랑 비슷한 듯)

 

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

ReactDOM.render(
  <DndProvider backend={HTML5Backend}>
    <App />
  </DndProvider>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

설명 들어보면 Dnd 가 Drag and Drop 이고 

 

 

chess-react.netlify.app/

 

React Chess App

 

chess-react.netlify.app

이미 완성된 예시에 들어가서 게임해봤는데 체스 게임 플레이방식 자체가 Drag and Drop 이어서 필요한 라이브러리 같다.

 

 

 

그 다음 과정으로는 /src 폴더에 Board 파일을 만드는데 영상에서 jsx 나 js 아무거나 상관 없다고하여 나는 .js 로 만들겠다.

 

 

// /src/Board.js

rfce // 단축어

 

rfce 는 functional component 쉽게 작성해주는 단축어이다.

 

 

// /src/Board.js

import React from 'react'

function Board() {
    return (
        <div>
            
        </div>
    )
}

export default Board;

 

 

Game.js 파일도 생성하는데 Game.js 에는 chess.js를 import 한 후 instance 를 생성해야 한다.

(영상에 따르면 이 과정을 intialize chess game이라고 함, 진짜 말 그대로 create new Chess game임)

 

// /src/Game.js

import * as Chess from 'chess.js';

// initialize chess game
const chess = new Chess();

// method
chess.board();

 

chess.board() 를 영상에서는 "the method we need" 이라고 표현하는데

 

board는 말 그대로 체스판을 대표하고

이 안에는 chess item들이 row로 들어있다고 한다.

 

 

 

그리고 rxjs에서 BehaviorSubject 를 import 하여 새로 선언해준다.

영상 설명에 따르면 BehaviorSubject 는 react의 hook인 useSelector 와 비슷한 역할을 하는 것 같다.

 

// /src/Game.js

import { BehaviorSubject } from 'rxjs';

export const gameSubject = new BehaviorSubject();

 

 

multiple subscribers 가 존재하고 변경사항이 생기면 각기 다른 value를 주어야 하는데 그 때 모든 application을 listen 해주는 게 BehaviorSubject 이다.

 

 

쉽게 말해 "움직임 변경을 위한 데이터 관리"

(뭔가 정리하기 어려웠는데 도움을 받음. 땡큐땡큐)

 

 

 

 

그리고 우리는 체스판 위의 말들의 움직임을 파악해야 하므로

 

BehaviorSubject 안에 chess.board()를 넣어준다. 키는 board 로 한다.

 

// /src/Game.js

import * as Chess from 'chess.js';
import { BehaviorSubject } from 'rxjs';


const chess = new Chess();
export const gameSubject = new BehaviorSubject({
    board: chess.board()
});

 

useSelector 여러 개 필요없이 저 두 줄로 끝나다니 너무나 신기할 뿐

 

 

 

마지막으로 /src/App.js 에 Game 의 gameSubject 와 Board 를 import 해준다.

useEffect, useState 도 사용할 것이므로 useEffect, useState  import 구문도 한 번에 작성해준다.

 

// /src/App.js

import React, { useEffect, useState } from 'react';
import { gameSubject } from './Game';
import Board from './Board';

 

 

체스판 상황인 board와 상황을 업데이트해줄 setBoard를 useState 를 이용하여 만들고

 

useEffect 안에는 구독사항(subscribe)을 설정한다.

game이 바뀔 때마다 체스판을 업데이트 해주도록 말이다.

(여기까지 통틀어 useSelector의 역할을 보는 것 같다.)

 

Board 컴포넌트는 디스플레이를 위한 것 같다. 그래서 체스판 상황인 board를 프로퍼티로 받게 해준다.

 

(redux 쓰다가 안 쓰다보니 매우 답답..)

 

// /src/App.js

function App() {
  
  const [board, setBoard] = useState([]);
  
  useEffect(() => {
    const subscribe = gameSubject.subscribe(game => setBoard(game.board));
    return () => subscribe.unsubscribe();
  }, [])
  
  return (
    <div>
      <Board />
    </div>
  );
}

export default App;

 

 

 

넘긴 board는 Board에서 {} 형태로 받고

받은 board는 map 과 JSON.stringfy를 이용하여 안에 무엇이 들어있는지 한 번 살펴보자.

 

// /src/Board.js

import React from 'react';

function Board({board}) {
    return (
        <div className="board">
            {board.map((piece, index) => (<div key={index}><p>{JSON.stringify(piece)}</p></div>))}
        </div>
    )
}

export default Board;

 

 

화면에 보이는 결과는 이렇다.

 

boardjsonstringfy

 

위에 나온 값은 격자무늬 체스판 위를 보여준다.

가운데 null은 말 그대로 체스판 초기 상태에 아무 말도 없는 공간이고 b는 흑으로, w는 백으로 보면 된다.

타입은 체스말을 가리킨다. 예시로 q는 queen, 여왕이다.

 

chessboardexample

 

 

Board.js 에서 className 을 'board'로 입력하였는데 지금 css 파일에는 board에 관해서 설정된 게 없으므로 App.css 에 가서 board 클래스를 설정해보자.

 

/* /src/App.css */

/* 모든 부분 설정 */
* {
  margin: 0;
  padding: 0;
}

.board {
  width: 100%;
  height: 100%;
  display: flex;
  flex-wrap: wrap;
}

 

 

사실 여기까지 정해도 화면 상 변하는 건 아직 없다.

App.js 에서 더 작성해줘야 한다.

 

// /src/App.js

import './App.css';

  return (
    <div className="container">
      <div className="board-container">
        <Board board={board}/>
      </div>
    </div>
  );

 

App.js 의 div에 container 라는 class를 추가해준다. (아직 없지만 곧 global container 될 예정)

그리고 새 div에 board-container 라는 class를 추가하고 Board 컴포넌트를 감싼다. (아직 없지만222)

 

 

그리고 다시 css로 와서 새로 만들어진 containerboard-container를 만들어준다.

.container {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: rgb(34, 34, 34);
}

.board-container {
  width: 600px;
  height: 600px;
}

 

 

화면을 보면 그냥 새카맣게만 나올 것이다.

 

다음 포스팅은 체스판을 더 체스판답게 바꾸는 것으로 시작하면서 진행하겠다.

반응형