Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
f491808
refactor : 게임 상태 패키지 이름 변경 (State)
yenawee Mar 24, 2023
4d5a5d7
docs : 2단계 기능 요구사항 정리
yenawee Mar 24, 2023
6736e0c
feat : Command 상태에 Status 추가
yenawee Mar 26, 2023
9811eb5
feat : King 이 잡혔을 때 게임 종료 기능 구현
yenawee Mar 26, 2023
35a81cd
feat : 기물별 점수 정의
yenawee Mar 26, 2023
e00d95e
feat : 점수 계산 기능 구현
yenawee Mar 26, 2023
a808317
feat : status 입력 시 점수 및 어느 진영이 이겼는지 출력 기능 구현
yenawee Mar 26, 2023
0dd3b82
feat : Camp -> TeamColor 로 안바뀐 메소드명 및 매개변수 이름 수정
yenawee Mar 26, 2023
0c9985a
docs : 4단계 요구사항 정리
yenawee Mar 26, 2023
e490901
refactor : package 이름 변경
yenawee Mar 26, 2023
6e2c09a
feat : 불필요한 ChessBoardFactory 캐싱 제거. ChessGame 을 키로 하여 ChessBoard 를 캐싱
yenawee Mar 26, 2023
6a351ee
feat : king 이 잡혀서 종료되었을 시에만 status 에 우승자 출력. 아닐 시에는 점수만 출력
yenawee Mar 26, 2023
e80a84b
docs : CRUD 쿼리문 작성
yenawee Mar 26, 2023
7244de8
feat : DB 연결
yenawee Mar 26, 2023
978d9aa
feat : PieceType, TeamColor 를 바탕으로 Piece 생성 기능 구현 추가
yenawee Mar 26, 2023
63f6dbd
feat : ChessGameDao 인터페이스 생성, DB 연결 전 InMemomryChessGameDao 사용
yenawee Mar 26, 2023
64d46dc
feat : ChessGameLoader 생성
yenawee Mar 26, 2023
8f87503
feat : ChessBoard, ChessGame 생성자 추가
yenawee Mar 26, 2023
dc89d3f
test : ChessGame 생성자 수정에 따른 테스트 수정
yenawee Mar 26, 2023
79ca4a3
feat : ChessBoardDao 구현 (DB connection)
yenawee Mar 26, 2023
f0cc766
feat : Move 생성 시 현재 팀은 chessGame 에서 받아온 팀으로 받아오게끔 수정
yenawee Mar 26, 2023
494b1e2
feat : CREATE TABLE chess_game 정보 추가
yenawee Mar 26, 2023
f118208
docs : 기능 구현 사항 업데이트
yenawee Mar 26, 2023
4500fb4
fix : 다음 체스 게임이 시작될 때는 현재 저장되어 있는 turn 과 다른 팀으로 시작되어야 한다
yenawee Mar 27, 2023
798aed2
fix : Select 쿼리 실행 시 Pawn 은 BlackPawn, WhitePawn 으로 나눠서 생성해야 한다
yenawee Mar 27, 2023
8be2aa3
feat : king 이 잡혀서 게임 종료 시엔 DB 초기화
yenawee Mar 27, 2023
e8152d3
feat : chess_game table 의 piece_rank, piece_file 자료형을 TINYINT로 변경
yenawee Mar 27, 2023
66552cd
refactor : source 와 target 의 위치가 상향 대각선인지 하향대각선인지 판단하는 로직을 Direction …
yenawee Mar 27, 2023
853381b
style : 자바 컨벤션
yenawee Mar 27, 2023
71f80eb
docs : 3단계 기능 요구사항 정리
yenawee Mar 24, 2023
5b7c3de
feat : Command 상태에 Status 추가
yenawee Mar 26, 2023
ebc319e
feat : King 이 잡혔을 때 게임 종료 기능 구현
yenawee Mar 26, 2023
17a3ef4
feat : 기물별 점수 정의
yenawee Mar 26, 2023
6b8d545
feat : 점수 계산 기능 구현
yenawee Mar 26, 2023
ad007cd
feat : status 입력 시 점수 및 어느 진영이 이겼는지 출력 기능 구현
yenawee Mar 26, 2023
d65f72f
feat : Camp -> TeamColor 로 안바뀐 메소드명 및 매개변수 이름 수정
yenawee Mar 26, 2023
b90ad88
docs : 4단계 요구사항 정리
yenawee Mar 26, 2023
f3bde69
refactor : package 이름 변경
yenawee Mar 26, 2023
66a295f
feat : 불필요한 ChessBoardFactory 캐싱 제거. ChessGame 을 키로 하여 ChessBoard 를 캐싱
yenawee Mar 26, 2023
a72d05d
feat : king 이 잡혀서 종료되었을 시에만 status 에 우승자 출력. 아닐 시에는 점수만 출력
yenawee Mar 26, 2023
c883c3a
docs : CRUD 쿼리문 작성
yenawee Mar 26, 2023
2045f4e
feat : DB 연결
yenawee Mar 26, 2023
6da294d
feat : PieceType, TeamColor 를 바탕으로 Piece 생성 기능 구현 추가
yenawee Mar 26, 2023
b496182
feat : ChessGameDao 인터페이스 생성, DB 연결 전 InMemomryChessGameDao 사용
yenawee Mar 26, 2023
d13c399
feat : ChessGameLoader 생성
yenawee Mar 26, 2023
9e1be36
feat : ChessBoard, ChessGame 생성자 추가
yenawee Mar 26, 2023
e76dc72
test : ChessGame 생성자 수정에 따른 테스트 수정
yenawee Mar 26, 2023
629c160
feat : ChessBoardDao 구현 (DB connection)
yenawee Mar 26, 2023
4ca82a3
feat : Move 생성 시 현재 팀은 chessGame 에서 받아온 팀으로 받아오게끔 수정
yenawee Mar 26, 2023
a038e53
feat : CREATE TABLE chess_game 정보 추가
yenawee Mar 26, 2023
8b1db28
docs : 기능 구현 사항 업데이트
yenawee Mar 26, 2023
3c937a6
fix : 다음 체스 게임이 시작될 때는 현재 저장되어 있는 turn 과 다른 팀으로 시작되어야 한다
yenawee Mar 27, 2023
157e5a5
fix : Select 쿼리 실행 시 Pawn 은 BlackPawn, WhitePawn 으로 나눠서 생성해야 한다
yenawee Mar 27, 2023
2a2998b
feat : king 이 잡혀서 게임 종료 시엔 DB 초기화
yenawee Mar 27, 2023
3b4087a
feat : chess_game table 의 piece_rank, piece_file 자료형을 TINYINT로 변경
yenawee Mar 27, 2023
d8e9d97
refactor : source 와 target 의 위치가 상향 대각선인지 하향대각선인지 판단하는 로직을 Direction …
yenawee Mar 27, 2023
d763820
style : 자바 컨벤션
yenawee Mar 27, 2023
9687d63
Merge remote-tracking branch 'origin/step2' into step2
yenawee Mar 27, 2023
74200e4
feat : docker 실행 시 chessgame 테이블 생성되도록 설정
yenawee Mar 27, 2023
692af06
docs : chess_game table 자료형 업데이트
yenawee Mar 27, 2023
8b3b61a
.gitignore 에 docker file 추가
yenawee Mar 30, 2023
1cbffc1
docs : 3, 4 단계 수정 사항 기능목록 정리
yenawee Mar 30, 2023
5e8bd2d
.gitignore 수정
yenawee Mar 30, 2023
b9b29bc
docs : readme 에 도커 환경 설정 방법 추가
yenawee Mar 30, 2023
605c525
feat : DB 연결 실패했을 때 커스텀 예외 던지게 수정
yenawee Mar 30, 2023
1d23898
style : 불필요한 주석 삭제
yenawee Mar 30, 2023
19db20e
feat : Direction 에게 상향,하향 대각선인지 물어보는 것으로 수정
yenawee Mar 30, 2023
0b59baa
feat : 매직 넘버 상수화 및 메소드 이름 구체화
yenawee Mar 30, 2023
0309457
feat : 하나의 요청에 대해 하나의 Connection 으로 처리하도록 수정
yenawee Mar 30, 2023
f1c6205
refactor : chessGamecontroller play 메소드 분리
yenawee Mar 30, 2023
456dfff
feat : init.sql 추가
yenawee Mar 30, 2023
00f9208
docs : readme 추가
yenawee Mar 30, 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ out/

