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

다즐의 체스 게임 #8

Open
wants to merge 70 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
ff4f19d
feat: remove web dependency
woowahan-neo Mar 13, 2023
1bab9ff
feat: add example for functional programming api example
woowahan-neo Mar 13, 2023
98598c0
chore: change package
woowahan-neo Mar 13, 2023
1dd0f93
docs: 구현 기능 목록 정리
woo-chang Mar 14, 2023
a762eb2
feat: 흑과 백 생성
woo-chang Mar 14, 2023
1610552
feat: a부터 h까지 인덱스를 갖는 세로줄 생성
woo-chang Mar 14, 2023
20539aa
feat: 1부터 8까지 인덱스를 갖는 가로줄 생성
woo-chang Mar 14, 2023
295abff
feat: 검은색인지 확인하는 기능 구현
woo-chang Mar 14, 2023
d721903
feat: 기물에서 검은색인지 확인하는 기능 구현
woo-chang Mar 14, 2023
279523e
feat: 체스 기물 구현
woo-chang Mar 14, 2023
a244af0
refactor: 도메인 패키지 분리
woo-chang Mar 14, 2023
b94e60c
feat: 같은 칸인지 확인하는 기능 구현
woo-chang Mar 14, 2023
f8c8cfc
feat: 기물 위치 초기화
woo-chang Mar 15, 2023
a3464a7
feat: 게임 시작/종료 여부 입력 기능 구현
woo-chang Mar 15, 2023
0018acb
feat: 체스 실행명령 상태 구현
woo-chang Mar 15, 2023
85cd37d
feat: 게임 시작 문구 출력
woo-chang Mar 15, 2023
83ce04a
feat: 특정 칸에 존재하는 기물 확인
woo-chang Mar 15, 2023
c3bd497
feat: 체스판 출력
woo-chang Mar 15, 2023
7f968ee
refactor: 패키지명 수정
woo-chang Mar 15, 2023
a94dbb4
feat: 파일 위치(이전, 다음, 거리) 계산 기능 구현
woo-chang Mar 15, 2023
b865ae3
feat: 랭크 위치(이전, 다음, 거리) 계산 기능 구현
woo-chang Mar 15, 2023
ff8bc45
feat: 방향 벡터(다음 파일, 다음 랭크, 방향 확인) 기능 구현
woo-chang Mar 15, 2023
8ccc18f
feat: 룩이 움직이는 경로 구하는 기능 구현
woo-chang Mar 15, 2023
09db9cc
feat: 비숍이 움직이는 경로 구하는 기능 구현
woo-chang Mar 15, 2023
e589479
feat: 퀸이 움직이는 경로 구하는 기능 구현
woo-chang Mar 15, 2023
b4fe033
feat: 나이트가 움직이는 경로 구하는 기능 구현
woo-chang Mar 15, 2023
8933b75
feat: 킹이 움직이는 경로 구하는 기능 구현
woo-chang Mar 15, 2023
7e4d664
feat: 이동 경로로 이동할 수 있는지 확인
woo-chang Mar 16, 2023
cfa6f6a
feat: 폰이 움직이는 경로 확인
woo-chang Mar 16, 2023
72fcb86
feat: 폰이 이동 경로로 이동할 수 있는지 확인
woo-chang Mar 16, 2023
1f57caa
feat: 체스보드에서 기물 위치 업데이트
woo-chang Mar 16, 2023
8278add
refactor: 예외 메시지 수정
woo-chang Mar 16, 2023
50440a5
feat: 폰인지 확인하는 기능 구현
woo-chang Mar 16, 2023
98e5b26
refactor: Optional 반환하도록 수정
woo-chang Mar 16, 2023
3918940
feat: 기물 이동
woo-chang Mar 16, 2023
8c20f4a
refactor: 게임 시작 문구 수정
woo-chang Mar 16, 2023
1d11b77
feat: 체스 게임 구현 완료
woo-chang Mar 16, 2023
b6ee99a
feat: 체스 재입력 기능 구현
woo-chang Mar 17, 2023
727d999
feat: 람다, 스트림 미션 구현
woo-chang Mar 17, 2023
334d8e8
refactor: 모든 테스트에 한글 메서드명을 위한 어노테이션 추가
woo-chang Mar 18, 2023
03c3e84
refactor: 불변 Map을 생성하도록 수정
woo-chang Mar 18, 2023
0e3476e
refactor: static 키워드 사용
woo-chang Mar 18, 2023
86451fb
refactor: Character -> char 수정
woo-chang Mar 18, 2023
47cf4bc
refactor: 변수명 수정
woo-chang Mar 18, 2023
0c5feb5
refactor: 보일러 플레이트 코드가 아래에 위치하도록 수정
woo-chang Mar 18, 2023
d86af18
refactor: 사용하지 않는 코드 삭제
woo-chang Mar 18, 2023
eb37ed2
refactor: Optional을 받는 시점에 처리하도록 수정
woo-chang Mar 18, 2023
661e1e5
feat: 같은 색인지 판단하는 기능 구현
woo-chang Mar 18, 2023
55d8bce
refactor: dto 패키지 controller -> view 수정
woo-chang Mar 18, 2023
04af044
feat: Turn에 알맞은 기물이 움직이는 기능 구현
woo-chang Mar 18, 2023
6f81b3b
refactor: 생성자 주입으로 수정
woo-chang Mar 18, 2023
ca97f14
refactor: 메서드 순서 수정
woo-chang Mar 18, 2023
153a5d4
refactor: 가독성을 위한 코드 수정
woo-chang Mar 18, 2023
adaee92
refactor: 불필요한 import 제거 및 컨벤션 수정
woo-chang Mar 18, 2023
7910ae9
refactor: 도메인 의미에 맞게 x,y -> file,rank 수정
woo-chang Mar 18, 2023
0d0e5f4
feat: SquareFixture 생성
woo-chang Mar 18, 2023
65e4c3d
refactor: Board -> BoardFactory 보드 생성 역할 수정
woo-chang Mar 18, 2023
8f6d9a5
refactor: 각 기물에 맞는 전략을 가지도록 수정
woo-chang Mar 18, 2023
b8237f4
refactor: 게임 상태에 따른 커맨드 패턴 적용
woo-chang Mar 18, 2023
f63f543
refactor: 메서드 순서 수정
woo-chang Mar 18, 2023
9d9f51f
docs: 요구사항 명세서 수정
woo-chang Mar 18, 2023
932d774
refactor: 함수형 인터페이스 어노테이션 사용
woo-chang Mar 19, 2023
abdb43c
refactor: 개행 코드 컨벤션 수정
woo-chang Mar 20, 2023
951b32d
refactor: 용도에 알맞은 변수명으로 수정
woo-chang Mar 20, 2023
b0eb44c
refactor: 사용되지 않는 주석 제거
woo-chang Mar 20, 2023
c015026
refactor: 의미를 잘 나타내는 메서드명으로 수정
woo-chang Mar 20, 2023
c986ac9
refactor: 사용하지 않는 TestPiece 제거
woo-chang Mar 20, 2023
e2eeee0
refactor: vector 패키지 수정
woo-chang Mar 20, 2023
932f1fe
refactor: 동일 전략은 공통화하도록 수정
woo-chang Mar 21, 2023
584a958
feat: 기물에서 책임을 다하기 위해 BoardSnapShot 구현
woo-chang Mar 21, 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: 0 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ repositories {
}

