Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d4bacf5
feat(Position): Position 도메인 κ΅¬ν˜„
haechanmoon Mar 25, 2026
cc4a35d
docs(readme): v1.1 νŒ€ μΆ”κ°€ 및 기물이 κ·œμΉ™μ„ κ°–κ³ μžˆκ²Œν•¨
haechanmoon Mar 25, 2026
4d014e3
feat(Team): μ΄ˆλ‚˜λΌμ™€ ν•œλ‚˜λΌ enum으둜 관리
haechanmoon Mar 25, 2026
782e1dc
docs(readme): v1.2 κ΅¬ν˜„μ˜ 어렀움에 λ”°λ₯Έ 도메인 λ³€κ²½ -> λŒμ•„κ°€λŠ” μ½”λ“œλ₯Ό μš°μ„  λ§Œλ“€μ–΄λ³΄κΈ°
haechanmoon Mar 26, 2026
68a19d2
feat: ν•΄λ‹Ή 기물은 νŒ€κ³Ό κΈ°λ¬Ό νƒ€μž…μ„ κ°€μ§„λ‹€. TDD κ΅¬ν˜„
haechanmoon Mar 26, 2026
0dac849
feat: 상차림은 λ§ˆμƒλ§ˆμƒμœΌλ‘œ κ³ μ •ν•˜μ—¬ λ³΄λ“œ μ΄ˆκΈ°ν™”
haechanmoon Mar 26, 2026
7aade2e
feat: 각 기물은 고유의 κ·œμΉ™μ„ κ°€μ§„λ‹€.
haechanmoon Mar 27, 2026
8e805d5
refactor: MoveRule μΈν„°νŽ˜μ΄μŠ€ 생성
haechanmoon Mar 27, 2026
ed501e2
feat: 쑸의 이동가λŠ₯ μ—¬λΆ€λ₯Ό νŒλ‹¨
haechanmoon Mar 30, 2026
e55e727
test: 마의 이동가λŠ₯ μ—¬λΆ€λ₯Ό νŒλ‹¨
haechanmoon Mar 30, 2026
27ffdfc
fix(board): μƒμ„±μžμ—μ„œ λ³΄λ“œμ΄ˆκΈ°ν™” 제거
haechanmoon Mar 30, 2026
361391c
test: 상,사,μ™•μ˜ 이동가λŠ₯ μ—¬λΆ€λ₯Ό νŒλ‹¨
haechanmoon Mar 30, 2026
a49a2c4
feat: 차의 이동가λŠ₯ μ—¬λΆ€λ₯Ό νŒλ‹¨
haechanmoon Mar 30, 2026
adac323
feat: 포의 이동가λŠ₯ μ—¬λΆ€λ₯Ό νŒλ‹¨
haechanmoon Mar 30, 2026
08f4aad
test: DisplayNameκ³Ό λ©”μ„œλ“œλͺ… λ³€κ²½
haechanmoon Mar 30, 2026
f7f0f3e
feat: 뷰와 컨트둀러 κΈ°λŠ₯ κ΅¬ν˜„
haechanmoon Mar 30, 2026
61a6903
feat: μž¬μž…λ ₯ 둜직 κ΅¬ν˜„
haechanmoon Mar 30, 2026
3ed382f
refactor: μ½”λ“œ μŠ€νƒ€μΌ κ°œμ„ 
haechanmoon Mar 30, 2026
c6d763a
test: μ‹€νŒ¨ν•˜λŠ” 포 ν…ŒμŠ€νŠΈ μ½”λ“œ μˆ˜μ •
Mar 30, 2026
8bf0029
refactor: λ³΄λ“œ μ΄ˆκΈ°ν™” 둜직 반볡문으둜 κ΅¬ν˜„(상차림: λ§ˆμƒλ§ˆμƒ)
Mar 31, 2026
2111fbf
refactor: yμ’Œν‘œλ₯Ό λ‚˜λΌμ— 따라 κ³„μ‚°ν•˜λŠ” λ‘œμ§μ„ team에 κ΅¬ν˜„
Mar 31, 2026
0587fe5
refactor: PieceTypeμ—μ„œ λ³΄λ“œμ— ν•΄λ‹Ή κΈ°λ¬Ό 배치
Mar 31, 2026
8e93874
refactor: 경둜 μ°ΎκΈ° κΈ°λ¬Όμ—μ„œ κ΅¬ν˜„
Mar 31, 2026
5dc1bdc
refactor: convertToPositions λ©”μ„œλ“œ μ±…μž„ 뢄리
Mar 31, 2026
7a995a5
refactor: 이용 κ°€λŠ₯ν•œ μ’Œν‘œ κ°€μ Έμ˜€λŠ” κΈ°λŠ₯ λ©”μ„œλ“œ μΆ”μΆœ
Mar 31, 2026
09ebf2c
fix: 도착지 검증 λ©”μ„œλ“œμ—μ„œ equals둜 비ꡐ
Apr 1, 2026
cd99a6a
test(PieceTest): 차인지, 포인지, 같은 νŒ€μΈμ§€ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œ μΆ”κ°€
Apr 1, 2026
3a0ad8f
test(PositionTest): λ°©ν–₯ 적용 ν›„ μ’Œν‘œ λ°˜ν™˜ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈ μ½”λ“œ μΆ”κ°€
Apr 1, 2026
e0bc2e9
refactor: λ©”μ„œλ“œ 배치 μˆœμ„œ λ³€κ²½
Apr 1, 2026
e46df42
refactor(JanggiController): λ©”μ„œλ“œ μΆ”μΆœ
Apr 1, 2026
f300e60
feat: 상차림 선택 둜직 κ΅¬ν˜„
Apr 1, 2026
063b6a7
refactor: BoardInitiatorμ—κ²Œ λ³΄λ“œ μ΄ˆκΈ°ν™” μ±…μž„ λ„˜κΈ°κΈ°
Apr 2, 2026
0648bd3
refactor: RouteConverterμ—κ²Œ 경둜λ₯Ό μ’Œν‘œ ν˜•νƒœλ‘œ λ°”κΎΈλŠ” μ±…μž„ λ„˜κΈ°κΈ°
Apr 2, 2026
b57e61a
refactor: RouteCheckerμ—κ²Œ μ§€λ‚˜κ°ˆ 수 μžˆλŠ” 경둜 확인 μ±…μž„ λ„˜κΈ°κΈ°
Apr 2, 2026
3059d68
refactor: νŒ¨ν‚€μ§€ ꡬ쑰 μ‘°μ •
Apr 2, 2026
3c800f6
test(Board): λ³΄λ“œ ν…ŒμŠ€νŠΈ μΆ”κ°€
Apr 2, 2026
eff4d10
test(RouteConverter): λ³΄λ“œ λ²”μœ„ 내에 μžˆμ„ λ•Œ κ°€λŠ₯ν•œ 경둜λ₯Ό μ’Œν‘œλ‘œ λ³€ν™˜ν•˜λŠ” ν…ŒμŠ€νŠΈ μΆ”κ°€
Apr 2, 2026
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
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
# java-janggi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

