Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
2c15f8e
docs: README ๊ธฐ๋Šฅ ๋ช…์„ธ
yejinkimis Mar 25, 2026
38f7091
test: ์œ„์น˜ ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ์˜ˆ์™ธ ํ…Œ์ŠคํŠธ
yejinkimis Mar 26, 2026
eec72c2
feat: ์œ„์น˜ ๊ฐ์ฒด ์ƒ์„ฑ
yejinkimis Mar 26, 2026
4eece5c
test: ๊ธฐ๋ฌผ ์ƒ์„ฑ ํ…Œ์ŠคํŠธ
yejinkimis Mar 26, 2026
8d1d684
test: ์ƒ์ฐจ๋ฆผ๋ณ„ ๊ธฐ๋ฌผ ๋ฐฐ์น˜ ํ…Œ์ŠคํŠธ
yejinkimis Mar 26, 2026
488805e
feat: ๊ฐ ๊ธฐ๋ฌผ ํด๋ž˜์Šค ๊ตฌํ˜„
yejinkimis Mar 26, 2026
74217a1
feat: ์ดˆ๋‚˜๋ผ/ํ•œ๋‚˜๋ผ ๊ตฌ๋ถ„ enum ์ƒ์„ฑ
yejinkimis Mar 26, 2026
1966e66
feat: ๊ธฐ๋ฌผ๋ณ„ ์ดˆ๊ธฐ ์œ„์น˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง„ enum ์ƒ์„ฑ
yejinkimis Mar 26, 2026
9775ac1
feat: ์ƒ์ฐจ๋ฆผ๋ณ„ ์ƒ/๋งˆ ์œ„์น˜ ์ •๋ณด๋ฅผ ๊ฐ€์ง„ enum ์ƒ์„ฑ
yejinkimis Mar 26, 2026
9832ec2
feat: ์ƒ์ฐจ๋ฆผ ์ „๋žต์— ๋”ฐ๋ฅธ ํฌ์ง€์…˜ ๋ฐ ๊ธฐ๋ฌผ ์ƒ์„ฑ
yejinkimis Mar 26, 2026
af8fa6c
docs: README ์—…๋ฐ์ดํŠธ
yejinkimis Mar 26, 2026
e7d1eaf
docs: README ์—…๋ฐ์ดํŠธ
yejinkimis Mar 26, 2026
f3b5bea
test(Board): ๋ณด๋“œ ๋‚ด ๊ธฐ๋ฌผ ์ด๋™ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
yejinkimis Mar 27, 2026
4677afa
feat: ๋ณด๋“œ ๋‚ด ๊ธฐ๋ฌผ ์ด๋™ ๊ตฌํ˜„
yejinkimis Mar 27, 2026
0de8449
refactor: ์ขŒํ‘œ ๊ธฐ์ค€ ๋ณ€๊ฒฝ
yejinkimis Mar 29, 2026
627b906
test: ๊ธฐ๋ฌผ ์ด๋™ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
yejinkimis Mar 29, 2026
79e6716
feat: ๊ธฐ๋ฌผ๋ณ„ ์ด๋™ ๊ตฌํ˜„
yejinkimis Mar 29, 2026
e3b8c05
docs: README ์—…๋ฐ์ดํŠธ
yejinkimis Mar 29, 2026
abe756a
feat: ๊ฐ ๊ธฐ๋ฌผ ํด๋ž˜์Šค์— ๊ธฐ๋ฌผ ํƒ€์ž… ๊ตฌ๋ถ„์„ ์œ„ํ•œ PieceType ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ ์ถ”๊ฐ€
yejinkimis Mar 30, 2026
b08d536
feat: ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’ ๋„๋ฉ”์ธ ์ „๋‹ฌ Dto ๊ตฌํ˜„
yejinkimis Mar 30, 2026
c7c986c
feat: ์ƒ์ฐจ๋ฆผ ํƒ€์ž… ๋ฒˆํ˜ธ ๊ตฌํ˜„
yejinkimis Mar 30, 2026
8d5d4e8
feat: Camp enum ํ•œ๊ธ€ ์ด๋ฆ„ ๋งคํ•‘
yejinkimis Mar 30, 2026
976e2f4
feat: ์‚ฌ์šฉ์ž ์ž…์ถœ๋ ฅ ๋ฐ ํ”Œ๋ ˆ์ด ๊ตฌํ˜„
yejinkimis Mar 30, 2026
0b63577
docs: README ์—…๋ฐ์ดํŠธ
yejinkimis Mar 30, 2026
2592641
feat: ๊ธฐ๋ฌผ ์ด๋™ ๋ถˆ๊ฐ€๋Šฅ ์‹œ ์žฌ์ž…๋ ฅ
yejinkimis Mar 30, 2026
2351f64
refactor: ๋ณด๋“œ ํฌ๊ธฐ ๋งค์ง๋„˜๋ฒ„ ์‚ฌ์šฉ
yejinkimis Mar 30, 2026
a629d79
refactor: Camp ์ด๋ฆ„ ๋ฐ ์ขŒํ‘œ ์—๋Ÿฌ ์ถœ๋ ฅ ์ˆ˜์ •
yejinkimis Mar 30, 2026
b751742
refactor: ์ ‘๊ทผ ์ œ์–ด์ž ๋ฐ final ์ถ”๊ฐ€
Eian1106 Mar 31, 2026
e025d9c
refactor: Camp Enum NONE ์ถ”๊ฐ€
Eian1106 Mar 31, 2026
3a57a25
refactor: Piece ์ถ”์ƒ ํด๋ž˜์Šค๋กœ ๋ณ€๊ฒฝ
Eian1106 Mar 31, 2026
ab2a4e5
refactor: ํƒ€์ž… ๋น„๊ต. getClass๊ฐ€ ์•„๋‹Œ PieceType์„ ๋น„๊ตํ•˜๋„๋ก ๋ณ€๊ฒฝ
Eian1106 Mar 31, 2026
f1674ee
refactor: Piece ์ถ”์ƒํด๋ž˜์Šค ๋ณ€๊ฒฝ์œผ๋กœ ์ธํ•œ test ๊ธฐ๋ฌผ ์ˆ˜์ •
Eian1106 Mar 31, 2026
a32db10
refactor: ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด PieceType์„ ๋ฐ›๋„๋ก ๋ณ€๊ฒฝ
Eian1106 Mar 31, 2026
23aa42e
refactor(Position): ์ž…๋ ฅ๊ฐ’๋„ ์ถœ๋ ฅํ•˜๋„๋ก ์˜ค๋ฅ˜๋ฉ”์‹œ์ง€ ๊ตฌ์ฒดํ™”
Eian1106 Mar 31, 2026
6c0ec71
refactor: rename PieceLocation to InitialPieceLocation
Eian1106 Apr 1, 2026
6ca82a3
refactor: PieceGenerator static์œผ๋กœ ๋ณ€๊ฒฝ
Eian1106 Apr 2, 2026
b83bc3f
refactor: view์—์„œ ElephantFormation ์ˆœ์„œ ์ถœ๋ ฅํ•˜๋„๋ก ๋ณ€๊ฒฝ
Eian1106 Apr 2, 2026
0d27ef0
refactor: rename ExistBoard to BoardReader
Eian1106 Apr 2, 2026
07fcc4b
feat(Route): ๋ฐฉํ–ฅ์— ๋”ฐ๋ผ position ๊ณ„์‚ฐํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋Š” route ๊ตฌํ˜„
Eian1106 Apr 3, 2026
457dcc4
refactor: ๊ฐ ๊ธฐ๋ฌผ๋“ค canMove ๋‚ด๋ถ€๊ตฌํ˜„ ๋ณ€๊ฒฝ
Eian1106 Apr 3, 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
81 changes: 81 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,84 @@
# java-janggi