dependencies {
implementation 'com.sparkjava:spark-core:2.9.3'
implementation 'com.sparkjava:spark-template-handlebars:2.7.1'
implementation 'ch.qos.logback:logback-classic:1.2.10'
Comment on lines -12 to -14

Choose a reason for hiding this comment

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

이 부분이 변경된 이유가 있나욥><
큰 이유가 없다면, 변경되지 않았어도 좋을 것 같아욥><!

Copy link
Author

Choose a reason for hiding this comment

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

헉 건들이지 않았던 것 같은데 무슨일이죠 🤔

testImplementation 'org.assertj:assertj-core:3.22.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
}
Expand Down
82 changes: 82 additions & 0 deletions src/docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
## 도메인 객체 그래프

```mermaid
graph TD
ChessController --> InputView
ChessController --> OutputView

ChessController --> ChessGame
ChessGame --> Board

Square --> File
Square --> Rank

Board --> Square
Board --> PIECE

PIECE --> Color

subgraph PIECE
direction BT
Pawn -.-> Piece
Rook -.-> Piece
Bishop -.-> Piece
Knight -.-> Piece
Queen -.-> Piece
King -.-> Piece
end
```

## 구현 기능 목록
Copy link
Member

Choose a reason for hiding this comment

The 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] 체스판을 출력한다.
10 changes: 10 additions & 0 deletions src/main/java/chess/ChessApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package chess;

