Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3, 4단계 - 체스] 허브(방대의) 미션 제출합니다. #529

Merged
merged 82 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
e22fcb3
refactor: 스트림 미니 미션 테스트 Disable
greeng00se Mar 19, 2023
8a78c7b
refactor: 보드 생성 책임을 담당하는 BoardGenerator 추가
greeng00se Mar 19, 2023
4e41311
test: 체스판 검증 기능 가독성 개선
greeng00se Mar 19, 2023
8659523
refactor: static 제거
greeng00se Mar 19, 2023
85e3615
refactor: 사용하지 않는 메서드 제거
greeng00se Mar 19, 2023
547058d
refactor: EmptyPiece의 정적 팩터리 메서드 네이밍 변경
greeng00se Mar 19, 2023
d878f8b
refactor: board 검증부 부정연산자 제거
greeng00se Mar 19, 2023
b904300
refactor: 기물 메서드명 일관성있게 변경
greeng00se Mar 19, 2023
319563d
refactor: 줄바꿈 일관성있게 변경
greeng00se Mar 19, 2023
5d450b8
refactor: Board를 문자열로 변경해주는 Converter 클래스 추가
greeng00se Mar 19, 2023
0441806
refactor: Position 패키지 분리
greeng00se Mar 19, 2023
d9522c7
docs: 3단계 요구사항 정리
greeng00se Mar 19, 2023
0119bd3
feat: 같은 생상인지 확인하는 메서드 추가
greeng00se Mar 19, 2023
de53b5d
feat: 기물의 점수를 계산하는 기능 추가
greeng00se Mar 19, 2023
b1b6758
refactor: 보드 상태패턴 적용
greeng00se Mar 19, 2023
65739a2
feat: 왕이 잡히면 게임이 종료되는 기능 추가
greeng00se Mar 20, 2023
0ad4ac9
feat: 결과를 반환하는 기능 추가
greeng00se Mar 20, 2023
2e408fc
feat: 결과를 계산하는 클래스 추가
greeng00se Mar 20, 2023
505143e
feat: 상태 출력하는 기능 추가
greeng00se Mar 20, 2023
392be91
refactor: 커맨드 길이 검증 개선
greeng00se Mar 20, 2023
a87dc9d
docs: 요구사항 정리
greeng00se Mar 20, 2023
abceac6
refactor: 상태 클래스명 변경
greeng00se Mar 20, 2023
e986881
refactor: Board의 Move가 Position을 받도록 수정
greeng00se Mar 21, 2023
7130470
feat: 데이터베이스 연동기능 추가
greeng00se Mar 21, 2023
01fe9d9
feat: 체스게임 초기화 기능 추가
greeng00se Mar 21, 2023
4e8d1c2
refactor: ChessGame에서 MoveDto 사용하도록 수정
greeng00se Mar 21, 2023
87dc039
refactor: 템플릿 콜백 패턴 적용
greeng00se Mar 21, 2023
2ebb089
refactor: 매개변수명 수정 및 final 추가
greeng00se Mar 21, 2023
4746e46
refactor: Dao 예외 전환 적용, RowMapper 메서드 시그니처 수정
greeng00se Mar 23, 2023
62ecd3a
refactor: 체스게임 내부에서 생성하도록 수정
greeng00se Mar 23, 2023
b476169
remove: 미니미션 코드 제거
greeng00se Mar 23, 2023
6484578
refactor: 상태 패턴 적용한 부분 제거
greeng00se Mar 23, 2023
beb6237
refactor: RowMapper에 Functional Interface 적용
greeng00se Mar 24, 2023
3f4e9c6
feat: 게임이 종료되면 상태가 출력되는 기능 추가
greeng00se Mar 24, 2023
76f20e7
feat: dao 테스트 추가
greeng00se Mar 24, 2023
73fe527
refactor: 데이터베이스 연결 시 ConnectionPool을 사용하도록 수정
greeng00se Mar 25, 2023
0b7ba9d
refactor: Command -> ChessGameCommand로 클래스명 변경
greeng00se Mar 25, 2023
ace0bbc
docs: 요구사항 추가
greeng00se Mar 25, 2023
0f87826
feat: MainCommand, CommandMapper 클래스 추가
greeng00se Mar 25, 2023
5d4f8ff
feat: 로그인한 사용자, 선택한 방에 대한 정보를 가지고 있는 클래스 추가
greeng00se Mar 25, 2023
97207dc
feat: MainController 추가
greeng00se Mar 25, 2023
15536f5
style: 줄바꿈 수정
greeng00se Mar 25, 2023
0b811a0
feat: 사용자 저장 및 조회기능 추가
greeng00se Mar 25, 2023
eb8f6b9
style: ChessDao 코드 포맷 수정
greeng00se Mar 25, 2023
5f14eec
feat: UserService 추가
greeng00se Mar 25, 2023
7bb6ce1
feat: 사용자 회원가입, 로그인, 로그아웃 기능 추가
greeng00se Mar 26, 2023
e9271bd
test: CommandTest 패키지 변경
greeng00se Mar 26, 2023
535553d
refactor: Input, Output 필드로 추가
greeng00se Mar 26, 2023
5315ae3
feat: 중복 로그인, 중복 회원가입시 예외 던지도록 기능 추가
greeng00se Mar 26, 2023
0dc4140
refactor: 유저, 방 도메인 패키지로 이동
greeng00se Mar 26, 2023
c5c6b43
feat: 방 생성, 조회 기능 추가
greeng00se Mar 26, 2023
c9352d3
refactor: RoomDao가 Room 반환하도록 수정
greeng00se Mar 26, 2023
7dc8153
refactor: UserDao가 User 반환하도록 수정
greeng00se Mar 26, 2023
0dea052
feat: RoomController 추가
greeng00se Mar 26, 2023
a9a0f2f
feat: RoomService 추가
greeng00se Mar 26, 2023
20824ad
feat: RoomController 기능 추가
greeng00se Mar 26, 2023
ffac2e8
refactor: UI 수정
greeng00se Mar 26, 2023
b9d5966
refactor: UI 수정
greeng00se Mar 26, 2023
0ed5a87
feat: ThreadLocal 값 제거 로직 추가
greeng00se Mar 26, 2023
ecd5232
refactor: 게임 진행 기능 수정
greeng00se Mar 26, 2023
e025164
Merge remote-tracking branch 'origin/step2' into step2
greeng00se Mar 26, 2023
1ffb77c
refactor: nameDto 제거
greeng00se Mar 26, 2023
ef1ce69
refactor: Action 하나만 사용하도록 수정
greeng00se Mar 26, 2023
1149eae
refactor: static import 설정
greeng00se Mar 26, 2023
682dd16
remove: 사용하지 않는 namedto 제거
greeng00se Mar 26, 2023
fb10477
docs: 요구사항 정리
greeng00se Mar 26, 2023
9717a43
refactor: 방 finished 필드 제거
greeng00se Mar 26, 2023
515fbd1
refactor: 방 미선택시 선택한 방 이름 none으로 보이도록 수정
greeng00se Mar 26, 2023
995fd19
remove: 사용하지 않는 메서드 제거
greeng00se Mar 26, 2023
89d8395
docs: 다이어그램 추가
greeng00se Mar 26, 2023
41e1643
fear: GameController에서 나가면 service에 올라간 board 제거
greeng00se Mar 26, 2023
172151a
refactor: 메서드 위치 변경
greeng00se Mar 26, 2023
ba1baf4
remove: 사용하지 않는 생성자 제거
greeng00se Mar 26, 2023
8751e86
remove: 사용하지 않는 변수 제거
greeng00se Mar 26, 2023
0d5f686
refactor: MainController Controller 인터페이스 구현하는 부분 제거
greeng00se Mar 28, 2023
a8adb91
refactor: 인터페이스명 SubController로 변경
greeng00se Mar 28, 2023
1a13e1f
docs: 외래키 추가
greeng00se Mar 28, 2023
e971899
refactor: DAO optional 적용
greeng00se Mar 28, 2023
f9f953a
refactor: rowMapper 재사용 가능하도록 필드로 설정
greeng00se Mar 28, 2023
e24049a
refactor: 각각의 DaoStub 이너 클래스로 생성
greeng00se Mar 28, 2023
602c24f
refactor: InputView 중복 제거
greeng00se Mar 28, 2023
9c8b418
remove: 사용하지 않는 클래스 제거
greeng00se Mar 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 114 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,22 @@