์žฅ๊ธฐ ๋ฏธ์…˜ ์ €์žฅ์†Œ

**์ฃผ์š” ๊ธฐ๋Šฅ**

- [x] ํ”Œ๋ ˆ์ด์–ด๋Š” โ€˜์ƒ ์ฐจ๋ฆผโ€™์„ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
- [x] ๊ธฐ๋ฌผ์€ ์ž๋™์œผ๋กœ ๋ฐฐ์น˜๋œ๋‹ค.
- [x] ํ˜„์žฌ ์žฅ๊ธฐํŒ์˜ ํ˜„ํ™ฉ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
- [x] ์ดˆ๋‚˜๋ผ(์„ )/ํ•œ๋‚˜๋ผ(ํ›„) ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ํ”Œ๋ ˆ์ดํ•œ๋‹ค.
- [x] ํ”Œ๋ ˆ์ด์–ด๋Š” ๊ธฐ๋ฌผ์˜ ์ด๋™ ๊ทœ์น™์— ๋”ฐ๋ผ ์ด๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
- [x] ์ƒ๋Œ€ ํ”Œ๋ ˆ์ด์–ด์˜ ๊ธฐ๋ฌผ์„ ์žก์„ ์ˆ˜ ์žˆ๋‹ค.
- [ ] ์ƒ๋Œ€ ํ”Œ๋ ˆ์ด์–ด์˜ ์™•์„ ์žก์œผ๋ฉด ์Šน๋ฆฌํ•˜๊ณ , ๊ฒŒ์ž„์€ ์ข…๋ฃŒ๋œ๋‹ค.