import chess.controller.ChessController;

public class ChessApplication {
public static void main(String[] args) {
final ChessController chessController = new ChessController();
chessController.run();
}
}
22 changes: 0 additions & 22 deletions src/main/java/chess/WebApplication.java

This file was deleted.

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

import static chess.controller.ChessStartCommand.START;

import chess.controller.dto.ChessBoardDto;
import chess.domain.ChessGame;
import chess.view.InputView;
import chess.view.OutputView;

public class ChessController {

private static final InputView inputView = new InputView();
private static final OutputView outputView = new OutputView();
Comment on lines +19 to +20
Copy link
Member

Choose a reason for hiding this comment

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

여기서 생성하신 이유가 있나욥?

Copy link
Author

@woo-chang woo-chang Mar 20, 2023

Choose a reason for hiding this comment

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

클래스 필드가 늘어나는 것도 막을 수 있고, 뷰 자체로 상태를 가지지 않기에 static으로 둬도 괜찮다고 판단하였습니다!


private final ChessGame chessGame = new ChessGame();

public void run() {
outputView.printStartMessage();
if (readChessStartCommand() == START) {
outputView.printChessBoard(ChessBoardDto.from(chessGame));
playChessGame();
}
}

private ChessStartCommand readChessStartCommand() {
while (true) {
try {
return ChessStartCommand.from(inputView.readChessExecuteCommand());
} catch (IllegalArgumentException e) {
outputView.printErrorMessage(e.getMessage());
}
}

Choose a reason for hiding this comment

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

다즐은 depth 2 어떻게 생각하시나요?

Copy link
Author

Choose a reason for hiding this comment

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

재귀를 사용하지 않으려 했던 소심한 반란이였습니다

}

private void playChessGame() {
while (true) {
try {
repeatMove();
return;
} catch (IllegalArgumentException e) {
outputView.printErrorMessage(e.getMessage());
}
}
}

private void repeatMove() {
ChessGameCommand chessGameCommand = ChessGameCommand.from(inputView.readChessGameCommand());
while (chessGameCommand.getChessExecuteCommand() == ChessExecuteCommand.MOVE) {
chessGame.move(chessGameCommand.getSource(), chessGameCommand.getDestination());
outputView.printChessBoard(ChessBoardDto.from(chessGame));
chessGameCommand = ChessGameCommand.from(inputView.readChessGameCommand());
}
}
}
29 changes: 29 additions & 0 deletions src/main/java/chess/controller/ChessExecuteCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package chess.controller;

import static java.lang.String.format;

import java.util.Arrays;

public enum ChessExecuteCommand {

MOVE("move"),
STOP("end");

private final String input;

ChessExecuteCommand(final String input) {
this.input = input;
}

@Override
public String toString() {
return input;
}

public static ChessExecuteCommand from(final String input) {
return Arrays.stream(ChessExecuteCommand.values())
.filter(chessExecuteCommand -> chessExecuteCommand.input.equals(input))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(format("%s나 %s 중 입력해야 합니다.", MOVE, STOP)));
}
}
84 changes: 84 additions & 0 deletions src/main/java/chess/controller/ChessGameCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package chess.controller;

