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

[1단계 - 보드 초기화, 기물 이동] 윌슨(박형균) 미션 제출합니다. #40

Merged
merged 84 commits into from
Mar 26, 2025
Merged
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
5b26e65
🔴red: 폰이 이동 가능한 위치를 리스트로 반환하는 기능 레드 테스트
phk1128 Mar 18, 2025
46d3565
🟢green(Pawn): 폰이 이동 가능한 위치를 리스트로 반환하는 기능 그린 테스트
phk1128 Mar 18, 2025
392eec0
🛠️refactor(Pawn): 폰이 이동 가능한 위치를 리스트로 반환하는 기능 리팩토링
phk1128 Mar 18, 2025
39e1459
🔴red: 목적지의 위치를 알려줄 수 있다 테스트 작성
minSsan Mar 18, 2025
dc4aec8
🟢green: 목적지의 위치를 알려줄 수 있다 테스트 통과 로직 작성
minSsan Mar 18, 2025
6448dd8
🛠️refactor: 기물이 가능한 이동 경로 리스트를 반환하도록 변경
minSsan Mar 18, 2025
56f7a91
feat: 기물 타입 정의
phk1128 Mar 18, 2025
733bc05
feat: 팀 타입 정의
phk1128 Mar 18, 2025
873e99d
feat: 기물 타입 재정의
phk1128 Mar 18, 2025
cedbe32
🛠️refactor: 기물 추상화 및 변수 이름 변경
phk1128 Mar 18, 2025
0201a24
🔴red: 보드 초기화 레드 테스트
phk1128 Mar 18, 2025
865d9b9
🟢green: 보드 초기화 그린 테스트
phk1128 Mar 18, 2025
94ba1f2
🛠️refactor: 보드 초기화 기능 및 기물 추상 클래스 인터페이스로 리팩토링
phk1128 Mar 18, 2025
4726799
feat: 기물 객체 정의
phk1128 Mar 18, 2025
bbca0a9
🛠️refactor: 기물 객체 생성자 추가 및 보드 초기화 리팩토링
phk1128 Mar 18, 2025
e014055
🛠️refactor: 기물을 초기화하는 책임을 ChessPiecePositions으로 이동 및 테스트
phk1128 Mar 18, 2025
ef5e7f0
🛠️refactor: 기물들의 위치를 초기화하는 테스트 리팩토링
phk1128 Mar 18, 2025
a617810
docs: 과제 진행 사항 작성
phk1128 Mar 18, 2025
49fa706
🛠️refactor: 보드 객체 프로덕션 레벨로 이동
phk1128 Mar 18, 2025
d1de6cb
🔴red: 위치 생성 검증 테스트 작성
minSsan Mar 19, 2025
643db30
🟢green: 위치 생성 검증 테스트 통과 코드 작성
minSsan Mar 19, 2025
adce400
🛠️refactor: 위치 검증 로직 리팩터링
minSsan Mar 19, 2025
8ea0b2c
refactor: 위치 검증 로직 추가에 따른 ChessPiece 로직 변경
minSsan Mar 19, 2025
471d4e8
refactor: 초기 위치의 기물 목록을 생성하는 책임을 기물에게 옮기기
minSsan Mar 19, 2025
b20ae07
🔴red: 마의 이동 경로를 반환하는 기능 레드 테스트
phk1128 Mar 19, 2025
5714adc
🛠️refactor: Path 객체 equals 재정의
phk1128 Mar 19, 2025
446c45e
🟢green: 마의 이동경로를 반환하는 기능 그린 테스트
phk1128 Mar 19, 2025
72068ac
feat: 방향 enum 정의
phk1128 Mar 19, 2025
58dcbb5
feat: Elephant 이동 경로 탐색 기능 구현
phk1128 Mar 19, 2025
4c1aa67
feat: Horse 이동 경로 탐색 기능 구현
phk1128 Mar 19, 2025
6c9db55
feat: 위치가 갱신된 ChessPosition을 반환하는 메서드 구현
phk1128 Mar 19, 2025
a09a943
🛠️refactor: 사용하지 않는 클래스 삭제
phk1128 Mar 19, 2025
81e9984
feat: 차 이동 경로 계산 기능 구현
phk1128 Mar 19, 2025
a224ab3
🛠️refactor: 경로를 탐색할때 시작점을 넣지 않는것으로 수정
phk1128 Mar 19, 2025
da3198e
refactor: 장기 기물을 타입 계층으로 변경
minSsan Mar 20, 2025
09c9fcc
refactor: 장기 기물을 타입 계층으로 변경 - 포, 차
minSsan Mar 20, 2025
b517669
🔴red: 폰이 이동할 수 있는 목적지 리스트를 반환할 수 있다 테스트
minSsan Mar 20, 2025
543ffde
refactor: getCoordinateDestinations() 메서드 시그니처 변경
phk1128 Mar 20, 2025
1a6750a
🟢green: 폰의 이동 경로를 반환하는 기능 그린 테스트
phk1128 Mar 20, 2025
aa0fa69
🛠️refactor: 폰의 이동 경로를 반환하는 기능 리팩토링
phk1128 Mar 20, 2025
e87ffc4
🔴red: 마의 이동 가능한 경로를 계산하는 기능 레드 테스트
phk1128 Mar 20, 2025
1564053
🟢green: 마의 이동 가능한 경로를 계산하는 기능 그린 테스트
phk1128 Mar 20, 2025
57c867e
🔴red: 장애물이 있을때 마의 이동 경로를 계산하는 기능 레드 테스트
phk1128 Mar 20, 2025
6999184
🟢green: 장애물이 있을때 마의 이동 경로 계산 기능 그린 테스트
phk1128 Mar 20, 2025
5c77bda
🛠️refactor: 장애물이 있을때 마의 이동 경로 계산 기능 리팩토링
phk1128 Mar 20, 2025
7c03318
🔴red: 상대방의 포가 존재하지 않을때 포의 이동 경로를 계산하는 기능 레드 테스트
phk1128 Mar 20, 2025
8971b00
🟢green: 상대방의 포가 존재하지 않을때 포의 이동 경로를 계산하는 기능 그린 테스트
phk1128 Mar 20, 2025
689cc58
🔴red: 상대방의 포가 존재할때 포의 이동 경로를 계산하는 기능 레드 테스트
phk1128 Mar 20, 2025
5e2170c
🟢green: 상대방의 포가 존재할때 포의 이동 경로를 계산하는 기능 그린 테스트
phk1128 Mar 20, 2025
77ed67d
🔴red: 차의 이동경로를 계산하는 기능 레드 테스트
phk1128 Mar 20, 2025
47995de
🟢green: 차의 이동경로를 계산하는 기능 그린 테스트
phk1128 Mar 20, 2025
f2e53e7
🛠️refactor: 차의 이동경로를 계산하는 기능 리팩토링
phk1128 Mar 20, 2025
95820bc
🟢green: 폰이 이동할 수 있는 목적지 리스트를 반환할 수 있다 테스트 통과 로직 작성
minSsan Mar 20, 2025
bc1d1dc
🔴red: 상이 이동할 수 있는 목적지 리스트를 반환할 수 있다 테스트 작성
minSsan Mar 20, 2025
0a03292
🟢green: 장애물이 없는 경우 상의 목적지 반환 통과 로직 작성
minSsan Mar 20, 2025
8dd4cef
refactor: 테스트 검증 메서드 수정
minSsan Mar 20, 2025
a2f2781
🔴red: 장애물이 있는 경우 상이 모든 목적지를 반환할 수 있다 테스트 작성
minSsan Mar 20, 2025
47ee3cd
🟢green: 장애물이 있는 경우 상이 모든 목적지를 반환할 수 있다 테스트 통과 로직 작성
minSsan Mar 20, 2025
42e19ff
refactor: 목적지에 상대 기물이 있는 경우도 움직일 수 있다
minSsan Mar 20, 2025
fb988b8
refactor: 차는 적의 말이 있는 위치로 이동할 수 있다
minSsan Mar 20, 2025
b15c53e
chore: 공백 삭제
minSsan Mar 20, 2025
a1fef29
refactor: LimitedChessPiece 구현체의 코드 중복 삭제
minSsan Mar 20, 2025
1e5d703
chore: 미사용 클래스 삭제
minSsan Mar 20, 2025
23545b0
docs(README.md): 요구사항 리스트 반영
minSsan Mar 20, 2025
67bdd69
refactor: 메서드 분리
minSsan Mar 20, 2025
5ee128b
refactor: LimitedChessPiece.java -> LimitedMoveChessPiece 이름 변경
minSsan Mar 20, 2025
60fd543
refactor: 패키지 분리
minSsan Mar 21, 2025
a121444
feat: ChessPiecePositions 초기화를 담당하는 ChessPiecePositionsGenerator 추가
minSsan Mar 21, 2025
53e9e5c
fix(Cannon): 포를 만난 경우 더이상 탐색을 이어가지 않도록 변경
minSsan Mar 21, 2025
6e85953
refactor: ChessPiece 의 ChessPosition 필드 삭제
minSsan Mar 22, 2025
48373a0
refactor: 장애물 관련 로직을 별도의 클래스로 분리 및 합성
minSsan Mar 23, 2025
7fdc907
chore: LimitedMoveChessPiece, UnlimitedMoveChessPiece 의 getCoordinate…
minSsan Mar 23, 2025
cf74248
chore: 메서드 final 키워드 추가
minSsan Mar 23, 2025
8fcd07d
chore: 메서드명 수정
minSsan Mar 23, 2025
6d7a389
chore: static import 삭제
minSsan Mar 23, 2025
e8b8b08
refactor(ChessPosition): 위치 검증 메서드 삭제 및 canMove 메서드 추가
minSsan Mar 23, 2025
5657669
chore: test 클래스 패키지 분리
minSsan Mar 23, 2025
728790d
feat: Board에 장기 이동 책임 연결
minSsan Mar 24, 2025
dac11aa
feat(Pawn): 졸/병의 누락된 초기 위치 추가
minSsan Mar 24, 2025
4348045
chore(Path): 불필요한 equals 재정의 삭제
minSsan Mar 24, 2025
9922508
feat: 뷰 연결
minSsan Mar 24, 2025
d4e8d98
refactor: ChessPiece, ChessPiecePositions 순환 참조 문제 개선
phk1128 Mar 24, 2025
388ea70
refactor: 왕, 가드 제거
phk1128 Mar 25, 2025
d4cfb5d
refactor: 추상 메서드는 자식에서 구현 하므로 제거
phk1128 Mar 25, 2025
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
48 changes: 48 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
# java-janggi

