Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8d0791d
docs(Readme): 1์ฐจ ๊ธฐ๋Šฅ๋ช…์„ธ์„œ ์ž‘์„ฑ
sangjun121 Mar 24, 2026
0e90099
feat: ๋ณด๋“œ ์ƒ๋งˆ์ƒ๋งˆ ์ƒ์ฐจ๋ฆผ ๋ฐฐ์น˜ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ฐ ๊ตฌํ˜„
sangjun121 Mar 26, 2026
d6b6956
feat: ์ƒ๊ณผ ๋งˆ์˜ ์ƒ์ฐจ๋ฆผ ๋ชจ๋“  ์ผ€์ด์Šค ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ฐ ๊ตฌํ˜„
sangjun121 Mar 26, 2026
4195106
test(test): ์ „์ฒด ๊ธฐ๋ณธ ๊ธฐ๋ฌผ ๋ฐฐ์น˜ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
sangjun121 Mar 26, 2026
791f048
feat: ์ „์ง„ ๋ฐฉํ–ฅ์ด ๋นˆ ๊ฒฝ์šฐ, ์กธ ์ด๋™ ๊ทœ์น™ ๊ตฌํ˜„
sangjun121 Mar 27, 2026
2fd153b
feat: ์กธ ์ด๋™ ๋ชฉ์ ์ง€์— ๊ฐ™์€ ํŒ€์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ด๋™ ๊ทœ์น™ ๊ตฌํ˜„
sangjun121 Mar 27, 2026
1470386
feat: ์กธ ์ง„ํ–‰ ๋ฐฉํ–ฅ ๋ฐ ๊ฑฐ๋ฆฌ๊ฐ€, ์‹ค์ œ ๊ธฐ๋ฌผ์˜ ์ด๋™๊ทœ์น™๊ณผ ๋™์ผํ•œ์ง€ ํŒ๋‹จ ๋กœ์ง ๊ตฌํ˜„
sangjun121 Mar 27, 2026
c6ff662
chore: ๊ธฐ๋ฌผ ์ด๋™์‹œ ๋ฒ”์œ„ ์ฒดํฌ์— ๋Œ€ํ•œ ์Šค์ผˆ๋ ˆํ†ค ์ฝ”๋“œ ์„  ์ž‘์„ฑ
sangjun121 Mar 27, 2026
63b8f8a
chore: ์ฃผ์„์ œ๊ฑฐ
sangjun121 Mar 27, 2026
0c2947b
feat: ํฌ ๊ธฐ๋ฌผ ์ด๋™ ๊ทœ์น™ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ ๋ฐ ๊ตฌํ˜„
sangjun121 Mar 27, 2026
59fe958
feat: ์ฐจ ์ด๋™ ๊ทœ์น™ ํ…Œ์ŠคํŠธ ๋ฐ ๊ตฌํ˜„
sangjun121 Mar 27, 2026
40d3adc
๊ถ ์ด๋™ ๊ทœ์น™ ํ…Œ์ŠคํŠธ ๋ฐ ๊ตฌํ˜„
sangjun121 Mar 27, 2026
f4a0e68
feat: ์‚ฌ ์ด๋™ ๊ทœ์น™ ํ…Œ์ŠคํŠธ ๋ฐ ๊ตฌํ˜„
sangjun121 Mar 27, 2026
8ec818e
feat: ๋งˆ, ์ƒ ์ด๋™ ๊ทœ์น™ ๊ตฌํ˜„ ๋ฐ ํ…Œ์ŠคํŠธ
sangjun121 Mar 27, 2026
5bd7a9f
feat: ๋ณด๋“œํŒ์˜ ์ด๋™ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„ ๋ฐ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ
sangjun121 Mar 27, 2026
4690900
feat: ์ƒ๋งˆ์ƒ๋งˆ ์ƒ์ฐจ๋ฆผ ์ž…๋ ฅ ๋ ˆ์ด์–ด ๊ตฌํ˜„
sangjun121 Mar 29, 2026
1b5420d
feat: ํ˜„์žฌ ๋ณด๋“œ ์ƒํƒœ ์ถœ๋ ฅ ๋ฉ”์„œ๋“œ ๊ตฌํ˜„
sangjun121 Mar 29, 2026
aa34334
feat: ๊ธฐ๋ฌผ ์‹ค์ œ ์ด๋™ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฐ ํ˜„ํ™ฉ ์žฅ๊ธฐํŒ ์ถœ๋ ฅ ๊ตฌํ˜„
sangjun121 Mar 29, 2026
bcfea14
feat: ๊ธฐ๋ฌผ ์ด๋™ ๋ฐ˜๋ณต ๊ตฌํ˜„ ๋ฐ ์˜ˆ์™ธ ๋ฐœ์ƒ ์ฒ˜๋ฆฌ
sangjun121 Mar 30, 2026
6cd4382
refactor: ์ƒ๋งˆ์ƒ๋งˆ ์ƒ์ฐจ๋ฆผ ์ž…๋ ฅ์— ๋Œ€ํ•œ ์ค‘๋ณต ์ฝ”๋“œ ์ œ๊ฑฐ
sangjun121 Mar 30, 2026
274e082
feat: ์ƒ๋งˆ์ƒ๋งˆ ์ƒ์ฐจ๋ฆผ ๊ฒ€์ฆ๋กœ์ง ์ถ”๊ฐ€
sangjun121 Mar 30, 2026
996c162
feat: ์ด๋™ ์œ„์น˜ ๋ฐ ๊ธฐ๋ฌผ ์ด๋ฆ„ ์ž…๋ ฅ์‹œ ๊ฒ€์ฆ ์ถ”๊ฐ€
sangjun121 Mar 30, 2026
6f6c12d
fix: ์ƒ๋งˆ์ƒ๋งˆ ์ƒ์ฐจ๋ฆผ ์˜ˆ์™ธ ๋ฐœ์ƒ์‹œ ๋ฐ˜๋ณต ์ž…๋ ฅ ๊ตฌํ˜„
sangjun121 Mar 30, 2026
e60395c
feat: ๊ถ์„ฑ ์ด๋™ ๊ทœ์น™ ์ถ”๊ฐ€
sangjun121 Apr 1, 2026
3fb7328
feat: ๊ฒŒ์ž„ ์ข…๋ฃŒ ๊ทœ์น™ ๊ตฌํ˜„
sangjun121 Apr 2, 2026
3ab27c3
refactor: Board ์ƒ์„ฑ์ธ์ž๋ฅผ ๊ฐ ํŒ€์˜ ์ „๋žต์„ ๋งคํ•‘ํ•œ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ˆ˜์ •
sangjun121 Apr 2, 2026
acb2ad5
Merge branch 'sangjun121' into step2
sangjun121 Apr 2, 2026
752f175
docs(README): ๊ฐ ๊ธฐ๋ฌผ์˜ ์ ์ˆ˜ ๊ทœ์น™ ์ž‘์„ฑ
sangjun121 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
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,20 @@
- ์ด๋™ ์œ„์น˜๋Š” โ€œ1,1โ€์™€ ๊ฐ™์ด ์ขŒํ‘œํ˜•ํƒœ์˜ ์ˆซ์ž๊ฐ’๋งŒ ์ž…๋ ฅ์œผ๋กœ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค. ์ขŒํ‘œ๋Š” ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.
- ์ถ”๊ฐ€์ ์œผ๋กœ โ€œํ•œ์ˆ˜์‰ผโ€์ด ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