### **์‹คํ–‰ ์˜ˆ์‹œ**

```
์ดˆ๋‚˜๋ผ ์ƒ ์ฐจ๋ฆผ์„ ๊ฒฐ์ •ํ•ด์ฃผ์„ธ์š”.
1. [๋งˆ ์ƒ ๋งˆ ์ƒ]
2. [๋งˆ ์ƒ ์ƒ ๋งˆ]
3. [์ƒ ๋งˆ ์ƒ ๋งˆ]
4. [์ƒ ๋งˆ ๋งˆ ์ƒ]

2

ํ•œ๋‚˜๋ผ ์ƒ ์ฐจ๋ฆผ์„ ๊ฒฐ์ •ํ•ด์ฃผ์„ธ์š”.
1. [๋งˆ ์ƒ ๋งˆ ์ƒ]
2. [๋งˆ ์ƒ ์ƒ ๋งˆ]
3. [์ƒ ๋งˆ ์ƒ ๋งˆ]
4. [์ƒ ๋งˆ ๋งˆ ์ƒ]

3

๊ธฐ๋ฌผ์ด ๋ฐฐ์น˜ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
0 1 2 3 4 5 6 7 8
0 ่ปŠ ้ฆฌ ่ฑก ๅฃซ ยท ๅฃซ ้ฆฌ ่ฑก ่ปŠ
1 ยท ยท ยท ยท ๆผข ยท ยท ยท ยท
2 ยท ็ ฒ ยท ยท ยท ยท ยท ็ ฒ ยท
3 ๅ…ต ยท ๅ…ต ยท ๅ…ต ยท ๅ…ต ยท ๅ…ต
4 ยท ยท ยท ยท ยท ยท ยท ยท ยท
5 ยท ยท ยท ยท ยท ยท ยท ยท ยท
6 ๅ’ ยท ๅ’ ยท ๅ’ ยท ๅ’ ยท ๅ’
7 ยท ็‚ฎ ยท ยท ยท ยท ยท ็‚ฎ ยท
8 ยท ยท ยท ยท ๆฅš ยท ยท ยท ยท
9 ่ปŠ ้ฆฌ ็›ธ ๅฃซ ยท ๅฃซ ็›ธ ้ฆฌ ่ปŠ

์ดˆ๋‚˜๋ผ ํ”Œ๋ ˆ์ด์–ด๋Š” ๋ง์„ ์„ ํƒํ•ด์ฃผ์„ธ์š”.(์ž…๋ ฅ์˜ˆ์‹œ ์ขŒํ‘œ: 0, 9)
์ขŒํ‘œ: 0, 9

์ดˆ๋‚˜๋ผ ํ”Œ๋ ˆ์ด์–ด๋Š” ์„ ํƒํ•œ ๋ง์„ ์›€์ง์ผ ์œ„์น˜๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์„ธ์š”.(์ž…๋ ฅ์˜ˆ์‹œ ์ขŒํ‘œ: 0, 7)
์ขŒํ‘œ: 0, 7

์ด๋™๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
0 1 2 3 4 5 6 7 8
0 ่ปŠ ้ฆฌ ่ฑก ๅฃซ ยท ๅฃซ ้ฆฌ ่ฑก ่ปŠ
1 ยท ยท ยท ยท ๆผข ยท ยท ยท ยท
2 ยท ็ ฒ ยท ยท ยท ยท ยท ็ ฒ ยท
3 ๅ…ต ยท ๅ…ต ยท ๅ…ต ยท ๅ…ต ยท ๅ…ต
4 ยท ยท ยท ยท ยท ยท ยท ยท ยท
5 ยท ยท ยท ยท ยท ยท ยท ยท ยท
6 ๅ’ ยท ๅ’ ยท ๅ’ ยท ๅ’ ยท ๅ’
7 ่ปŠ ็‚ฎ ยท ยท ยท ยท ยท ็‚ฎ ยท
8 ยท ยท ยท ยท ๆฅš ยท ยท ยท ยท
9 ยท ้ฆฌ ็›ธ ๅฃซ ยท ๅฃซ ็›ธ ้ฆฌ ่ปŠ
```