10쀄 μš”κ΅¬μ‚¬ν•­ μ§€μΌœλ³΄μžλŠ” λͺ©ν‘œ 잘 μ§€μΌœμ£Όμ…¨μ–΄μš” πŸ‘
(아직 μ’€ λ„˜λŠ” 곳듀이 보이긴 ν•˜λŠ”λ°, κ·Έλž˜λ„ μΆ©λΆ„νžˆ κ³ λ―Όν•΄μ£Όμ‹  κ²ƒμœΌλ‘œ λ³΄μ—¬μ„œ λ„˜μ–΄κ°‘λ‹ˆλ‹€ γ…Ž)

μ§€κΈˆλΆ€ν„°λŠ” λ©”μ„œλ“œ 길이 10쀄 외에도 λ‹€λ₯Έ μš”κ΅¬μ‚¬ν•­λ“€μ„ ν•œ 번 챙겨보면 쒋을 것 κ°™μ•„μš”.
특히 indent μš”κ΅¬μ‚¬ν•­μ„ μ€‘μ μœΌλ‘œ 챙겨보죠.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μ•„ 그리고 view μͺ½μ€ μš”κ΅¬μ‚¬ν•­ μ μš©μ„ 크게 κ³ λ €λ₯Ό μ•ˆν•΄μ£Όμ‹  것 같은데,
μ €λŠ” view도 μš”κ΅¬μ‚¬ν•­μ— 맞게, 그리고 가독성 μ’‹κ²Œ λ¦¬νŒ©ν„°λ§ ν•΄μ£Όμ…¨μœΌλ©΄ ν•©λ‹ˆλ‹€.