### VS Code ###
.vscode/

### docker ###
./src/main/java/chess/docker/db.mysql
55 changes: 51 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,55 @@

## Pair: 져니 [⛄️](http://github.com/cl8d), 제나 [❤️](https://github.com/yenawee)

## 1단계 피드백 사항 및 추가 수정 사항
### 프로그램 실행방법
./java-chess/src/main/java/chess/docker 경로에서 아래 명령어를 입력해주세요

```
docker-compose -p chess up -d
```

정지 시에는 아래 명령어를 입력해주세요
```
docker-compose -p chess down
```

## 3, 4 단계 피드백 사항 및 추가 수정사항
- [x] Readme 에 도커 환경 세팅 설명 추가
- [x] DB connect 연결 에러 발생 시 처리
- [x] 매직 넘버 상수화 및 메소드 이름 구체화
- [ ] Command 처리 로직 수정
- [x] 하나의 요청에 대해 하나의 Connection 으로 처리하도록 수정
- [ ] update 쿼리 수정


## ✔ 4단계 기능 요구사항

- [x] 애플리케이션 재시작 시 이전에 하던 체스 게임을 재시작할 수 있어야 한다
- [x] table
- [x] Piece 정보 : piece_type, team_color, rank, file
- [x] Chessgame 정보 : turn (chessGame id 는 추후 적용 필요)
- [x] CRUD
- [x] Create
- [x] DB에서 불러 올 체스 게임이 없으면 만든다
- [x] Read
- [x] DB에 체스 게임 정보가 저장되어 있다면 DB에서 읽어온다
- [x] Update
- [x] 기물을 움직일 때마다 DB 업데이트 해준다
- [x] 우선 delete 후 save 로 구현 (UPDATE 쿼리 사용으로 변경 필요)
- [x] Delete
- [x] King 이 죽으면 DB 초기화 해준다