장기 미션 저장소

## 미션을 수행하며 반드시 고민할 것
Copy link

Choose a reason for hiding this comment

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

프롤로그 작성이 누락된 것 같아요. 🥲
아무래도 첫 리뷰 요청 마감 기간이 있다보니 시간이 조금 빠듯하셔서 프롤로그까지 작성하시기가 어려우셨을 것 같아요.
다음 리뷰 요청 전에는 프롤로그 작성도 같이 부탁드릴게요. 🙏😉


### ✅ 장기의 말(駒)들은 어떻게 객체로 나누어야 하는가?

장기가 이동할 수 있는 경로를 정의한 인터페이스를 각 기물 종류마다 구현한다.

### ✅ 각 말의 이동 규칙을 어떻게 설계할 것인가?

Enum으로 상,하,좌,우,대각선 4방향을 정의하고, 각 기물이 해당 Enum을 이용해서 이동 규칙을 구현한다.

Comment on lines +11 to +14
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

기물 이동 규칙의 확장 가능성도 고민해보세요.

Enum을 이용해서 4방향·대각선을 정의해두셨지만, 각 기물마다 특수 이동 규칙(포의 뛰어넘기, 마/상 이동 등)을 어떻게 Enum과 함께 처리할지 문서에서도 추가로 언급해주시면 이해도가 더 높아질 것 같습니다.