## 2-3. ๊ธฐ๋ฌผ ์ ์ˆ˜ ๊ทœ์น™
- ํ˜„์žฌ ์žฅ๊ธฐํŒ์— ๋‚จ์•„์žˆ๋Š” ๊ธฐ๋ฌผ๋“ค์˜ ๊ฐ ์ ์ˆ˜๋ฅผ ํ•ฉ์‚ฐํ•˜์—ฌ, ํ˜„์žฌ ์ ์ˆ˜๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.
- ๊ฐ ๊ธฐ๋ฌผ์˜ ์ ์ˆ˜๋Š” ์ค‘์š”๋„ ์ˆœ์œผ๋กœ ๋†’์€ ๋ฐฐ์ ์„ ๊ฐ€์ง€๋ฉฐ, ๊ฐ ์ ์ˆ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

| ๊ธฐ๋ฌผ | ์ ์ˆ˜ |
|-----|----------------|
| ๊ถ | 0์ (์ ์ˆ˜ ๊ณ„์‚ฐ์—์„œ ๋ฐฐ์ œ) |
| ์ฐจ | 13์  |
| ํฌ | 7์  |
| ๋งˆ | 5์  |
| ์ƒ | 3์  |
| ์‚ฌ | 3์  |
| ์กธ(๋ณ‘) | 2์  |