## ✔ 3단계 기능 요구사항

- [x] King 이 잡혔을 때 게임 종료
- [x] status 명령 입력 시 점수 출력, 어느 진영이 이겼는지 출력
- [x] commandType 에 status 추가
- [x] 점수 계산
- [x] Queen : 9, Rook : 5, Bishop : 3, Knight : 2.5
- [x] Pawn : 기본 1. 같은 세로 줄에 같은 색의 폰이 있으면 0.5

## 1, 2단계 피드백 사항 및 추가 수정 사항

- [x] 출력 시 View 와 Domain 의존성 제거 - DTO 도입
- [x] 매직 넘버 상수화
- [x] 클래스 및 메소드 네이밍 의미있는 표현으로 변경
Expand All @@ -13,8 +61,7 @@
- [ ] Readme 에 네이밍 사전, 클래스 다이어그램, 프로그래밍 흐름도 정리하기
- [x] 예외 발생 시 재입력


## ✔ 기능 요구사항
## ✔ 1, 2단계 기능 요구사항

### ChessBoard

Expand All @@ -30,7 +77,7 @@

- [x] 체스 게임을 진행한다.

### CampType
### TeamColor

- [x] 사용자의 진영을 관리한다.
- [x] 입력받은 위치의 열이 소문자면 WHITE, 대문자면 BLACK 진영으로 나눈다.
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/chess/ChessApplication.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package chess;

import chess.controller.ChessController;
import chess.dao.ChessBoardDao;

public class ChessApplication {
public static void main(String[] args) {
final ChessController chessController = new ChessController();
final ChessController chessController = new ChessController(new ChessBoardDao());
chessController.run();
}
}
44 changes: 26 additions & 18 deletions src/main/java/chess/controller/ChessController.java
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
package chess.controller;

import chess.controller.status.Start;
import chess.controller.status.Status;
import chess.domain.chess.ChessGame;
import chess.controller.state.Start;
import chess.controller.state.State;
import chess.dao.ChessGameDao;
import chess.dao.ChessGameLoader;
import chess.domain.game.ChessGame;
import chess.domain.piece.Piece;
import chess.domain.position.Position;
import chess.view.InputView;
import chess.view.OutputView;

import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