λ°±μ—”λ“œ κ°œλ°œμžλΌλ„ ν”„λ‘œμ νŠΈ λ‚΄μ—μ„œ view λ₯Ό κ΄€λ¦¬ν•˜λŠ” 상황이라면,
λ°±μ—”λ“œ 둜직과 λ™μΌν•˜κ²Œ 잘 κ΄€λ¦¬ν•΄μ€˜μ•Ό ν•œλ‹€κ³  μƒκ°ν•˜κ±°λ“ μš”. μ˜ˆμ™Έλ₯Ό 두면 μ•ˆλΌμš”.

μ‹€μ œλ‘œ λ°±μ—”λ“œμΈλ°λ„ ν”„λ‘ νŠΈμ—”λ“œλ₯Ό λ‹€λ€„μ•Όν•˜λŠ” κ²½μš°κ°€ ꡉμž₯히 자주 λ°œμƒν•˜κ³  (생각보닀 더 자주 λ°œμƒν•©λ‹ˆλ‹€)
μ§€κΈˆμ²˜λŸΌ TUI λ₯Ό λ§Œλ“€μ–΄μ•Όν•˜λŠ” κ²½μš°λ„ μƒκΈ°κ±°λ“ μš”.
κ·Έ λ•Œ κ°€μ„œ 'μ•„ view λŠ” μ€‘μš”ν•œ λ°±μ—”λ“œ 둜직이 μ•„λ‹ˆλ‹ˆκΉŒ' 라고 말할 μˆ˜λŠ” μ—†μž–μ•„μš” :)

근데 view 닀뀄야 ν•  일이 μ§„μ§œ 자주 μžˆμ„κ²λ‹ˆλ‹€. κ°•μ‘°ν•˜λŠ”κ±°μ˜ˆμš”.
μš°ν…Œμ½” 크루듀 보면 선을 μ™„μ „νžˆ κ·Έμ–΄λ²„λ¦¬λŠ” κ²½ν–₯이 μžˆλŠ” 것 κ°™μ•„μ„œμš”.

뷰에 indent 외에도 else μ‚¬μš©κ³Ό public μƒμˆ˜ 등이 μžˆλŠ”λ°,
μ „μ²΄μ μœΌλ‘œ λ¦¬νŒ©ν„°λ§ ν•΄μ£Όμ„Έμš”.


μž₯κΈ° λ―Έμ…˜ μ €μž₯μ†Œ

version : 1.2 (κ΅¬ν˜„μ˜ 어렀움에 λ”°λ₯Έ 도메인 λ³€κ²½ : λŒμ•„κ°€λŠ” μ½”λ“œλ₯Ό μš°μ„  λ§Œλ“€μ–΄λ³΄κΈ°)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

κΈ°λŠ₯ λͺ©λ‘μ„ 체크리슀트둜 μ •λ¦¬ν•˜κ³ , κ΅¬ν˜„ μ™„λ£Œ μ—¬λΆ€λ₯Ό ν‘œμ‹œν•œ 점 μ’‹μŠ΅λ‹ˆλ‹€.