**체스**

- [x] 화이트, 블랙으로 나뉘며 한 턴씩 번갈아 가며 기물을 움직인다.
- [x] 화이트가 기물을 먼저 움직인다.
- [x] 흰색, 검은색으로 나뉘며 한 턴씩 번갈아 가며 기물을 움직인다.
- [x] 흰색 진영이 기물을 먼저 움직인다.
- [x] 킹이 잡힌 경우 게임을 종료한다.

**보드**

- [x] 보드는 가로 8칸, 세로 8칸로 이루어져있고, 총 64칸이 존재한다.
- [x] 가로(Rank)줄은 아래부터 위로 1 ~ 8이다.
- [x] 세로(Rank)줄은 왼쪽에서 오른쪽으로 A ~ H이다.
- [x] 세로(File)줄은 왼쪽에서 오른쪽으로 A ~ H이다.
- [x] 각 칸에는 기물이 존재하거나, 존재하지 않을 수 있다.
- [x] 보드의 상태는 초기(InitialState), 게임 진행(PlayState), 종료(EndState)가 있다.
- [x] 초기(Initial) 상태는 초기화되지 않은 보드를 의미한다.
- [x] 초기화하는 경우 게임 진행(Play) 상태가 된다.
- [x] 게임 진행(Play) 상태는 초기화 된, 게임을 진행되고 있는 상태를 의미한다.
- [x] 어느 한 쪽의 왕이 잡힌 겨우 게임이 종료(End) 상태가 된다.
- [x] 종료(End) 상태는 게임을 진행할 수 없다.