### ✅ 객체 간의 책임을 어떻게 나눌 것인가?

- 객체가 주체성을 갖고 행동하는가? (_'객체의 결합도가 낮고 응집도가 높은가?'_)
- 객체안의 메서드들을 테스트할 수 있는지 판단 (_'메서드가 public으로 유지 될 수 있는가?'_)
- 객체안의 메서드들이 필드 멤버를 온전히 사용하고 있는지 확인

### ✅ 어떤 원칙을 적용해야 더 좋은 설계를 할 수 있을까?

#### TDD 사이클이 한번 끝날때 마다 아래 항목들을 검사한다.

- 각 객체의 책임이 적절히 할당이 되었는가?
- 메서드 시그니처가 자연스러운가?
- getter의 사용이 적절한가? (_'진짜 여기서 getter를 써야만할까?'_)

Comment on lines +21 to +28
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

헤딩의 마침표를 제거해 마크다운 린트 에러를 피하세요.

현재 "#### TDD 사이클이 한번 끝날때 마다 아래 항목들을 검사한다." 헤딩 끝에 마침표가 있어 lint 에러(MD026)가 발생합니다. 아래와 같이 수정해 보시는 걸 권장드립니다.

-#### TDD 사이클이 한번 끝날때 마다 아래 항목들을 검사한다.
+#### TDD 사이클이 한번 끝날때 마다 아래 항목들을 검사한다
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### ✅ 어떤 원칙을 적용해야 더 좋은 설계를 할 수 있을까?
#### TDD 사이클이 한번 끝날때 마다 아래 항목들을 검사한다.
- 각 객체의 책임이 적절히 할당이 되었는가?
- 메서드 시그니처가 자연스러운가?
- getter의 사용이 적절한가? (_'진짜 여기서 getter를 써야만할까?'_)
### ✅ 어떤 원칙을 적용해야 더 좋은 설계를 할 수 있을까?
#### TDD 사이클이 한번 끝날때 마다 아래 항목들을 검사한다
- 각 객체의 책임이 적절히 할당이 되었는가?
- 메서드 시그니처가 자연스러운가?
- getter의 사용이 적절한가? (_'진짜 여기서 getter를 써야만할까?'_)
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)