v1.2둜 "λŒμ•„κ°€λŠ” μ½”λ“œλ₯Ό μš°μ„  λ§Œλ“€μ–΄λ³΄κΈ°"에 μ§‘μ€‘ν•œ 것도 μ’‹μ•˜λ‹€κ³  μƒκ°ν•΄μš”.
μ²˜μŒλΆ€ν„° μ™„λ²½ν•˜κ²Œ μ„€κ³„ν•˜λ €λ‹€ ν•œ 쀄도 λͺ» μ“°λŠ” 것보닀,
일단 λ™μž‘ν•˜λŠ” μ½”λ“œλ₯Ό λ§Œλ“€κ³  κ·Έ μœ„μ— λ¦¬νŒ©ν„°λ§ν•˜λŠ” κ²½ν—˜μ΄ 훨씬 κ°’μ§€κ±°λ“ μš”.

이제 "λŒμ•„κ°€λŠ” μ½”λ“œ"λŠ” λ§Œλ“€μ–΄μ‘ŒμœΌλ‹ˆ, λ¦¬νŒ©ν„°λ§μ˜ μ°¨λ‘€μž…λ‹ˆλ‹€ :)


# μ‹œλ‚˜λ¦¬μ˜€

1. ν•œλ‚˜λΌ μ‚¬μš©μžκ°€ 상차림을 μ„ νƒν•œλ‹€.
2. μ΄ˆλ‚˜λΌ μ‚¬μš©μžκ°€ 상차림을 μ„ νƒν•œλ‹€.
3. μ΄ˆλ‚˜λΌ μ‹œμž‘
1. 이동할 기물의 μ’Œν‘œλ₯Ό μž…λ ₯ν•œλ‹€. (무λ₯΄κΈ° : q)

ν˜„μž¬ λ³΄λ“œλ₯Ό 보여쀀닀.

ex) 쑸을 μ„ νƒν–ˆμŠ΅λ‹ˆλ‹€. 쑸은 ν˜„μž¬ (1,1)에 μžˆμŠ΅λ‹ˆλ‹€.

2. ν•΄λ‹Ή 기물이 이동할 수 μžˆλŠ” μ’Œν‘œλ₯Ό 보여쀀닀. (κΈ°λ¬Ό λ‹€μ‹œμ„ νƒ : r)
- λ§Œμ•½μ— 아무데도 이동 λΆˆκ°€λŠ₯ν•˜λ©΄ λ‹€μ‹œ a둜 λŒμ•„κ°€μ„œ μ„ νƒν•˜κ²Œ ν•œλ‹€.
3. 보여진 μ’Œν‘œ 쀑 이동할 μ’Œν‘œλ₯Ό μž…λ ₯ν•œλ‹€.
- 이동할 μ’Œν‘œλ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”.(μ˜ˆμ‹œ: 3, 5)
4. ν•΄λ‹Ή μ’Œν‘œλ‘œ μ΄λ™ν•œλ‹€.
4. ν•œλ‚˜λΌ μ‹œμž‘

μ΄ˆλ‚˜λΌμ™€ 동일

# 도메인 κ΅¬ν˜„ 리슀트

- **λ³΄λ“œ**
- [x] 상차림은 λ§ˆμƒλ§ˆμƒμœΌλ‘œ κ³ μ •ν•˜μ—¬ μ΄ˆκΈ°ν™” ν•œλ‹€. (μΆ”ν›„ μΆ”κ°€ μ˜ˆμ •)
- [x] ν•΄λ‹Ή 기물의 이동 κ°€λŠ₯ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•œλ‹€
- 멱에 λ‹€λ₯Έ 기물이 있으면 μ•ˆ λ˜λŠ” 경우: 마,상, μ‘Έ/병, μ°¨, μž₯, 사
- λ©± 사이에 ν•˜λ‚˜μ˜ 기물이 μžˆμ–΄μ•Ό ν•˜λŠ” 경우: 포
- κ·Έ 기물이 ν¬μ—¬μ„œλŠ” μ•ˆ λœλ‹€.
- μ΄λ™ν•˜κ³ μž ν•˜λŠ” μ’Œν‘œ μžμ²΄κ°€ 포 or 아ꡰ이면 μ•ˆ λœλ‹€.
- [x] 기물을 μ΄λ™μ‹œν‚¨λ‹€.
- **μ’Œν‘œ**
- [x] λ³΄λ“œ λ‚΄μ˜ μ’Œν‘œ λ²”μœ„λ₯Ό κ²€μ¦ν•œλ‹€.
- **κΈ°λ¬Ό**
- [x] ν•΄λ‹Ή 기물은 νŒ€κ³Ό κΈ°λ¬Ό νƒ€μž…μ„ κ°€μ§„λ‹€.
- [x] PieceType(enum) μž‘μ„±
- [x] νŒ€ Team(enum) μž‘μ„±
- **κ·œμΉ™**
- [x] 각 기물은 고유의 κ·œμΉ™μ„ κ°€μ§„λ‹€.
10 changes: 10 additions & 0 deletions src/main/java/janggi/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package janggi;