**기물**

Expand All @@ -38,16 +45,115 @@
- [x] 움직이려는 칸에 같은 편 기물이 존재하는 경우 움직일 수 없다.
- [x] 움직이려는 칸에 상대 편 기물이 존재하는 경우 해당 기물을 잡는다.

### 다이어그램
**점수 계산**

- [x] 각 진영의 점수를 구한다. 기물의 점수는 아래와 같다.
- [x] 킹: 0점
- [x] 퀸: 9점
- [x] 룩: 5점
- [x] 비숍: 3점
- [x] 나이트: 2.5점
- [x] 폰: 1점
- [x] 폰의 경우 세로(File)줄에 여러 개 있는 경우(더블 폰, 트리플 폰) 각 0.5점으로 계산한다.

### 컨트롤러

- [x] MainController
- [x] USER, GAME, START의 명령어를 입력할 수 있다.
- [x] USER 명령어를 입력하면 계정 관리 화면으로 이동한다. (UserController)
- [x] GAME 명령어를 입력하면 게임 관리 화면으로 이동한다. (BoardController)
- [x] 해당 화면은 로그인을 해야지 이동할 수 있다.
- [x] START 명령어를 입력하면 선택한 게임을 시작한다. (GameController)
- [x] 로그인을 하지 않은 경우 게임 기록이 데이터베이스에 저장되지만 따로 관리할 수 없다.

- [x] UserController
- [x] REGISTER, LOGIN, LOGOUT 명령어를 입력할 수 있다.
- [x] REGISTER 명령어와 함께 아이디를 입력하여 계정을 생성할 수 있다. ex) REGISTER herb
- [x] LOGIN 명령어와 함께 아이디를 입력하여 로그인을 할 수 있다. ex) LOGIN herb
- [x] LOGOUT 명령어를 입력하여 로그아웃을 할 수 있다. ex) LOGOUT

- [x] BoardController
- [x] 게임 관리 화면으로 로그인을 해야지 이동할 수 있다.
- [x] HISTORY, CREATE, JOIN 명령어를 입력할 수 있다.
- [x] HISTORY 명령어를 입력하여 진행한 게임을 확인할 수 있다.
- [x] CREATE 명령어를 이용하여 게임을 생성할 수 있다. ex) CREATE 방이름
- [x] JOIN 명령어와 게임 번호를 입력하여 진행할 게임을 선택할 수 있다. ex) JOIN 3

- [x] GameController
- [x] 게임 선택을 하지 않은 경우 새로운 게임이 데이터베이스에 저장된다.
- [x] MOVE, STATUS, END 명령어를 입력할 수 있다.
- [x] MOVE 명령어를 입력하면 기물을 이동시킨다. ex) move e2 e4
- [x] STATUS 명령어를 입력하면 현재 게임의 상태를 볼 수 있다.
- [x] END 명령어를 입력하면 현재 게임을 종료한다.

### 출력

- [x] 게임 시작시 명령어를 안내하는 내용을 출력한다.

```
> 체스 게임을 시작합니다.
> 게임 상태 : status
> 게임 종료 : end
> 게임 초기화 : clear
> 게임 이동 : move source위치 target위치 - 예. move b2 b3
```

- [x] 시작(START) 명령어 입력시 초기화된 보드가 출력된다.

```
RNBQKBNR
PPPPPPPP
........
........
........
........
pppppppp
rnbqkbnr
```

- [x] 이동(MOVE) 명령어 입력시 이동 후의 보드가 출력된다.

```
RNBQKBNR
PPPPPPPP
........
........
....p...
........
pppp.ppp
rnbqkbnr
```

- [x] 상태(STATUS) 명령어 입력시 각 진영의 점수를 확인한다.
- [x] 왕이 잡히는 경우 패배로 출력된다.
- [x] 양쪽 진영 다 왕이 잡히지 않은 경우 점수로 결과를 출력한다.

```
흰색 점수: 38.0
검은색 점수: 38.0
현재 상태: 백색 승
```

### 컨트롤러