**์ž…๋ ฅ**

- [x] โ€˜์ƒ ์ฐจ๋ฆผโ€™ ๋ฐฐ์น˜ ํƒ€์ž… ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
- [x] ์„ ํƒํ•  ๊ธฐ๋ฌผ์˜ ์ขŒํ‘œ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
- [x] `[ERROR]` ํ•ด๋‹น ์ขŒํ‘œ์— ๊ธฐ๋ฌผ์ด ์—†์„ ๋•Œ
- [x] `[ERROR]` ์„ ํƒํ•œ ๊ธฐ๋ฌผ์ด ํ”Œ๋ ˆ์ด์–ด์˜ ๊ธฐ๋ฌผ์ด ์•„๋‹ ๋•Œ
- [x] ์ด๋™ํ•  ์ขŒํ‘œ๋ฅผ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค.
- [x] `[ERROR]` ์ด๋™ํ•  ์ขŒํ‘œ๊ฐ€ ๋ณด๋“œ ํฌ๊ธฐ ๋‚ด์— ์œ ํšจํ•˜์ง€ ์•Š์„ ๋•Œ
- [x] `[ERROR]` ํ•ด๋‹น ์ขŒํ‘œ์— ํ”Œ๋ ˆ์ด์–ด์˜ ํŒ€ ๊ธฐ๋ฌผ์ด ์žˆ์„ ๋•Œ
- [x] `[ERROR]` ์ด๋™ ๊ทœ์น™์— ๋”ฐ๋ผ ์ด๋™ํ•  ์ˆ˜ ์—†์„ ๋•Œ

**์ถœ๋ ฅ**

- [x] 4 ์ข…๋ฅ˜์˜ โ€˜์ƒ ์ฐจ๋ฆผโ€™ ๋ฐฐ์น˜๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
- [x] ๊ธฐ๋ฌผ์ด ๋ฐฐ์น˜๋œ ๋ณด๋“œ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
- [x] ํ˜„์žฌ ํ„ด์„ ์ถœ๋ ฅํ•œ๋‹ค.
- [x] ํ„ด์ด ๋๋‚˜๊ณ  ๊ธฐ๋ฌผ ์ด๋™์ด ๋œ ๋ณด๋“œ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
- [ ] ์ตœ์ข… ์ŠนํŒจ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.
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 view.InputView;
import view.OutputView;

public class Application {

public static void main(String[] args) {
InputView inputView = new InputView();
OutputView outputView = new OutputView();

JanggiController janggiController = new JanggiController(inputView, outputView);
janggiController.run();
}
}
80 changes: 80 additions & 0 deletions src/main/java/JanggiController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import domain.Board;
import domain.Camp;
import domain.ElephantFormation;
import domain.Position;
import dto.BoardStatusDto;
import view.InputView;
import view.OutputView;

public class JanggiController {

private final InputView inputView;
private final OutputView outputView;


JanggiController(InputView inputView, OutputView outputView) {
this.inputView = inputView;
this.outputView = outputView;
}

public void run() {
Board board = generateBoard();
printBoard(board);

playJanggi(board);
}

private Board generateBoard() {
Board board = new Board();
int choElephantFormation = inputView.askElephantFormation(Camp.CHO);
int hanElephantFormation = inputView.askElephantFormation(Camp.HAN);
board.generatePiecesBy(Camp.CHO, mappingElephantFormation(choElephantFormation));
board.generatePiecesBy(Camp.HAN, mappingElephantFormation(hanElephantFormation));
return board;
}

private void playJanggi(Board board) {
Camp camp = Camp.CHO;
while (true) {
try{
Position fromPosition = askFromPosition(camp, board);
Position toPosition = inputView.askToPosition(camp);
board.move(fromPosition, toPosition);
} catch (IllegalArgumentException e) {
outputView.printErrorMessage(e);
continue;
}
printBoard(board);
camp = turnCamp(camp);

//Todo: ์‚ฌ์ดํด2 ์™•์ด ์žกํžˆ๋ฉด, ๊ฒŒ์ž„์ด ์ข…๋ฃŒ
}
}

private Camp turnCamp(Camp camp) {
if (camp.equals(Camp.CHO)) {
return Camp.HAN;
}
return Camp.CHO;
}

private Position askFromPosition(Camp camp, Board board) {
while (true) {
Position fromPosition = inputView.askFromPosition(camp);
if (!board.isPieceOfCamp(fromPosition, camp)) {
outputView.printWrongChoice();
continue;
}
return fromPosition;
}
}

private void printBoard(Board board) {
BoardStatusDto boardStatus = board.getBoardStatus();
outputView.printBoardStatus(boardStatus);
}

private ElephantFormation mappingElephantFormation(int userInput) {
return ElephantFormation.getFormationType(userInput);
}
}
101 changes: 101 additions & 0 deletions src/main/java/domain/Board.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package domain;