import janggi.controller.JanggiController;

public class Application {
public static void main(String[] args) {
JanggiController janggiController = new JanggiController();
janggiController.run();
}
}
92 changes: 92 additions & 0 deletions src/main/java/janggi/controller/JanggiController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package janggi.controller;

import janggi.domain.board.Board;
import janggi.domain.board.BoardFormation;
import janggi.domain.board.BoardInitiator;
import janggi.domain.common.Position;
import janggi.domain.common.Team;
import janggi.domain.route.RouteChecker;
import janggi.view.InputView;
import janggi.view.OutputView;
import java.util.List;
import java.util.function.Supplier;

public class JanggiController {

private final InputView inputView = new InputView();
private final OutputView outputView = new OutputView();
private final BoardInitiator boardInitiator = new BoardInitiator();
private final RouteChecker routeChecker = new RouteChecker();

public void run() {
Board board = new Board();

choiceBoardFormation(board);

boolean isChoTurn = true;

outputView.printBoard(board.getBoard());

while (true) {
playGame(isChoTurn, board);

isChoTurn = changeTurn(isChoTurn);
}
}

private void choiceBoardFormation(Board board) {
askBoardFormation(board, Team.HAN);
askBoardFormation(board, Team.CHO);
}

private void askBoardFormation(Board board, Team team) {
outputView.printBoardFormation(team);
int boardFormationChoice = inputView.readBoardFormationChoice();
BoardFormation formation = BoardFormation.selectByChoice(boardFormationChoice);
boardInitiator.initializeByFormation(board, formation, team);
}

private void playGame(boolean isChoTurn, Board board) {
outputView.printTurnMessage(isChoTurn);

Position movePiecePosition = doLoop(() -> askMovePiecePosition(board));

List<Position> availablePositions = routeChecker.findAvailablePositions(board, movePiecePosition);

outputView.printAvailablePositions(board.getBoard(), availablePositions);

Position movePosition = doLoop(() -> askMovePosition(board, movePiecePosition));

board.movePiece(movePiecePosition, movePosition);

outputView.printBoard(board.getBoard());
}

private boolean changeTurn(boolean isChoTurn) {
return !isChoTurn;
}

private Position askMovePosition(Board board, Position movePiecePosition) {
outputView.printMoveChoiceInfo();
Position position = inputView.readPosition();
routeChecker.validateDestination(board, movePiecePosition, position);
return position;
}

private Position askMovePiecePosition(Board board) {
outputView.printMoveInfo();
Position position = inputView.readPosition();
routeChecker.findAvailablePositions(board, position);
return position;
}

private <T> T doLoop(Supplier<T> inputFunction) {
while (true) {
try {
return inputFunction.get();
} catch (IllegalArgumentException e) {
OutputView.printErrorMessage(e.getMessage());
}
}
}
Comment on lines +83 to +91
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

반볡 μž…λ ₯을 μΆ”μΆœν•˜λ €λŠ” μ‹œλ„ μžμ²΄λŠ” μ’‹μŠ΅λ‹ˆλ‹€.

λ‹€λ§Œ ν˜ΈμΆœλΆ€κ°€ 두 곳인데 λ‘˜ λ‹€ Position을 λ°˜ν™˜ν•΄μ„œ <T> μ œλ„€λ¦­μ΄ μ‹€μ§ˆμ μœΌλ‘œ ν•˜λŠ” 일이 μ—†κ³ ,
μ•ˆμ—μ„œ OutputView.printErrorMessage()λ₯Ό 직접 ν˜ΈμΆœν•˜κ³  IllegalArgumentException만 작고 μžˆμ–΄μ„œ
λ‹€λ₯Έ λ§₯λ½μ—μ„œ μž¬μ‚¬μš©ν•˜κΈ°λ„ μ–΄λ €μ›Œμš”.

이 정도 규λͺ¨μ—μ„œλŠ” 였히렀 ν’€μ–΄ μ“°λŠ” 게 읽기 μ’‹μ§€ μ•Šμ„κΉŒμš”?

private Position askMovePiecePositionUntilValid(Board board) {
    while (true) {
        try {
            outputView.printMoveInfo();
            Position position = inputView.readPosition();
            routeChecker.findAvailablePositions(board, position);
            return position;
        } catch (IllegalArgumentException e) {
            OutputView.printErrorMessage(e.getMessage());
        }
    }
}

이러면 λ©”μ„œλ“œ 이름이 "뭘 ν•˜λŠ”μ§€"λ₯Ό 말해주고,
doLoop의 μ •μ˜λ₯Ό μ°Ύμ•„κ°€μ§€ μ•Šμ•„λ„ λ°”λ‘œ 이해할 수 μžˆμ–΄μš”.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

더 λ‚˜μ•„κ°€ while (true) 문도 λͺ…μ‹œμ μΈ flag λ₯Ό λ‘λŠ” λ°©μ‹μœΌλ‘œ λ°”κΎΈλ©΄ μ–΄λ–¨κΉŒ ν•΄μš”.
while (true) λŠ” 정말 μœ„ν—˜ν•œ λ‘œμ§μ΄κ±°λ“ μš”.

μ§€κΈˆ λ‹Ήμž₯ 문제λ₯Ό μΌμœΌν‚€μ§€ μ•Šλ”λΌλ„
μœ μ§€λ³΄μˆ˜ ν•˜κ±°λ‚˜ κΈ°λŠ₯이 μΆ”κ°€λ˜λŠ” κ³Όμ •μ—μ„œ μ˜λ„μΉ˜ μ•Šκ²Œ 이 루프λ₯Ό λΉ μ Έλ‚˜κ°€μ§€ λͺ»ν•˜λŠ” λ¬Έμ œκ°€ 생길 κ°€λŠ₯성이 λ†’μ•„μš”.
그러면 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μžμ²΄κ°€ μ œλŒ€λ‘œ λ™μž‘ν•˜μ§€ μ•Šκ²Œ λ˜λŠ”κ±΄λ°μš”,

λͺ…μ‹œμ μΈ flagλ₯Ό λ„£λŠ”λ‹€κ³  κ·Έ λ¬Έμ œκ°€ μ™„μ „νžˆ ν•΄κ²°λ˜μ§€λŠ” μ•Šμ§€λ§Œ
적어도 μ•ˆμ „μž₯치 ν•˜λ‚˜λŠ” λ„£μ–΄μ€€λ‹€κ³  보면 쒋을 것 κ°™λ„€μš”.
그리 어렡지도 μ•ŠμœΌλ‹ˆ ν•œ 번 λ„μ „ν•΄λ΄…μ‹œλ‹€!

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

import janggi.domain.common.Position;
import janggi.domain.piece.Piece;
import java.util.HashMap;
import java.util.Map;

public class Board {

private final Map<Position, Piece> board = new HashMap<>();

public void place(Position position, Piece piece) {
board.put(position, piece);
}

public Map<Position, Piece> getBoard() {
return board;
}

public void movePiece(Position movePiecePosition, Position destination) {
Piece piece = board.get(movePiecePosition);
board.remove(movePiecePosition);
board.put(destination, piece);
}
Comment on lines +20 to +24
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μΆ”κ°€λ‘œ, movePiece()μ—μ„œ board.get(movePiecePosition)이 null을 λ°˜ν™˜ν•˜λŠ” κ²½μš°λ„ 생각해보면 μ’‹κ² μ–΄μš”.
빈 μœ„μΉ˜λ₯Ό μ΄λ™ν•˜λ €κ³  ν•˜λ©΄ null이 destination에 μ €μž₯λ˜κ±°λ“ μš”.


public Piece pieceAt(Position position) {
return board.get(position);
}

public boolean hasPiece(Position position) {
return board.containsKey(position);
}
}
54 changes: 54 additions & 0 deletions src/main/java/janggi/domain/board/BoardFormation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package janggi.domain.board;

import java.util.List;

public enum BoardFormation {
MA_SANG_MA_SANG(1, "λ§ˆμƒλ§ˆμƒ", List.of(2, 7), List.of(3, 8)),
MA_SANG_SANG_MA(2, "λ§ˆμƒμƒλ§ˆ", List.of(2, 8), List.of(3, 7)),
SANG_MA_SANG_MA(3, "μƒλ§ˆμƒλ§ˆ", List.of(3, 8), List.of(2, 7)),
SANG_MA_MA_SANG(4, "μƒλ§ˆλ§ˆμƒ", List.of(3, 7), List.of(2, 8));

private final int choice;
private final String name;
private final List<Integer> maXPositions;
private final List<Integer> sangXPositions;

BoardFormation(int choice, String name, List<Integer> maXPositions, List<Integer> sangXPositions) {
this.choice = choice;
this.name = name;
this.maXPositions = maXPositions;
this.sangXPositions = sangXPositions;
}

public static BoardFormation selectByChoice(int choice) {
if (choice == 1) {
return MA_SANG_MA_SANG;
}
if (choice == 2) {
return MA_SANG_SANG_MA;
}
if (choice == 3) {
return SANG_MA_SANG_MA;
}
if (choice == 4) {
return SANG_MA_MA_SANG;
}
throw new IllegalArgumentException("[ERROR] 잘λͺ»λœ 번호λ₯Ό μž…λ ₯ν•˜μ…¨μŠ΅λ‹ˆλ‹€.");
}

public int getChoice() {
return choice;
}

public String getName() {
return name;
}

public List<Integer> getMaXPositions() {
return maXPositions;
}

public List<Integer> getSangXPositions() {
return sangXPositions;
}
}
73 changes: 73 additions & 0 deletions src/main/java/janggi/domain/board/BoardInitiator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package janggi.domain.board;

import janggi.domain.common.Position;
import janggi.domain.common.Team;
import janggi.domain.piece.Piece;
import janggi.domain.piece.PieceType;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BoardInitiator {

private static final int MAX_Y = 11;

private final Map<PieceType, List<Integer>> defaultXPositions = Map.of(
PieceType.KING, List.of(5),
PieceType.SA, List.of(4, 6),
PieceType.CHA, List.of(1, 9),
PieceType.PO, List.of(2, 8),
PieceType.ZOL, List.of(1, 3, 5, 7, 9)
);

private final Map<PieceType, Integer> defaultYPosition = Map.of(
PieceType.KING, 9,
PieceType.SA, 10,
PieceType.SANG, 10,
PieceType.MA, 10,
PieceType.CHA, 10,
PieceType.PO, 8,
PieceType.ZOL, 7
);

public void initializeByFormation(Board board, BoardFormation formation, Team team) {
Map<PieceType, List<Integer>> xPositions = initXPositionsByFormation(formation);
placeByPieceType(board, xPositions, team);
}

private Map<PieceType, List<Integer>> initXPositionsByFormation(BoardFormation formation) {
Map<PieceType, List<Integer>> result = new HashMap<>();
for (PieceType pieceType : PieceType.values()) {
if (pieceType == PieceType.MA) {
result.put(pieceType, formation.getMaXPositions());
continue;
}
if (pieceType == PieceType.SANG) {
result.put(pieceType, formation.getSangXPositions());
continue;
}
result.put(pieceType, defaultXPositions.get(pieceType));
}
return result;
}

private void placeByPieceType(Board board, Map<PieceType, List<Integer>> hanXPositions, Team team) {
for (PieceType pieceType : PieceType.values()) {
placeByPieceType(board, hanXPositions, team, pieceType);
}
}

private void placeByPieceType(Board board, Map<PieceType, List<Integer>> hanXPositions, Team team,
PieceType pieceType) {
for (Integer x : hanXPositions.get(pieceType)) {
if (team == Team.CHO) {
Position position = new Position(x, defaultYPosition.get(pieceType));
board.place(position, new Piece(team, pieceType));
}
if (team == Team.HAN) {
Position position = new Position(x, MAX_Y - defaultYPosition.get(pieceType));
board.place(position, new Piece(team, pieceType));
}
Comment on lines +63 to +70
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

μ•žμ„œ λ§ν–ˆλ˜ team.isCho() λ₯Ό μ‘μš©ν•΄λ΄…μ‹œλ‹€.
ν˜„μž¬ 이 두 if 문듀은 y μ’Œν‘œλ₯Ό κ΅¬ν•˜λŠ” 것 μ™Έμ—λŠ” μ™„μ „νžˆ λ™μΌν•΄μš”.
κ·Έλ ‡λ‹€λ©΄ y μ’Œν‘œ κ΅¬ν•˜λŠ” κ±Έ team μ—κ²Œ λ§‘κ²¨μ„œ 이 쀑볡을 쀄여보면 μ–΄λ–¨κΉŒμš”? :

int y = team.calculateY(defaultYPosition.get(pieceType));

생각해보면 team 에 따라 y μ’Œν‘œ κ΅¬ν•˜λŠ” 둜직이 λ‹¬λΌμ§€λŠ”κ±΄ λ‹Ήμ—°ν•˜μž–μ•„μš”.
κ·ΈλŸ¬λ‹ˆ team 이 κ·Έ 역할을 담당해도 될 것 같은데 이산은 μ–΄λ–»κ²Œ μƒκ°ν•˜μ„Έμš”?

심지어 이산이 λΉ„μŠ·ν•œ μ‹œλ„λ₯Ό ν–ˆλ˜ 흔적이 μžˆλ”λΌκ³ μš” : 2111fbf 😁

}
}
}
Comment on lines +72 to +73
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

파일 끝에 빈 쀄(trailing newline)이 μ—†μ–΄μš”.

POSIX ν‘œμ€€μ—μ„œλŠ” ν…μŠ€νŠΈ 파일이 κ°œν–‰ 문자둜 λλ‚˜μ•Ό ν•˜κ³ , Git diffμ—μ„œ \\ No newline at end of file κ²½κ³ κ°€ λœ¨λ©΄μ„œ diffκ°€ μ§€μ €λΆ„ν•΄μ Έμš”.

IntelliJ μ„€μ •μ—μ„œ Editor β†’ General β†’ Ensure every saved file ends with a line breakλ₯Ό μΌœλ‘λ©΄ μžλ™μœΌλ‘œ μ²˜λ¦¬λΌμš” πŸ‘

26 changes: 26 additions & 0 deletions src/main/java/janggi/domain/common/Direction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package janggi.domain.common;

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

public enum Direction {
UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0),
UP_LEFT(-1, -1), UP_RIGHT(1, -1), DOWN_LEFT(-1, 1), DOWN_RIGHT(1, 1);

private final int x;
private final int y;

Direction(int x, int y) {
this.x = x;
this.y = y;
}

public Optional<Position> nextPosition(Position position) {
return position.applyDirection(x, y);
}

public void nextContinuousPosition(Position position, Map<Position, List<Position>> continuousRoute) {
position.applyContinuousDirection(x, y, continuousRoute);
}
}
Loading