```mermaid
graph TD
ChessController --> InputView
ChessController --> OutputView
MainController --> UserController --> UserService --> UserDao
MainController --> RoomController --> RoomService --> RoomDao
MainController --> GameController --> GameSerivce --> GameDao
Comment on lines +141 to +143
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리팩토링 시 README 도 계속 관리해주시는군요 👍 👍 👍

```

### 체스 게임

ChessController --> ChessGame
ChessGame --> Board
```mermaid
graph TD
GameController --> GameInputView
GameController --> GameOutputView --> BoardConverter

GameController --> GameService
GameService --> Board
Board --> BoardGenerator
Board --> GameResult
Position --> Rank
Position --> File

Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ repositories {
dependencies {
testImplementation 'org.assertj:assertj-core:3.22.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
runtimeOnly 'mysql:mysql-connector-java:8.0.28'
}

java {
Expand Down
15 changes: 10 additions & 5 deletions src/main/java/chess/ChessGameApplication.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package chess;

import chess.controller.ChessGameController;
import chess.domain.game.ChessGame;
import chess.controller.Controller;
import chess.controller.ControllerFactory;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ChessGameApplication {

public static void main(String[] args) {
final ChessGameController chessGameController = new ChessGameController(new ChessGame());
chessGameController.run();
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
final Controller controller = ControllerFactory.mainController();
controller.run();
});
executor.shutdown();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import java.util.List;

@FunctionalInterface
public interface ChessGameAction {
ChessGameAction EMPTY = ignore -> {
public interface Action {
Action EMPTY = ignore -> {
};

void execute(final List<String> commands);
Expand Down
74 changes: 0 additions & 74 deletions src/main/java/chess/controller/ChessGameController.java

This file was deleted.

16 changes: 16 additions & 0 deletions src/main/java/chess/controller/CommandMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package chess.controller;

import java.util.HashMap;
import java.util.Map;

public class CommandMapper<K, V> {
private final Map<K, V> commandMapper = new HashMap<>();

public CommandMapper(final Map<K, V> commandMapper) {
this.commandMapper.putAll(commandMapper);
}

public V getValue(final K command) {
return commandMapper.get(command);
}
}
6 changes: 6 additions & 0 deletions src/main/java/chess/controller/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package chess.controller;

@FunctionalInterface
public interface Controller {
void run();
}
77 changes: 77 additions & 0 deletions src/main/java/chess/controller/ControllerFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package chess.controller;

import chess.controller.game.GameController;
import chess.controller.main.MainCommand;
import chess.controller.main.MainController;
import chess.controller.room.RoomController;
import chess.controller.user.UserController;
import chess.db.FixedConnectionPool;
import chess.db.JdbcTemplate;
import chess.repository.GameDao;
import chess.repository.GameJdbcDao;
import chess.repository.RoomDao;
import chess.repository.RoomJdbcDao;
import chess.repository.UserDao;
import chess.repository.UserJdbcDao;
import chess.service.GameService;
import chess.service.RoomService;
import chess.service.UserService;
import chess.view.input.GameInputView;
import chess.view.input.MainInputView;
import chess.view.input.RoomInputView;
import chess.view.input.UserInputView;
import chess.view.output.GameOutputView;
import chess.view.output.MainOutputView;
import chess.view.output.RoomOutputView;
import chess.view.output.UserOutputView;
import java.util.Map;
import java.util.Scanner;

public class ControllerFactory {
private static final Controller INSTANCE;
private static final Scanner SCANNER = new Scanner(System.in);
private static final JdbcTemplate JDBC_TEMPLATE = new JdbcTemplate(FixedConnectionPool.getInstance());

static {
final CommandMapper<MainCommand, Controller> mainCommandMapper = new CommandMapper<>(Map.of(
MainCommand.USER, userController(),
MainCommand.ROOM, roomController(),
MainCommand.START, gameController(),
MainCommand.END, empty()
));
INSTANCE = new MainController(new MainInputView(SCANNER), new MainOutputView(), mainCommandMapper);
}

private static Controller userController() {
return new UserController(new UserInputView(SCANNER), new UserOutputView(), new UserService(userDao()));
}

private static UserDao userDao() {
return new UserJdbcDao(JDBC_TEMPLATE);
}

private static Controller roomController() {
return new RoomController(new RoomInputView(SCANNER), new RoomOutputView(), new RoomService(roomDao()));
}

private static RoomDao roomDao() {
return new RoomJdbcDao(JDBC_TEMPLATE);
}

private static Controller gameController() {
return new GameController(new GameInputView(SCANNER), new GameOutputView(), new GameService(gameDao()));
}

private static GameDao gameDao() {
return new GameJdbcDao(JDBC_TEMPLATE);
}

private static Controller empty() {
return () -> {
};
}

public static Controller mainController() {
return INSTANCE;
}
}
Loading