import domain.pieces.Piece;
import dto.BoardStatusDto;
import dto.PositionStatusDto;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Board implements BoardReader {

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

public void generatePiecesBy(Camp camp, ElephantFormation elephantFormation) {
Map<Position, Piece> pieces = PieceGenerator.generatePieces(camp, elephantFormation);

board.putAll(pieces);
}

public void locatePiece(Position position, Piece piece) {
if (!isExist(position)) {
board.put(position, piece);
return;
}

if (getPieceFrom(position).isSameCamp(piece)) {
throw new IllegalArgumentException("[ERROR] ๊ฐ™์€ ํŒ€์€ ์žก์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค!");
}

board.put(position, piece);
}

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

@Override
public boolean isExist(Position position) {
return board.containsKey(position);
}

public void move(Position fromPosition, Position toPosition) {
if (fromPosition.equals(toPosition)) {
throw new IllegalArgumentException("[ERROR] ์ œ์ž๋ฆฌ ์ด๋™์€ ๋ถˆ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.");
}

Piece piece = board.get(fromPosition);
boolean canMove = piece.canMove(fromPosition, toPosition, this);
if (canMove) {
locatePiece(toPosition, piece);
board.remove(fromPosition);
return;
}

throw new IllegalArgumentException("[ERROR] ์ด๋™ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค");
}

@Override
public boolean isDifferentPieceType(Position position, Piece piece) {
if (!board.containsKey(position)) {
return true;
}

return board.get(position).isDifferentPieceType(piece);
}

public BoardStatusDto getBoardStatus() {
List<List<PositionStatusDto>> boardStatusDto = new ArrayList<>();
for (int y = Position.MIN_Y_VALUE; y <= Position.MAX_Y_VALUE; y++) {
List<PositionStatusDto> xPositionStatus = new ArrayList<>();
for (int x = Position.MIN_X_VALUE; x <= Position.MAX_X_VALUE; x++) {
Position position = new Position(x, y);

PositionStatusDto positionStatusDto = getPositionStatusDto(position);
xPositionStatus.add(positionStatusDto);
}
boardStatusDto.add(xPositionStatus);
}
return new BoardStatusDto(boardStatusDto);
}

private PositionStatusDto getPositionStatusDto(Position position) {
if (!board.containsKey(position)) {
return new PositionStatusDto(position, PieceType.NONE, Camp.NONE);
}

Piece piece = board.get(position);
PieceType pieceType = piece.getPieceType();
Camp camp = piece.getCamp();
return new PositionStatusDto(position, pieceType, camp);
}

public boolean isPieceOfCamp(Position position, Camp camp) {
if (!board.containsKey(position)) {
return false;
}

return board.get(position).isSameCamp(camp);
}
}
10 changes: 10 additions & 0 deletions src/main/java/domain/BoardReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package domain;

import domain.pieces.Piece;

public interface BoardReader {

boolean isExist(Position position);

boolean isDifferentPieceType(Position position, Piece piece);
}
18 changes: 18 additions & 0 deletions src/main/java/domain/Camp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package domain;

public enum Camp {
HAN("ํ•œ๋‚˜๋ผ"),
CHO("์ดˆ๋‚˜๋ผ"),
NONE("์ค‘๋ฆฝ");

private final String campName;

Camp(String campName) {
this.campName = campName;
}

public String getCampName() {
return campName;
}
}

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

public enum Direction {
NORTH(0, -1),
NORTHEAST(1, -1),
EAST(1, 0),
SOUTHEAST(1, 1),
SOUTH(0,1),
SOUTHWEST(-1, 1),
WEST(-1, 0),
NORTHWEST(-1, -1);

private final int x;
private final int y;

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

public int getDx() {
return x;
}

public int getDy() {
return y;
}
}
Loading