# 3. ์šฉ์–ด ์‚ฌ์ „

### 3-1. ๊ธฐ๋ณธ ์šฉ์–ด
Expand Down
54 changes: 43 additions & 11 deletions src/main/java/controller/JanggiController.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@
import controller.dto.CurrentBoardStatus;
import controller.dto.MovedPieceRequest;
import domain.GameManager;
import domain.HorseElephantFormation;
import domain.Team;
import exception.GameExceptionHandler;
import exception.custom.GameException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import strategy.InitializeStrategy;

import view.InputView;
import view.OutputView;

Expand All @@ -26,8 +30,9 @@ public JanggiController(GameExceptionHandler gameExceptionHandler, InputView inp

public void start() {
Map<Team, String> horseElephantFormations = readHorseElephantFormation();
startJanggiGame(horseElephantFormations);
playJanggiGame();
initializeJanggiGame(horseElephantFormations);
Team winnerTeam = playJanggiGame();
printGameWinner(winnerTeam);
}

private Map<Team, String> readHorseElephantFormation() {
Expand All @@ -38,24 +43,40 @@ private Map<Team, String> readHorseElephantFormation() {
return horseElephantInputs;
}

private void startJanggiGame(Map<Team, String> horseElephantFormations) {
this.gameManager = new GameManager(horseElephantFormations);
/**
* 1. ์žฅ๊ธฐ ๊ฒŒ์ž„ ์ดˆ๊ธฐํ™”
*/
private void initializeJanggiGame(Map<Team, String> horseElephantFormations) {
this.gameManager = new GameManager(toInitializeStrategies(horseElephantFormations));
printCurrentBoardStatus();
}

private Map<Team, InitializeStrategy> toInitializeStrategies(Map<Team, String> horseElephantFormations) {
Map<Team, InitializeStrategy> initializeStrategies = new HashMap<>();
horseElephantFormations.forEach(
(team, formation) -> initializeStrategies.put(team, getBoardInitializeStrategy(formation))
);
return initializeStrategies;
}

private InitializeStrategy getBoardInitializeStrategy(String formationInput) {
return HorseElephantFormation.getStrategy(formationInput);
}

private void printCurrentBoardStatus() {
List<CurrentBoardStatus> statuses = gameManager.getCurrentBoardStatus();
outputView.printCurrentBoard(statuses);
}

private void playJanggiGame() {
/**
* TODO: 2์ฐจ ์‚ฌ์ดํด - ๊ฒŒ์ž„ ์ข…๋ฃŒ ์กฐ๊ฑด ์ถ”๊ฐ€ ์˜ˆ์ •
*/
while (true) {
playTurn(Team.CHO);
playTurn(Team.HAN);
private Team playJanggiGame() {
Team currentTeam = Team.CHO;

while (!gameManager.isGameFinished(currentTeam)) {
playTurn(currentTeam);
currentTeam = switchTeam(currentTeam);
}

return switchTeam(currentTeam);
}

private void playTurn(Team team) {
Expand All @@ -69,6 +90,17 @@ private void playTurn(Team team) {
}
}

private Team switchTeam(Team team) {
if (team == Team.CHO) {
return Team.HAN;
}
return Team.CHO;
}

private void printGameWinner(Team team) {
outputView.printGameWinner(team.getKoreanName());
}

private void movePiece(Team team) {
MovedPieceRequest movedPieceRequest = readMovedPiece();
gameManager.movePiece(movedPieceRequest, team);
Expand Down
36 changes: 33 additions & 3 deletions src/main/java/domain/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,21 @@ public class Board {
private static final int MAX_COLUMN = 9;
private static final int MIN_COLUMN = 1;

private static final int CHO_PALACE_MAX_ROW = 10;
private static final int CHO_PALACE_MIN_ROW = 8;
private static final int HAN_PALACE_MAX_ROW = 3;
private static final int HAN_PALACE_MIN_ROW = 1;
private static final int PALACE_MAX_COLUMN = 6;
private static final int PALACE_MIN_COLUMN = 4;

private static final Position CHO_PALACE_CENTER = Position.from(9, 5);
private static final Position HAN_PALACE_CENTER = Position.from(2, 5);

protected final Map<Position, Piece> pieces = new HashMap<>();

public Board(InitializeStrategy choInitializeStrategy, InitializeStrategy hanInitializeStrategy) {
initTeamBoard(choInitializeStrategy, Team.CHO);
initTeamBoard(hanInitializeStrategy, Team.HAN);
public Board(Map<Team, InitializeStrategy> initializeStrategies) {
initializeStrategies.forEach(((team, initializeStrategy) ->
initTeamBoard(initializeStrategy, team)));
}

public void move(Position from, Position to, PieceType pieceType, Team team) {
Expand Down Expand Up @@ -72,6 +82,26 @@ public List<CurrentBoardStatus> getCurrentStatus() {
return currentBoardStatuses;
}

public boolean isInPalace(Team team, Position target) {
if (Team.CHO == team) {
return target.isPossiblePosition(CHO_PALACE_MAX_ROW, CHO_PALACE_MIN_ROW, PALACE_MAX_COLUMN,
PALACE_MIN_COLUMN);
}
return target.isPossiblePosition(HAN_PALACE_MAX_ROW, HAN_PALACE_MIN_ROW, PALACE_MAX_COLUMN, PALACE_MIN_COLUMN);
}

public boolean isCenterPositionInPalace(Team team, Position target) {
if (Team.CHO == team) {
return CHO_PALACE_CENTER.isSamePosition(target);
}
return HAN_PALACE_CENTER.isSamePosition(target);
}

public boolean isExistPiece(PieceType target, Team team) {
return pieces.values().stream()
.anyMatch(piece -> piece.getType() == target && piece.getTeam() == team);
}

/**
* ํ—ฌํผ ๋ฉ”์„œ๋“œ
*/
Expand Down
14 changes: 4 additions & 10 deletions src/main/java/domain/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,8 @@
public class GameManager {
private final Board board;

public GameManager(Map<Team, String> formationInput) {
this.board = new Board(
getBoardInitializeStrategy(formationInput.get(Team.CHO)),
getBoardInitializeStrategy(formationInput.get(Team.HAN))
);
public GameManager(Map<Team, InitializeStrategy> initializeStrategies) {
this.board = new Board(initializeStrategies);
}

public List<CurrentBoardStatus> getCurrentBoardStatus() {
Expand All @@ -27,10 +24,7 @@ public void movePiece(MovedPieceRequest request, Team team) {
team);
}

/**
* ํ—ฌํผ ๋ฉ”์„œ๋“œ
*/
private InitializeStrategy getBoardInitializeStrategy(String formationInput) {
return HorseElephantFormation.getStrategy(formationInput);
public boolean isGameFinished(Team currentTeam) {
return !board.isExistPiece(PieceType.KING, currentTeam);
}
}
4 changes: 4 additions & 0 deletions src/main/java/domain/Position.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public boolean isSameRow(Position other) {
return false;
}

public boolean isSamePosition(Position other){
return other.row == row && other.column == column;
}

public boolean isPossiblePosition(int maxRow, int minRow, int maxColumn, int minColumn) {
if (this.row > maxRow || this.row < minRow) {
return false;
Expand Down
35 changes: 31 additions & 4 deletions src/main/java/domain/piece/Guard.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ public Guard(Team team) {

@Override
public boolean canMove(Position from, Position to, Board board) {
if (!isCorrectMoveDistanceAndDirection(from, to)) {
if (!isPossiblePosition(to, board)) {
return false;
}

if (!isCorrectMoveDistance(from, to)) {
return false;
}

if (!isCorrectDirection(from, to, board)) {
return false;
}

Expand All @@ -23,11 +31,30 @@ public boolean canMove(Position from, Position to, Board board) {
return !board.hasSameTeamOn(to, this);
}

private boolean isEmptySpace(Position to, Board board) {
return board.isEmpty(to);
private boolean isPossiblePosition(Position to, Board board) {
return board.isInPalace(this.team, to);
}

private boolean isCorrectMoveDistanceAndDirection(Position from, Position to) {
private boolean isCorrectMoveDistance(Position from, Position to) {
return Math.abs(from.columnDistanceTo(to)) == 1 || Math.abs(from.rowDistanceTo(to)) == 1;
}

private boolean isCorrectDirection(Position from, Position to, Board board) {
// 1. ์ถœ๋ฐœ์ง€๊ฐ€ ์ •์ค‘์•™์ธ ๊ฒฝ์šฐ, ๊ถ์„ฑ ๋‚ด ์–ด๋””๋“ ์ง€ ์ด๋™ ๊ฐ€๋Šฅ
if (board.isCenterPositionInPalace(team, from)) {
return true;
}

// 2. ์ถœ๋ฐœ์ง€๊ฐ€ ์ •์ค‘์•™์ด ์•„๋‹Œ ๊ฒฝ์šฐ, ์ค‘์•™์œผ๋กœ ์ด๋™ ๊ฐ€๋Šฅ
if (board.isCenterPositionInPalace(team, to)) {
return true;
}

// 3. ์ถœ๋ฐœ์ง€๊ฐ€ ์ •์ค‘์•™์ด ์•„๋‹Œ ๊ฒฝ์šฐ, ์ƒํ•˜์ขŒ์šฐ๋กœ ์ด๋™ ๊ฐ€๋Šฅ
return !(Math.abs(from.columnDistanceTo(to)) == 1 && Math.abs(from.rowDistanceTo(to)) == 1);
}

private boolean isEmptySpace(Position to, Board board) {
return board.isEmpty(to);
}
}
35 changes: 31 additions & 4 deletions src/main/java/domain/piece/King.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ public King(Team team) {

@Override
public boolean canMove(Position from, Position to, Board board) {
if (!isCorrectMoveDistanceAndDirection(from, to)) {
if (!isPossiblePosition(to, board)) {
return false;
}

if (!isCorrectMoveDistance(from, to)) {
return false;
}

if (!isCorrectDirection(from, to, board)) {
return false;
}

Expand All @@ -23,11 +31,30 @@ public boolean canMove(Position from, Position to, Board board) {
return !board.hasSameTeamOn(to, this);
}

private boolean isEmptySpace(Position to, Board board) {
return board.isEmpty(to);
private boolean isPossiblePosition(Position to, Board board) {
return board.isInPalace(this.team, to);
}

private boolean isCorrectMoveDistanceAndDirection(Position from, Position to) {
private boolean isCorrectMoveDistance(Position from, Position to) {
return Math.abs(from.columnDistanceTo(to)) == 1 || Math.abs(from.rowDistanceTo(to)) == 1;
}

private boolean isCorrectDirection(Position from, Position to, Board board) {
// 1. ์ถœ๋ฐœ์ง€๊ฐ€ ์ •์ค‘์•™์ธ ๊ฒฝ์šฐ, ๊ถ์„ฑ ๋‚ด ์–ด๋””๋“ ์ง€ ์ด๋™ ๊ฐ€๋Šฅ
if (board.isCenterPositionInPalace(team, from)) {
return true;
}

// 2. ์ถœ๋ฐœ์ง€๊ฐ€ ์ •์ค‘์•™์ด ์•„๋‹Œ ๊ฒฝ์šฐ, ์ค‘์•™์œผ๋กœ ์ด๋™ ๊ฐ€๋Šฅ
if (board.isCenterPositionInPalace(team, to)) {
return true;
}

// 3. ์ถœ๋ฐœ์ง€๊ฐ€ ์ •์ค‘์•™์ด ์•„๋‹Œ ๊ฒฝ์šฐ, ์ƒํ•˜์ขŒ์šฐ๋กœ ์ด๋™ ๊ฐ€๋Šฅ
return !(Math.abs(from.columnDistanceTo(to)) == 1 && Math.abs(from.rowDistanceTo(to)) == 1);
}

private boolean isEmptySpace(Position to, Board board) {
return board.isEmpty(to);
}
}
7 changes: 6 additions & 1 deletion src/main/java/view/OutputView.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import java.util.List;

public class OutputView {
private static final String GAME_WINNER_GUIDE = "์žฅ๊ธฐ ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์ž„์˜ ์šฐ์Šน์ž๋Š” %s๋‚˜๋ผ ์ž…๋‹ˆ๋‹ค.";

private static final int BOARD_ROW_SIZE = 10;
private static final int BOARD_COLUMN_SIZE = 9;
private static final String EMPTY_CELL = " ";
Expand All @@ -29,10 +31,13 @@ public void printErrorMessage(String message){
System.out.println(message);
}

public void printGameWinner(String winner) {
System.out.println(String.format(GAME_WINNER_GUIDE, winner));
}

/**
* ํ—ฌํผ ๋ฉ”์„œ๋“œ
*/

private String[][] createEmptyBoard() {
String[][] board = new String[BOARD_ROW_SIZE][BOARD_COLUMN_SIZE];

Expand Down
Loading