-
Notifications
You must be signed in to change notification settings - Fork 0
다즐의 체스 게임 #8
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
base: main
Are you sure you want to change the base?
다즐의 체스 게임 #8
Changes from all commits
ff4f19d
1bab9ff
98598c0
1dd0f93
a762eb2
1610552
20539aa
295abff
d721903
279523e
a244af0
b94e60c
f8c8cfc
a3464a7
0018acb
85cd37d
83ce04a
c3bd497
7f968ee
a94dbb4
b865ae3
ff8bc45
8ccc18f
09db9cc
e589479
b4fe033
8933b75
7e4d664
cfa6f6a
72fcb86
1f57caa
8278add
50440a5
98e5b26
3918940
8c20f4a
1d11b77
b6ee99a
727d999
334d8e8
03c3e84
0e3476e
86451fb
47cf4bc
0c5feb5
d86af18
eb37ed2
661e1e5
55d8bce
04af044
6f81b3b
ca97f14
153a5d4
adaee92
7910ae9
0d0e5f4
65e4c3d
8f6d9a5
b8237f4
f63f543
9d9f51f
932d774
abdb43c
951b32d
b0eb44c
c015026
c986ac9
e2eeee0
932f1fe
584a958
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| ## 도메인 객체 그래프 | ||
|
|
||
| ```mermaid | ||
| graph TD | ||
| ChessController --> InputView | ||
| ChessController --> OutputView | ||
| ChessController --> ExecuteState | ||
| ChessController --> ChessGame | ||
| ChessGame --> Board | ||
| Square --> File | ||
| Square --> Rank | ||
| BoardFactory --> Board | ||
| Board --> Square | ||
| Board --> PIECE | ||
| PIECE --> Color | ||
| PIECE --> Strategy | ||
| subgraph PIECE | ||
| direction BT | ||
| Pawn -.-> Piece | ||
| Rook -.-> Piece | ||
| Bishop -.-> Piece | ||
| Knight -.-> Piece | ||
| Queen -.-> Piece | ||
| King -.-> Piece | ||
| end | ||
| ``` | ||
|
|
||
| ## 구현 기능 목록 | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 구현 목록이 깔끔해서 좋은 것 같아! |
||
|
|
||
| ### 체스 게임 | ||
|
|
||
| - [x] 기물을 이동시킨다. | ||
|
|
||
| ### 체스 보드 | ||
|
|
||
| - [x] 체스 기물 위치를 알고 있다. | ||
| - [x] 특정 칸에 존재하는 기물을 확인한다. | ||
| - [x] 이동 경로로 이동할 수 있는지 확인한다. | ||
| - [x] 폰이 이동 경로로 이동할 수 있는지 확인한다. | ||
| - [x] 기물 위치를 업데이트한다. | ||
|
|
||
| ### 체스 칸 | ||
|
|
||
| - 세로줄 (File) | ||
| - [x] 왼쪽부터 a ~ h이다. | ||
| - [x] [예외사항] 존재하지 않는 인덱스라면 예외를 던진다. | ||
| - [x] 파일 간 거리를 계산한다. | ||
| - [x] 다음 파일을 반환한다. | ||
| - [x] 이전 파일을 반환한다. | ||
| - 가로줄 (Rank) | ||
| - [x] 아래부터 1 ~ 8이다. | ||
| - [x] [예외사항] 존재하지 않는 인덱스라면 예외를 던진다. | ||
| - [x] 랭크 간 거리를 계산한다. | ||
| - [x] 다음 랭크를 반환한다. | ||
| - [x] 이전 랭크를 반환한다. | ||
|
|
||
| ### 체스 기물 | ||
|
|
||
| - 여러 가지 기물이 존재한다. | ||
| - 폰 | ||
| - 룩 | ||
| - 나이트 | ||
| - 비숍 | ||
| - 퀸 | ||
| - 킹 | ||
| - 색을 가진다. | ||
| - [x] 흑과 백이 존재한다. | ||
| - [x] 검은색인지 확인한다. | ||
| - [x] 같은 색인지 확인한다. | ||
| - [x] 움직이는 경로를 반환한다. | ||
| - [x] 폰인지 확인한다. | ||
|
|
||
| ### 방향 벡터 | ||
|
|
||
| - [x] 움직이려는 방향으로 갈 수 있는지 확인한다. | ||
| - [x] 방향의 다음 파일을 반환한다. | ||
| - [x] 방향의 다음 랭크를 반환한다. | ||
|
|
||
| ### 입력 | ||
|
|
||
| - [x] 게임 실행 명령을 입력한다. | ||
|
|
||
| ### 출력 | ||
|
|
||
| - [x] 게임 시작 문구를 출력한다. | ||
| - [x] 체스판을 출력한다. | ||
| - [x] 에러 메시지를 출력한다. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package chess; | ||
|
|
||
| import chess.controller.ChessController; | ||
| import chess.domain.ChessGame; | ||
| import chess.domain.board.BoardFactory; | ||
|
|
||
| public class ChessApplication { | ||
| public static void main(String[] args) { | ||
| final ChessController chessController = new ChessController( | ||
| new ChessGame(BoardFactory.create()) | ||
| ); | ||
| chessController.run(); | ||
| } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| package chess.controller; | ||
|
|
||
| import static chess.controller.ExecuteState.END; | ||
| import static chess.controller.ExecuteState.INIT; | ||
| import static chess.controller.ExecuteState.MOVE; | ||
| import static chess.controller.ExecuteState.START; | ||
|
|
||
| import chess.domain.ChessGame; | ||
| import chess.domain.board.Square; | ||
| import chess.view.InputView; | ||
| import chess.view.OutputView; | ||
| import chess.view.dto.ChessBoardDto; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.function.Consumer; | ||
|
|
||
| public class ChessController { | ||
|
|
||
| private static final InputView inputView = new InputView(); | ||
| private static final OutputView outputView = new OutputView(); | ||
|
Comment on lines
+19
to
+20
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 여기서 생성하신 이유가 있나욥?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스 필드가 늘어나는 것도 막을 수 있고, 뷰 자체로 상태를 가지지 않기에 |
||
|
|
||
| private final ChessGame chessGame; | ||
| private ExecuteState executeState = INIT; | ||
| private final Map<ExecuteState, Consumer<List<String>>> actions = Map.of( | ||
| START, this::start, | ||
| MOVE, this::move, | ||
| END, this::end | ||
| ); | ||
|
|
||
| public ChessController(final ChessGame chessGame) { | ||
| this.chessGame = chessGame; | ||
| } | ||
|
|
||
| public void run() { | ||
| outputView.printStartMessage(); | ||
| while (executeState != END) { | ||
| playChessGame(); | ||
|
Comment on lines
+35
to
+37
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's cooooool |
||
| } | ||
| } | ||
|
|
||
| private void playChessGame() { | ||
| try { | ||
| final List<String> commands = inputView.readExecuteCommands(); | ||
| final ExecuteState executeState = readExecuteState(commands); | ||
| actions.get(executeState).accept(commands); | ||
| } catch (IllegalArgumentException e) { | ||
| outputView.printErrorMessage(e.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| private ExecuteState readExecuteState(final List<String> commands) { | ||
| validateCommands(commands); | ||
| return ExecuteState.from(commands.get(0)); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 매직넘버들 빼주시면 좋을 것 같아욥~!
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 좋은데요 🏎️ |
||
| } | ||
|
|
||
| private void validateCommands(final List<String> commands) { | ||
| if (commands.size() == 0) { | ||
| throw new IllegalArgumentException("게임 실행을 위해서는 명령 입력이 필요합니다."); | ||
| } | ||
| } | ||
|
|
||
| private void start(final List<String> commands) { | ||
| validateForNotMove(commands); | ||
| validateInit(); | ||
| executeState = START; | ||
| outputView.printChessBoard(ChessBoardDto.from(chessGame)); | ||
| } | ||
|
|
||
| private void end(final List<String> commands) { | ||
| validateForNotMove(commands); | ||
| executeState = END; | ||
| } | ||
|
|
||
| private void move(final List<String> commands) { | ||
| validateForMove(commands); | ||
| validateStart(); | ||
| chessGame.move(Square.from(commands.get(1)), Square.from(commands.get(2))); | ||
| outputView.printChessBoard(ChessBoardDto.from(chessGame)); | ||
| } | ||
|
|
||
| private static void validateForNotMove(final List<String> commands) { | ||
| if (commands.size() != 1) { | ||
| throw new IllegalArgumentException("실행 명령만 정확히 입력이 필요합니다."); | ||
| } | ||
| } | ||
|
|
||
| private void validateInit() { | ||
| if (executeState != INIT) { | ||
| throw new IllegalArgumentException("게임 시작은 처음 상태일때만 가능합니다."); | ||
| } | ||
| } | ||
|
|
||
| private void validateStart() { | ||
| if (executeState != START) { | ||
| throw new IllegalArgumentException("게임 진행중일때만 가능합니다."); | ||
| } | ||
| } | ||
|
|
||
| private static void validateForMove(final List<String> commands) { | ||
| if (commands.size() != 3) { | ||
| throw new IllegalArgumentException("이동을 위해서는 예시와 같이 입력이 필요합니다. 예) move b2 b3"); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package chess.controller; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public enum ExecuteState { | ||
|
|
||
| INIT, | ||
| START, | ||
| MOVE, | ||
| END, | ||
| ; | ||
|
|
||
| public static ExecuteState from(final String input) { | ||
| return Arrays.stream(ExecuteState.values()) | ||
| .filter(executeState -> executeState != INIT) | ||
| .filter(executeState -> executeState.name().toLowerCase().equals(input)) | ||
| .findFirst() | ||
| .orElseThrow(() -> new IllegalArgumentException("유효하지 않은 실행 명령입니다.")); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| package chess.domain; | ||
|
|
||
| import static java.lang.String.format; | ||
|
|
||
| import chess.domain.board.Board; | ||
| import chess.domain.board.Square; | ||
| import chess.domain.piece.Color; | ||
| import chess.domain.piece.Piece; | ||
| import java.util.List; | ||
|
|
||
| public class ChessGame { | ||
|
|
||
| private final Board board; | ||
| private Color turnColor = Color.WHITE; | ||
|
|
||
| public ChessGame(final Board board) { | ||
| this.board = board; | ||
| } | ||
|
|
||
| public void move(final Square source, final Square destination) { | ||
| final Piece piece = board.findPieceOf(source) | ||
| .orElseThrow(() -> new IllegalArgumentException("움직일 기물이 존재하지 않습니다.")); | ||
| validateTurn(piece); | ||
| moveToDestination(piece, source, destination); | ||
| nextTurn(); | ||
| } | ||
|
|
||
| private void validateTurn(final Piece piece) { | ||
| if (!piece.isSameColor(turnColor)) { | ||
| throw new IllegalArgumentException(format("%s의 차례입니다.", turnColor)); | ||
| } | ||
| } | ||
|
|
||
| private void moveToDestination(final Piece piece, final Square source, final Square destination) { | ||
| final List<Square> route = piece.findRoute(source, destination); | ||
| if (!piece.isMovable(source, route, board.getBoardSnapShot())) { | ||
| throw new IllegalArgumentException("움직일 수 없는 위치입니다."); | ||
| } | ||
| board.move(source, destination); | ||
| } | ||
|
|
||
| private void nextTurn() { | ||
| turnColor = turnColor.reverse(); | ||
| } | ||
|
|
||
| public Board getBoard() { | ||
| return board; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package chess.domain.board; | ||
|
|
||
| import chess.domain.piece.Piece; | ||
| import java.util.Collections; | ||
| import java.util.Map; | ||
| import java.util.Optional; | ||
|
|
||
| public class Board { | ||
|
|
||
| private final Map<Square, Piece> board; | ||
|
|
||
| public Board(final Map<Square, Piece> board) { | ||
| this.board = board; | ||
| } | ||
|
|
||
| public Optional<Piece> findPieceOf(final Square square) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. optional을 반환하는 이유가 뭐죠? 여기서 예외를 처리하는 것이 어떨까요?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| return Optional.ofNullable(board.get(square)); | ||
| } | ||
|
|
||
| public void move(final Square source, final Square destination) { | ||
| board.put(destination, board.remove(source)); | ||
| } | ||
|
|
||
| public BoardSnapShot getBoardSnapShot() { | ||
| return BoardSnapShot.from(board); | ||
| } | ||
|
|
||
| public Map<Square, Piece> getBoard() { | ||
| return Collections.unmodifiableMap(board); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분이 변경된 이유가 있나욥><
큰 이유가 없다면, 변경되지 않았어도 좋을 것 같아욥><!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
헉 건들이지 않았던 것 같은데 무슨일이죠 🤔