23-23: Trailing punctuation in heading
Punctuation: '.'

(MD026, no-trailing-punctuation)

## 기능 구현 목록

### 보드

- [ ] 특정 위치에서 이동 가능한 위치 리스트를 반환한다
- [ ] 점수를 계산 한다
- [ ] 예외 처리
- [ ] 해당 위치에 기물이 없으면 예외
Comment on lines +31 to +36
Copy link

Choose a reason for hiding this comment

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

보드판은 구현이 아직 안된걸까요? 👀


### 기물들의 위치

- [x] 기물들의 위치를 초기화 한다
- [x] 특정 위치에 어떤 기물이 있는지 반환한다

Comment on lines +38 to +42
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

초기화 로직 문서에 에러 처리나 중복 초기화 방안도 덧붙이면 좋겠습니다.

현재 기물 위치 초기화를 수행하는 항목이 있지만, 똑같은 위치나 이미 배치된 위치 등을 다시 초기화할 때의 처리 방안도 함께 기술하시면 유지보수나 협업 시 혼동이 줄어듭니다.

### 기물

- [x] 이동 가능한 위치를 리스트로 반환
- [x] 포 (`Cannon`)
- [x] 차 (`Chariot`)
- [x] 상 (`Elephant`)
- [x] 졸/병 (`Guard`)
- [x] 마 (`Horse`)
- [x] 대상 기물을 먹을 수 있는지 판단
Comment on lines +43 to +51
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

기물별 이동·공격 규칙을 더욱 구체적으로 문서화해 보세요.

각 기물의 이동 가능 경로, 공격 방식 등을 문서에서 조금 더 구체적으로 다루면 새로 참여하는 개발자들도 로직을 빠르게 이해할 수 있을 듯합니다.

13 changes: 13 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import game.JanggiGame;
import view.InputView;
import view.OutputView;