public class ChessController {
private final ChessGameDao chessGameDao;

public ChessController(final ChessGameDao chessGameDao) {
this.chessGameDao = chessGameDao;
}

public void run() {
OutputView.printStartMessage();
final ChessGame chessGame = new ChessGame();
play(chessGame, gameStatus -> {
if (gameStatus.isRun()) {
printChessBoard(chessGame.getChessBoard());
}
});
ChessGame chessGame = ChessGameLoader.load(chessGameDao);
State gameStatus = new Start(chessGame);
play(chessGame, gameStatus);
}

private void play(final ChessGame chessGame, Consumer<Status> consumer) {
Status gameStatus = new Start(chessGame);
while (gameStatus.isRun()) {
private void play(ChessGame chessGame, State gameStatus) {
while (!chessGame.isEnd() && gameStatus.isRun()) {
gameStatus = getStatus(gameStatus);
consumer.accept(gameStatus);
chessGameDao.update(chessGame);
printChessBoard(gameStatus, chessGame.getChessBoard());
}
if (chessGame.isEnd()) {
chessGameDao.init(chessGame);
}
}

private Status getStatus(Status gameStatus) {
private State getStatus(State gameStatus) {
try {
List<String> commands = InputView.getCommand();
final Command command = Command.findCommand(commands);
Expand All @@ -43,8 +49,10 @@ private Status getStatus(Status gameStatus) {
}
}

private void printChessBoard(Map<Position, Piece> board) {
ChessBoardDto chessBoardDTO = new ChessBoardDto(board);
OutputView.print(chessBoardDTO.getBoardMessage().toString());
private void printChessBoard(State gameStatus, Map<Position, Piece> board) {
if (gameStatus.isRun()) {
ChessBoardDto chessBoardDTO = new ChessBoardDto(board);
OutputView.print(chessBoardDTO.getBoardMessage().toString());
}
}
}
8 changes: 6 additions & 2 deletions src/main/java/chess/controller/Command.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package chess.controller;

import chess.controller.status.CommandType;
import chess.controller.state.CommandType;

import java.util.Arrays;
import java.util.List;
Expand All @@ -9,7 +9,7 @@ public final class Command {
public static final int COMMAND_INDEX = 0;
public static final int MOVE_COMMAND_SIZE = 3;
private static final String COMMAND_ERROR_MESSAGE = "잘못된 명령어 입력입니다.";

private final CommandType type;
private final List<String> commands;

Expand Down Expand Up @@ -38,6 +38,10 @@ public boolean isEnd() {
return type == CommandType.END;
}

public boolean isStatus() {
return type == CommandType.STATUS;
}

public boolean isCorrectWhenMove() {
return commands.size() == MOVE_COMMAND_SIZE;
}
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/chess/controller/ScoreDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package chess.controller;

import chess.domain.piece.TeamColor;
import chess.domain.result.Score;

public class ScoreDto {
private final Double whiteScore;
private final Double blackScore;

public ScoreDto(Score score) {
whiteScore = score.getScore(TeamColor.WHITE);
blackScore = score.getScore(TeamColor.BLACK);
}

public Double getWhiteScore() {
return whiteScore;
}

public Double getBlackScore() {
return blackScore;
}
}
5 changes: 5 additions & 0 deletions src/main/java/chess/controller/state/CommandType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package chess.controller.state;

public enum CommandType {
START, MOVE, END, STATUS
}
30 changes: 30 additions & 0 deletions src/main/java/chess/controller/state/End.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package chess.controller.state;

import chess.controller.Command;
import chess.controller.ScoreDto;
import chess.domain.game.ChessGame;
import chess.domain.piece.TeamColor;
import chess.domain.result.Score;
import chess.view.OutputView;

public final class End implements State {
@Override
public State checkCommand(final Command command) {
throw new IllegalArgumentException("게임이 끝났습니다.");
}

@Override
public boolean isRun() {
return false;
}

public State run(ChessGame chessGame) {
Score score = Score.calculate(chessGame.getChessBoard());
OutputView.printStatus(new ScoreDto(score));
if (chessGame.isEnd()) {
TeamColor winner = chessGame.getCurrentTeamColor();
OutputView.print(winner.name());
}
return new End();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package chess.controller.status;
package chess.controller.state;

import chess.controller.Command;
import chess.domain.chess.ChessGame;
import chess.domain.game.ChessGame;
import chess.domain.piece.TeamColor;
import chess.domain.position.Position;
import chess.domain.position.PositionConverter;

import java.util.List;

public final class Move implements Status {
public final class Move implements State {
public static final int SOURCE_INDEX = 1;
public static final int TARGET_INDEX = 2;

Expand All @@ -21,22 +21,28 @@ public Move(final ChessGame chessGame, final TeamColor teamColor) {
}

@Override
public Status checkCommand(final Command command) {
public State checkCommand(final Command command) {
if (command.isStart()) {
throw new IllegalArgumentException("이미 시작이 완료되었습니다.");
}
if (command.isEnd()) {
return new End();
return new End().run(chessGame);
}
if (command.isStatus()) {
return new Status(chessGame, teamColor).run();
}
validateCommand(command);
return move(command);
}

private Status move(final Command command) {
private State move(final Command command) {
final List<String> commands = command.getCommands();
final Position source = PositionConverter.convert(commands.get(SOURCE_INDEX));
final Position target = PositionConverter.convert(commands.get(TARGET_INDEX));
chessGame.setUp(source, target, teamColor);
if (chessGame.isEnd()) {
return new End().run(chessGame);
}
return new Move(chessGame, teamColor.changeTurn());
}
Comment on lines +38 to 47
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

status 상태를 추가하는 과정에서 Move 와 Status 에서 command 를 확인해 상태를 전환하는 메소드에 if 분기문이 하나 더 추가되어 총 11줄이 되어버렸습니다...
프로그램이 종료될 때 chess game 이 종료되었단 정보를 controller 에 넘겨줘야 하는데 현재 구조로는 ChessController 에 해당 코드를 넘길 수가 없어서 Move 객체의 move 메소드에서 확인해서 게임이 종료된 상태면 End 상태를 반환하게 하는데 설계 변경이 필요해 보입니다.
command 의 입력 상태를 처리하는 로직과 chess game 의 완료 상태를 확인 후 처리하는 로직을 분리하고 싶은데 상태 패턴을 걷어내야 할까요 ??

좋은 고민이네요! 지금 구조에서는 Move에서 분기문을 처리하지 않고, Status에서 처리해도 될 것 같아요.

    @Override
    public State checkCommand(Command command) {
        if (command.isEnd() || chessGame.isEnd()) {
            return new End().run(chessGame);
        }
        if (command.isMove()) {
            Move move = new Move(chessGame, teamColor);
            return move.checkCommand(command);
        }
        if (command.isStatus()) {
            return run();
        }
        throw new UnsupportedOperationException("end, move 명령어만 입력 가능합니다.");
    }

그리고 State에 available(Command)와 같은 메서드를 만들어 각 구현체의 조건을 넣어주면 위 분기문도 없앨 수 있을 것 같은데요, 혹시 이해가 안가시거나 제가 질문을 잘못 이해한거라면 DM 주세요 😃

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

지금 체스 게임 플레이가 Move 상태의 move 메소드에서 chessgame.setup() 으로 시작해서 Status 에서 처리하기는 힘들거같아보입니다..!! (Status 에서 처리가 된다면 status 를 입력해야만 체스게임이 종료되었는지를 확인하게 됨)
말씀해주신대로 available(Command) 의 메소드를 만들어서 분기문을 없애는 방식이 최선일 거 같은데 혹시 어떻게 조건을 넣어줘야 할지 힌트를 좀만 더 주실수있을까요 ?? 😿

Copy link
Copy Markdown

@jnsorn jnsorn Apr 2, 2023

Choose a reason for hiding this comment

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

앗 그렇군요. 제가 구조를 잘못 이해한 것 같네요 😭😭 그렇다면 현재 �로직도 괜찮을 것 같아요!


Expand Down
29 changes: 29 additions & 0 deletions src/main/java/chess/controller/state/Start.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package chess.controller.state;

import chess.controller.Command;
import chess.domain.game.ChessGame;

public final class Start implements State {

private final ChessGame chessGame;

public Start(final ChessGame chessGame) {
this.chessGame = chessGame;
}

@Override
public State checkCommand(final Command command) {
if (command.isStart()) {
return new Move(chessGame, chessGame.getCurrentTeamColor());
}
if (command.isEnd()) {
return new End();
}
throw new IllegalArgumentException("게임이 시작되지 않았습니다.");
}

@Override
public boolean isRun() {
return true;
}
}
9 changes: 9 additions & 0 deletions src/main/java/chess/controller/state/State.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package chess.controller.state;

import chess.controller.Command;

public interface State {
State checkCommand(final Command command);

boolean isRun();
}
44 changes: 44 additions & 0 deletions src/main/java/chess/controller/state/Status.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package chess.controller.state;

import chess.controller.Command;
import chess.controller.ScoreDto;
import chess.domain.game.ChessGame;
import chess.domain.piece.TeamColor;
import chess.domain.result.Score;
import chess.view.OutputView;

public class Status implements State {
private final ChessGame chessGame;
private final TeamColor teamColor;

public Status(ChessGame chessGame, TeamColor teamColor) {
this.chessGame = chessGame;
this.teamColor = teamColor;
}

State run() {
Score score = Score.calculate(chessGame.getChessBoard());
OutputView.printStatus(new ScoreDto(score));
return new Status(chessGame, teamColor);
}

@Override
public State checkCommand(Command command) {
if (command.isEnd()) {
return new End().run(chessGame);
}
if (command.isMove()) {
Move move = new Move(chessGame, teamColor);
return move.checkCommand(command);
}
if (command.isStatus()) {
return run();
}
throw new UnsupportedOperationException("end, move 명령어만 입력 가능합니다.");
}

@Override
public boolean isRun() {
return true;
}
}
5 changes: 0 additions & 5 deletions src/main/java/chess/controller/status/CommandType.java

This file was deleted.

Loading