import chess.domain.board.Square;
import java.util.List;

public class ChessGameCommand {

private final ChessExecuteCommand chessExecuteCommand;
private final Square source;
private final Square destination;

private ChessGameCommand(final ChessExecuteCommand chessExecuteCommand) {
this(chessExecuteCommand, null, null);
}

private ChessGameCommand(
final ChessExecuteCommand chessExecuteCommand,
final Square source,
final Square destination
) {
this.chessExecuteCommand = chessExecuteCommand;
this.source = source;
this.destination = destination;
}

public static ChessGameCommand initMove() {
return new ChessGameCommand(ChessExecuteCommand.MOVE);
}

public static ChessGameCommand from(final List<String> inputs) {
validateEmpty(inputs);
final ChessExecuteCommand chessExecuteCommand = ChessExecuteCommand.from(inputs.get(0));
if (chessExecuteCommand == ChessExecuteCommand.STOP) {
return getEndCommand(inputs, chessExecuteCommand);
}
return getMoveCommand(inputs, chessExecuteCommand);
}

private static void validateEmpty(final List<String> inputs) {
if (inputs.isEmpty()) {
throw new IllegalArgumentException("move랑 end 중 입력하세요.");
}
}

private static ChessGameCommand getEndCommand(
final List<String> inputs,
final ChessExecuteCommand chessExecuteCommand
) {
validateEnd(inputs);
return new ChessGameCommand(chessExecuteCommand);
}

private static void validateEnd(final List<String> inputs) {
if (inputs.size() != 1) {
throw new IllegalArgumentException("end만 입력해야 합니다.");
}
}

private static ChessGameCommand getMoveCommand(
final List<String> inputs,
final ChessExecuteCommand chessExecuteCommand
) {
validateMove(inputs);
return new ChessGameCommand(chessExecuteCommand, Square.from(inputs.get(1)), Square.from(inputs.get(2)));
}

private static void validateMove(final List<String> inputs) {
if (inputs.size() != 3) {
throw new IllegalArgumentException("(예. move b2 b3)와 같이 입력해야 합니다.");
}
}

public ChessExecuteCommand getChessExecuteCommand() {
return chessExecuteCommand;
}

public Square getSource() {
return source;
}

public Square getDestination() {
return destination;
}
}
29 changes: 29 additions & 0 deletions src/main/java/chess/controller/ChessStartCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package chess.controller;

import static java.lang.String.format;

import java.util.Arrays;

public enum ChessStartCommand {

START("start"),
END("end");

private final String input;

Choose a reason for hiding this comment

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

객체의 책임은 무얼 기준으로 평가해야할까요? 저는 "변경내용을 다른 클래스 파일에 전파시키지 않고 내부에서 끝내는 것" 으로 평가하는데요, GameCommand 가 가진 책임은 아마도 입력되는 명령어 변경을 자신 내부에서 끝내는 것 같아요. 아마 아래와 같은 요구사항이 전달될 때 GameCommand 가 빛을 발하겠죠.

start 를 시작 으로
end 를 종료 로
move 를 이동 으로
위와 같은 요구사항이 전달되었을 때 아직 GameCommand 클래스의 존재를 모르는 동료 개발자는 controller 와 view 중 어떤 패키지를 먼저 열어보게 될까요? GameCommand는 어떤 패키지에 위치하는게 더 탐색에 쉬울까요?

라고 현구막이 달아줬어요
리뷰어 방패

Copy link
Author

Choose a reason for hiding this comment

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

위와 동일한 내용인 것 같네요 👍


ChessStartCommand(final String input) {
this.input = input;
}

@Override
public String toString() {
return input;
}

public static ChessStartCommand from(final String input) {
return Arrays.stream(ChessStartCommand.values())
.filter(chessStartCommand -> chessStartCommand.input.equals(input))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(format("%s나 %s 중 입력해야 합니다.", START, END)));
}
}
Loading