public class Application {
public static void main(String[] args) {
JanggiGame janggiGame = new JanggiGame(
new InputView(),
new OutputView()
);
janggiGame.run();
}
Comment on lines +5 to +12
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

애플리케이션 진입점이 잘 구성되어 있습니다.

JanggiGame 인스턴스를 생성하고 필요한 뷰 컴포넌트를 주입하는 구조가 적절합니다. 의존성 주입 패턴이 잘 적용되어 있습니다.

다음 개선사항을 고려해보세요:

  1. main 메서드에 예외 처리를 추가하여 예상치 못한 예외가 발생했을 때 사용자에게 적절한 메시지를 표시하는 것이 좋을 것 같습니다.
  2. JanggiGame.run() 메서드에 무한 루프가 있어 게임을 정상적으로 종료할 방법이 없습니다. 종료 조건 또는 명령을 추가하는 것을 고려해보세요.
 public static void main(String[] args) {
+    try {
         JanggiGame janggiGame = new JanggiGame(
                 new InputView(),
                 new OutputView()
         );
         janggiGame.run();
+    } catch (Exception e) {
+        System.err.println("게임 실행 중 오류가 발생했습니다: " + e.getMessage());
+    }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public class Application {
public static void main(String[] args) {
JanggiGame janggiGame = new JanggiGame(
new InputView(),
new OutputView()
);
janggiGame.run();
}
public class Application {
public static void main(String[] args) {
try {
JanggiGame janggiGame = new JanggiGame(
new InputView(),
new OutputView()
);
janggiGame.run();
} catch (Exception e) {
System.err.println("게임 실행 중 오류가 발생했습니다: " + e.getMessage());
}
}
}

}
77 changes: 77 additions & 0 deletions src/main/java/domain/Board.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package domain;

import domain.chessPiece.ChessPiece;
import domain.hurdlePolicy.HurdlePolicy;
import domain.path.Path;
import domain.position.ChessPiecePositions;
import domain.position.ChessPosition;
import domain.score.Score;
import domain.type.ChessTeam;

import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class Board {

private final ChessPiecePositions chessPiecePositions;
private final Map<ChessTeam, Score> scores = new EnumMap<>(ChessTeam.class);
Copy link

Choose a reason for hiding this comment

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

따로 Score를 두신 이유가 있을까요? 🤔
score를 미리 업데이트해둠으로써 얻는 장점도있곘지만, 당장 scores가 없더라도 필요한 시점에 (score가 필요하다면) 계산해서 얻을 수 있을 것 같아서요. 😃

(물론 지금도 요구사항에는 만족하지만) 3개 이상의 인스턴스 변수를 가진 클래스를 만들지 않는다.라는 요구사항처럼 가능한 인스턴스 변수 갯수를 줄여보면 좋을 것 같아요.


public Board(final ChessPiecePositions chessPiecePositions) {
this.chessPiecePositions = chessPiecePositions;
scores.putAll(Map.of(
ChessTeam.RED, Score.zero(),
ChessTeam.BLUE, Score.zero()
));
Comment on lines +18 to +25
Copy link

Choose a reason for hiding this comment

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

아래와 같이 생성자를 통해 scores 필드를 바로 초기화해볼 수도 있을 것 같아요.

Suggested change
private final Map<ChessTeam, Score> scores = new EnumMap<>(ChessTeam.class);
public Board(final ChessPiecePositions chessPiecePositions) {
this.chessPiecePositions = chessPiecePositions;
scores.putAll(Map.of(
ChessTeam.RED, Score.zero(),
ChessTeam.BLUE, Score.zero()
));
private final Map<ChessTeam, Score> scores;
public Board(final ChessPiecePositions chessPiecePositions) {
this.chessPiecePositions = chessPiecePositions;
this.scores = Map.of(
ChessTeam.RED, Score.zero(),
ChessTeam.BLUE, Score.zero()
);
}

}

public boolean isExistPieceAt(ChessPosition position) {
return chessPiecePositions.existChessPieceByPosition(position);
}

public void move(final ChessTeam currentTeam, final ChessPosition from, final ChessPosition to) {
validateTeam(currentTeam, from);
validateDestination(from, to);
if (chessPiecePositions.existChessPieceByPosition(to)) {
killTarget(currentTeam, to);
}
chessPiecePositions.move(from, to);
}

public List<ChessPosition> getAvailableDestination(final ChessPosition position) {
Copy link

Choose a reason for hiding this comment

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

가능한 getter나 setter의 느낌이나는 메서드보다는 행위를 잘 표현해주는 네이밍을 고민해보시면 좋을 것 같아요.

ChessPiece chessPiece = chessPiecePositions.getChessPieceByPosition(position);
final List<Path> coordinatePaths = chessPiece.getCoordinatePaths(position);
final HurdlePolicy hurdlePolicy = chessPiece.getHurdlePolicy();
return hurdlePolicy.pickDestinations(chessPiece.getTeam(), coordinatePaths, chessPiecePositions);
Comment on lines +43 to +45
Copy link

Choose a reason for hiding this comment

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

hurdlePolicy를 두는 것은 괜찮은 시도인 것 같아요. 😃
하지만 잘 생각해보면 hurdlePolicycoordinatePaths 모두, chessPiece 객체가 상태로 가지거나 혹은 자신의 상태를 가지고 만들어낸 결과물로 보여요. (결국 getter를 통해 상태를 외부로 뽑아서 직접 처리하는 방식과 유사해지는 것 같네요 🤔)

그렇다면 chessPiece 객체에게 메시지를 보내서 chessPiece보고 수행해달라고 변경해볼 수 있을 것 같고
그러면 결국 AS IS의 상태와 거의 똑같은 상태가 될 것 같아요.

Suggested change
final List<Path> coordinatePaths = chessPiece.getCoordinatePaths(position);
final HurdlePolicy hurdlePolicy = chessPiece.getHurdlePolicy();
return hurdlePolicy.pickDestinations(chessPiece.getTeam(), coordinatePaths, chessPiecePositions);
return chessPiece.pickDestinations(position, chessPiecePositions);

저는 말씀하신 순환참조 문제를 해결하려면 Board 객체가 이동가능한 목적지를 직접 계산해주는 것도 괜찮을 것 같다고 생각해요. 🤔

}

public void validateTeam(final ChessTeam currentTeam, final ChessPosition from) {
ChessPiece chessPiece = chessPiecePositions.getChessPieceByPosition(from);
if (currentTeam != chessPiece.getTeam()) {
throw new IllegalArgumentException("상대편의 기물을 움직일 수 없습니다.");
}
}

private void killTarget(ChessTeam currentTeam, ChessPosition to) {
ChessPiece target = chessPiecePositions.getChessPieceByPosition(to);
updateScore(currentTeam, target);
chessPiecePositions.removeChessPieceByPosition(to);
}

private void updateScore(ChessTeam currentTeam, ChessPiece target) {
Score score = target.getScore();
Score updatedScore = scores.get(currentTeam).add(score);
scores.put(currentTeam, updatedScore);
}

private void validateDestination(final ChessPosition from, final ChessPosition to) {
List<ChessPosition> destinations = getAvailableDestination(from);
if (!destinations.contains(to)) {
throw new IllegalArgumentException("이동할 수 없는 경로입니다.");
}
}

public Map<ChessPosition, ChessPiece> getPositions() {
return chessPiecePositions.getChessPieces();
}
}
44 changes: 44 additions & 0 deletions src/main/java/domain/chessPiece/Cannon.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package domain.chessPiece;

import domain.direction.Direction;
import domain.hurdlePolicy.CannonHurdlePolicy;
import domain.hurdlePolicy.HurdlePolicy;
import domain.position.ChessPosition;
import domain.type.ChessPieceType;
import domain.type.ChessTeam;

import java.util.List;
import java.util.Map;

public class Cannon extends UnlimitedMoveChessPiece {
private static final List<Direction> directions = List.of(
Direction.UP,
Direction.DOWN,
Direction.LEFT,
Direction.RIGHT
);
private final HurdlePolicy hurdlePolicy = new CannonHurdlePolicy();

public Cannon(final ChessTeam team) {
super(team, directions);
}

public static Map<ChessPosition, ChessPiece> initPieces() {
return Map.of(
new ChessPosition(2, 1), new Cannon(ChessTeam.RED),
new ChessPosition(2, 7), new Cannon(ChessTeam.RED),
new ChessPosition(7, 1), new Cannon(ChessTeam.BLUE),
new ChessPosition(7, 7), new Cannon(ChessTeam.BLUE)
);
}

@Override
public HurdlePolicy getHurdlePolicy() {
return hurdlePolicy;
}

@Override
public ChessPieceType getChessPieceType() {
return ChessPieceType.CANNON;
}
}
45 changes: 45 additions & 0 deletions src/main/java/domain/chessPiece/Chariot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package domain.chessPiece;

import domain.direction.Direction;
import domain.hurdlePolicy.HurdlePolicy;
import domain.hurdlePolicy.StopAtHurdlePolicy;
import domain.position.ChessPosition;
import domain.type.ChessPieceType;
import domain.type.ChessTeam;

import java.util.List;
import java.util.Map;

public class Chariot extends UnlimitedMoveChessPiece {

private static final List<Direction> directions = List.of(
Copy link

Choose a reason for hiding this comment

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

static final로 선언하신거보니 상수로 선언하신 것 같은데요.
그렇다면 상수 네이밍 규칙에 맞게 네이밍을 변경해주시면 좋을 것 같아요. 😃

Direction.UP,
Direction.DOWN,
Direction.LEFT,
Direction.RIGHT
);
private final HurdlePolicy hurdlePolicy = new StopAtHurdlePolicy();

public Chariot(final ChessTeam team) {
super(team, directions);
}

public static Map<ChessPosition, ChessPiece> initPieces() {
return Map.of(
new ChessPosition(0, 0), new Chariot(ChessTeam.RED),
new ChessPosition(0, 8), new Chariot(ChessTeam.RED),
new ChessPosition(9, 0), new Chariot(ChessTeam.BLUE),
new ChessPosition(9, 8), new Chariot(ChessTeam.BLUE)
);
}

@Override
public HurdlePolicy getHurdlePolicy() {
return hurdlePolicy;
}

@Override
public ChessPieceType getChessPieceType() {
return ChessPieceType.CHARIOT;
}
}
20 changes: 20 additions & 0 deletions src/main/java/domain/chessPiece/ChessPiece.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package domain.chessPiece;

import domain.hurdlePolicy.HurdlePolicy;
import domain.path.Path;
import domain.position.ChessPiecePositions;
import domain.score.Score;
import domain.type.ChessPieceType;
import domain.position.ChessPosition;
import domain.type.ChessTeam;

import java.util.List;

public interface ChessPiece {
List<ChessPosition> getDestinations(ChessPosition startPosition, ChessPiecePositions positions);
ChessPieceType getChessPieceType();
ChessTeam getTeam();
Score getScore();
List<Path> getCoordinatePaths(final ChessPosition startPosition);
HurdlePolicy getHurdlePolicy();
}
49 changes: 49 additions & 0 deletions src/main/java/domain/chessPiece/Elephant.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package domain.chessPiece;

import domain.direction.Direction;
import domain.direction.Directions;
import domain.hurdlePolicy.HurdlePolicy;
import domain.hurdlePolicy.UnpassableHurdlePolicy;
import domain.position.ChessPosition;
import domain.type.ChessPieceType;
import domain.type.ChessTeam;

import java.util.List;
import java.util.Map;

public class Elephant extends LimitedMoveChessPiece {
private static final List<Directions> directions = List.of(
new Directions(List.of(Direction.UP, Direction.RIGHT_UP, Direction.RIGHT_UP)),
new Directions(List.of(Direction.UP, Direction.LEFT_UP, Direction.LEFT_UP)),
new Directions(List.of(Direction.LEFT, Direction.LEFT_UP, Direction.LEFT_UP)),
new Directions(List.of(Direction.LEFT, Direction.LEFT_DOWN, Direction.LEFT_DOWN)),
new Directions(List.of(Direction.RIGHT, Direction.RIGHT_UP, Direction.RIGHT_UP)),
new Directions(List.of(Direction.RIGHT, Direction.RIGHT_DOWN, Direction.RIGHT_DOWN)),
new Directions(List.of(Direction.DOWN, Direction.LEFT_DOWN, Direction.LEFT_DOWN)),
new Directions(List.of(Direction.DOWN, Direction.RIGHT_DOWN, Direction.RIGHT_DOWN))
);
private final HurdlePolicy hurdlePolicy = new UnpassableHurdlePolicy();

public Elephant(final ChessTeam team) {
super(team, directions);
}

public static Map<ChessPosition, ChessPiece> initPieces() {
return Map.of(
new ChessPosition(0, 2), new Elephant(ChessTeam.RED),
new ChessPosition(0, 6), new Elephant(ChessTeam.RED),
new ChessPosition(9, 2), new Elephant(ChessTeam.BLUE),
new ChessPosition(9, 6), new Elephant(ChessTeam.BLUE)
);
}

@Override
public HurdlePolicy getHurdlePolicy() {
return hurdlePolicy;
}

@Override
public ChessPieceType getChessPieceType() {
return ChessPieceType.ELEPHANT;
}
}
49 changes: 49 additions & 0 deletions src/main/java/domain/chessPiece/Horse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package domain.chessPiece;

import domain.direction.Direction;
import domain.direction.Directions;
import domain.hurdlePolicy.HurdlePolicy;
import domain.hurdlePolicy.UnpassableHurdlePolicy;
import domain.position.ChessPosition;
import domain.type.ChessPieceType;
import domain.type.ChessTeam;

import java.util.List;
import java.util.Map;

public class Horse extends LimitedMoveChessPiece {
private static final List<Directions> directions = List.of(
new Directions(List.of(Direction.UP, Direction.RIGHT_UP)),
new Directions(List.of(Direction.UP, Direction.LEFT_UP)),
new Directions(List.of(Direction.LEFT, Direction.LEFT_UP)),
new Directions(List.of(Direction.LEFT, Direction.LEFT_DOWN)),
new Directions(List.of(Direction.RIGHT, Direction.RIGHT_UP)),
new Directions(List.of(Direction.RIGHT, Direction.RIGHT_DOWN)),
new Directions(List.of(Direction.DOWN, Direction.LEFT_DOWN)),
new Directions(List.of(Direction.DOWN, Direction.RIGHT_DOWN))
);
private final HurdlePolicy hurdlePolicy = new UnpassableHurdlePolicy();

public Horse(final ChessTeam team) {
super(team, directions);
}

public static Map<ChessPosition, ChessPiece> initPieces() {
return Map.of(
new ChessPosition(0, 1), new Horse(ChessTeam.RED),
new ChessPosition(0, 7), new Horse(ChessTeam.RED),
new ChessPosition(9, 1), new Horse(ChessTeam.BLUE),
new ChessPosition(9, 7), new Horse(ChessTeam.BLUE)
);
}

@Override
public HurdlePolicy getHurdlePolicy() {
return hurdlePolicy;
}

@Override
public ChessPieceType getChessPieceType() {
return ChessPieceType.HORSE;
}
}
43 changes: 43 additions & 0 deletions src/main/java/domain/chessPiece/JanggiChessPiece.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package domain.chessPiece;

import domain.hurdlePolicy.HurdlePolicy;
import domain.position.ChessPiecePositions;
import domain.position.ChessPosition;
import domain.score.Score;
import domain.type.ChessTeam;
import domain.path.Path;

import java.util.List;

public abstract class JanggiChessPiece implements ChessPiece {

private final ChessTeam team;

protected JanggiChessPiece(ChessTeam team) {
this.team = team;
}

@Override
public final List<ChessPosition> getDestinations(ChessPosition startPosition, ChessPiecePositions positions) {
List<Path> coordinates = getCoordinatePaths(startPosition);
HurdlePolicy hurdlePolicy = getHurdlePolicy();
return hurdlePolicy.pickDestinations(team, coordinates, positions);
}


@Override
public abstract List<Path> getCoordinatePaths(ChessPosition startPosition);

@Override
public abstract HurdlePolicy getHurdlePolicy();

@Override
public final ChessTeam getTeam() {
return team;
}

@Override
public final Score getScore() {
return getChessPieceType().score;
}
}
Loading