데모
주의: 서버가 sleep 상태라서 로드되는데 시간이 걸린다.
개요
Red Tetris는 풀스택 JavaScript로 구현된 멀티플레이어 테트리스 게임으로, ecole42 커리큘럼의 일부다. 이 프로젝트는 JavaScript의 함수형 프로그래밍, 프로토타입 지향 설계, 동적 타입, 비동기 작업을 배우는데에 목적이 있다.
프로젝트 요구사항
- 클라이언트 측: 함수형 프로그래밍 스타일로 작성되어야 한다
- 서버 측: 객체지향 프로그래밍 스타일로 작성되어야 한다
- 테스트 커버리지: 문장(statements), 함수(functions), 라인(lines)의 최소 70%, 분기(branches)의 최소 50%
주요 기능
- 🎮 멀티플레이어 테트리스 - 최대 3명의 플레이어가 동시에 플레이 가능
- 💬 실시간 채팅 - 게임 중 다른 플레이어와 소통
- 🗺️ 다양한 맵 - 다양한 스테이지 구성 선택 가능
- ⚡ 페널티 시스템 - 여러 줄을 지워 상대방에게 페널티 전송
- 🎯 방 시스템 - 게임 방 생성 및 참가
- 🎵 사운드 효과 - 게임 액션에 대한 몰입감 있는 오디오 피드백
- 📊 점수 추적 - 모든 플레이어의 실시간 점수 업데이트
기술 스택
프론트엔드
- React (v17.0.1) - UI 프레임워크
- React Router DOM (v5.2.0) - 클라이언트 사이드 라우팅
- Styled Components (v5.2.0) - CSS-in-JS 스타일링
- Semantic UI React (v2.0.0) - UI 컴포넌트 라이브러리
- Socket.io Client (v2.3.1) - 실시간 통신
백엔드
- Node.js - 런타임 환경
- Express (v4.17.1) - 웹 프레임워크
- Socket.io (v2.3.0) - WebSocket 서버
- Lodash (v4.17.20) - 유틸리티 라이브러리
개발 도구
- Webpack (v5.1.3) - 모듈 번들러
- Babel - JavaScript 컴파일러
- Jest (v26.6.1) - 테스팅 프레임워크
- React Testing Library (v11.1.0) - 컴포넌트 테스팅
- Nodemon (v2.0.6) - 개발 서버 자동 재시작
프로젝트 구조
red_tetris/
├── src/
│ ├── client/ # 프론트엔드 React 애플리케이션
│ │ ├── components/ # React 컴포넌트
│ │ │ ├── MyTetris.jsx # 플레이어 자신의 게임 보드
│ │ │ ├── OthersTetris.jsx # 다른 플레이어들의 게임 보드
│ │ │ ├── Chat.jsx # 채팅 컴포넌트
│ │ │ ├── Room.jsx # 메인 게임 방 컴포넌트
│ │ │ └── ...
│ │ ├── pages/ # 페이지 컴포넌트
│ │ │ ├── Home.jsx # 랜딩 페이지 (방 생성)
│ │ │ └── Tetris.jsx # 게임 페이지
│ │ ├── hooks/ # 커스텀 React 훅
│ │ │ ├── useSocketEvent.js
│ │ │ ├── useCheckRoom.js
│ │ │ └── useInterval.js
│ │ └── gameHelper.js # 클라이언트 사이드 게임 유틸리티
│ │
│ └── server/ # 백엔드 Node.js 애플리케이션
│ ├── classes/ # OOP 클래스
│ │ ├── Game.js # 게임 방 로직
│ │ ├── Player.js # 플레이어 상태 및 액션
│ │ ├── Piece.js # 테트리스 조각 정의
│ │ └── SocketManager.js # Socket 이벤트 핸들러
│ ├── api.js # REST API 라우트
│ ├── gameHelper.js # 서버 사이드 게임 유틸리티
│ ├── ROOMS.js # 방 저장소 (Map)
│ └── index.js # 서버 진입점
│
├── test/ # 테스트 파일
├── config/ # Webpack 설정
└── public/ # 정적 자산
설치
필수 요구사항
- Node.js (v14 이상)
- npm 또는 yarn
설정
# 저장소 클론
git clone https://github.com/woolimi/red_tetris.git
cd red_tetris
# 의존성 설치
npm install
# 또는
yarn install
사용 방법
개발 모드
핫 리로드가 가능한 개발 서버 실행:
# 개발 모드로 클라이언트 빌드
npm run dev:build
# 서버 시작 (nodemon 사용)
npm run server
# 다른 터미널에서 클라이언트 개발 서버 시작
npm run client
클라이언트는 http://localhost:8080에서, 서버는 http://localhost:5000에서 사용 가능
프로덕션 빌드
# 프로덕션용 빌드
npm run build
# 프로덕션 서버 시작
npm start
환경 변수
루트 디렉토리에 .env 파일 생성:
PORT=5000
DOMAIN=http://localhost:8080
MODE=dev # 프로덕션의 경우 'prod'
게임 플레이 방법
- 방 생성/참가: 홈 페이지에서 방 이름과 사용자 이름 입력
- 플레이어 대기: 최대 3명의 플레이어가 방에 참가 가능
- 준비 완료: 준비되면 준비 버튼 클릭
- 게임 시작: 모든 플레이어가 준비되면 방장이 게임 시작 가능
- 플레이: 화살표 키로 조각 이동 및 회전
↑- 조각 회전←/→- 좌우 이동↓- 소프트 드롭Space- 하드 드롭
- 승리: 마지막까지 살아남은 플레이어가 승리!
게임 규칙
- 줄을 지워 점수 획득 (1줄: 10점, 2줄: 30점, 3줄: 60점, 4줄: 120점)
- 2줄 이상을 지우면 다른 플레이어에게 페널티 전송 (쓰레기 줄 추가)
- 마지막까지 남은 플레이어가 게임 승리
테스팅
커버리지와 함께 테스트 실행:
npm run coverage
테스트 커버리지 요구사항:
- 문장(Statements): ≥70%
- 함수(Functions): ≥70%
- 라인(Lines): ≥70%
- 분기(Branches): ≥50%
API 엔드포인트
REST API
-
POST /api/room- 방 생성 또는 입장 검증{ "roomName": "string", "userName": "string" } -
GET /api/room- 방 가용성 확인?roomName=string&userName=string
Socket.io 이벤트
클라이언트 → 서버
ROOM:ADD_PLAYER- 방 참가PLAYER:READY- 플레이어 준비 완료 표시GAME:START- 게임 시작 (방장만 가능)PLAYER:MOVE- 조각 좌우 이동PLAYER:ROTATE- 조각 회전PLAYER:DROPDOWN- 조각 아래로 떨어뜨리기CHAT- 채팅 메시지 전송GAME:CHANGE_MAP- 맵 변경 (방장만 가능)
서버 → 클라이언트
ROOM:PLAYERS- 플레이어 목록 업데이트ROOM:OWNER- 방장 업데이트GAME:START- 게임 시작됨PLAYER:MOVE- 플레이어 이동PLAYER:ROTATE- 플레이어 회전PLAYER:DROPDOWN- 플레이어가 조각을 떨어뜨림PLAYER:GAMEOVER- 플레이어 패배GAME:FINISH- 게임 종료CHAT- 채팅 메시지 수신
아키텍처
클라이언트 아키텍처 (함수형 프로그래밍)
- 함수형 컴포넌트: 모든 React 컴포넌트는 훅을 사용하는 함수형 컴포넌트
- 커스텀 훅: 재사용 가능한 로직을 커스텀 훅으로 추출
- Context API: React Context를 사용한 상태 관리
- 불변 업데이트: 상태 업데이트는 함수형 프로그래밍 원칙을 따름
서버 아키텍처 (객체지향 프로그래밍)
- 클래스: Game, Player, Piece, SocketManager가 클래스로 구현됨
- 캡슐화: private 메서드 및 속성
- 상속: 게임 엔티티를 위한 클래스 기반 구조
- 다형성: 메서드 오버라이딩 및 동적 디스패치
