From d4bacf5b1f823a93087815c2ad7ea10bc70932f6 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Wed, 25 Mar 2026 13:53:56 +0900 Subject: [PATCH 01/30] =?UTF-8?q?feat(Position):=20Position=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 64 +++++++++++++++++++++++ src/main/java/janggi/domain/Position.java | 18 +++++++ 2 files changed, 82 insertions(+) create mode 100644 src/main/java/janggi/domain/Position.java diff --git a/README.md b/README.md index 9775dda0ae..f4b00a71d0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,67 @@ # java-janggi 장기 미션 저장소 + +version : 1.0 (초기 구조 설계) + +# 시나리오 + +1. 한나라 사용자가 상차림을 선택한다. +2. 초나라 사용자가 상차림을 선택한다. +3. 초나라 시작 + 1. 이동할 기물의 좌표를 입력한다. (무르기 : q) + + 현재 보드를 보여준다. + + ex) 졸을 선택했습니다. 졸은 현재 (1,1)에 있습니다. + + 2. 해당 기물이 이동할 수 있는 좌표를 보여준다. (기물 다시선택 : r) + - 만약에 아무데도 이동 불가능하면 다시 a로 돌아가서 선택하게 한다. + 3. 보여진 좌표 중 이동할 좌표를 입력한다. + - 이동할 좌표를 입력해주세요.(예시: 3, 5) + 4. 해당 좌표로 이동한다. +4. 한나라 시작 + + 초나라와 동일 + + +# 핵심 도메인 데이터 + +- **보드** + - Map + - **상차림**(Enum) +- **좌표** Position + - int x + - int y + + 보드 내의 좌표 범위 검증 + +- **기물** (추상 클래스) +- **규칙** MoveRule + +# 도메인 구현 리스트 + +- **보드** + - [ ] 선택한 상차림에 맞게 보드를 초기화한다. + - 마상마상 + - 상마상마 + - 마상상마 + - 상마마상 + - [ ] 해당 기물의 이동 가능 여부를 판단한다 + - 멱에 다른 기물이 있으면 안 되는 경우: 마,상, 졸/병, 차, 장, 사 + - 멱 사이에 하나의 기물이 있어야 하는 경우: 포 + - 그 기물이 포여서는 안 된다. + - 이동하고자 하는 좌표 자체가 포 or 아군이면 안 된다. + - [ ] 기물을 이동시킨다. +- 상차림 + - [ ] 각 나라가 선택한 상차림을 보드에게 넘겨준다. + - 마상마상 + - 상마상마 + - 마상상마 + - 상마마상 +- **좌표** + - [x] 보드 내의 좌표 범위를 검증한다. +- **기물** (추상 클래스) + - [ ] 해당 기물의 이동 규칙에 따라 이동 가능한 좌표를 계산한다. +- **규칙** MoveRule(추상 클래스) + - [ ] 각 기물은 고유의 규칙을 가진다. diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java new file mode 100644 index 0000000000..7d4bbee4c4 --- /dev/null +++ b/src/main/java/janggi/domain/Position.java @@ -0,0 +1,18 @@ +package janggi.domain; + +public class Position { + private final int x; + private final int y; + + public Position(int x, int y) { + validateBoundary(x, y); + this.x = x; + this.y = y; + } + + private void validateBoundary(int x, int y) { + if(x < 1 || x > 9 || y < 1 || y > 10) { + throw new IllegalArgumentException("[ERROR] 보드 범위를 벗어났습니다."); + } + } +} From cc4a35d3cfed8a67328c3c222ac83d8d486f1a11 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Wed, 25 Mar 2026 17:22:41 +0900 Subject: [PATCH 02/30] =?UTF-8?q?docs(readme):=20v1.1=20=ED=8C=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EA=B8=B0=EB=AC=BC=EC=9D=B4=20?= =?UTF-8?q?=EA=B7=9C=EC=B9=99=EC=9D=84=20=EA=B0=96=EA=B3=A0=EC=9E=88?= =?UTF-8?q?=EA=B2=8C=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f4b00a71d0..d84ba461fc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 장기 미션 저장소 -version : 1.0 (초기 구조 설계) +version : 1.1 (팀 추가 및 기물이 규칙을 갖고있게함) # 시나리오 @@ -63,5 +63,6 @@ version : 1.0 (초기 구조 설계) - [x] 보드 내의 좌표 범위를 검증한다. - **기물** (추상 클래스) - [ ] 해당 기물의 이동 규칙에 따라 이동 가능한 좌표를 계산한다. -- **규칙** MoveRule(추상 클래스) - - [ ] 각 기물은 고유의 규칙을 가진다. + - **규칙** MoveRule(인터페이스) + - [ ] 각 기물은 고유의 규칙을 가진다. + - 팀 Team(enum) From 4d014e3575b3b21b3f68d1e3e9c226f0e47d209b Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Wed, 25 Mar 2026 17:29:14 +0900 Subject: [PATCH 03/30] =?UTF-8?q?feat(Team):=20=EC=B4=88=EB=82=98=EB=9D=BC?= =?UTF-8?q?=EC=99=80=20=ED=95=9C=EB=82=98=EB=9D=BC=20enum=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Team.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/janggi/domain/Team.java diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/Team.java new file mode 100644 index 0000000000..978fb8d764 --- /dev/null +++ b/src/main/java/janggi/domain/Team.java @@ -0,0 +1,12 @@ +package janggi.domain; + +public enum Team { + CHO("초나라"), + HAN("한나라"); + + private final String name; + + Team(String name) { + this.name = name; + } +} From 782e1dcb97187f5a40f96389e059e178cab371aa Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 26 Mar 2026 13:20:49 +0900 Subject: [PATCH 04/30] =?UTF-8?q?docs(readme):=20v1.2=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=EC=9D=98=20=EC=96=B4=EB=A0=A4=EC=9B=80=EC=97=90=20=EB=94=B0?= =?UTF-8?q?=EB=A5=B8=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?->=20=EB=8F=8C=EC=95=84=EA=B0=80=EB=8A=94=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A5=BC=20=EC=9A=B0=EC=84=A0=20=EB=A7=8C=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EB=B3=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index d84ba461fc..236279d729 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ 장기 미션 저장소 -version : 1.1 (팀 추가 및 기물이 규칙을 갖고있게함) +version : 1.2 (구현의 어려움에 따른 도메인 변경 : 돌아가는 코드를 우선 만들어보기) # 시나리오 @@ -24,45 +24,21 @@ version : 1.1 (팀 추가 및 기물이 규칙을 갖고있게함) 초나라와 동일 - -# 핵심 도메인 데이터 - -- **보드** - - Map - - **상차림**(Enum) -- **좌표** Position - - int x - - int y - - 보드 내의 좌표 범위 검증 - -- **기물** (추상 클래스) -- **규칙** MoveRule - # 도메인 구현 리스트 - **보드** - - [ ] 선택한 상차림에 맞게 보드를 초기화한다. - - 마상마상 - - 상마상마 - - 마상상마 - - 상마마상 + - [ ] 상차림은 마상마상으로 고정하여 초기화 한다. (추후 추가 예정) - [ ] 해당 기물의 이동 가능 여부를 판단한다 - 멱에 다른 기물이 있으면 안 되는 경우: 마,상, 졸/병, 차, 장, 사 - 멱 사이에 하나의 기물이 있어야 하는 경우: 포 - 그 기물이 포여서는 안 된다. - 이동하고자 하는 좌표 자체가 포 or 아군이면 안 된다. - [ ] 기물을 이동시킨다. -- 상차림 - - [ ] 각 나라가 선택한 상차림을 보드에게 넘겨준다. - - 마상마상 - - 상마상마 - - 마상상마 - - 상마마상 - **좌표** - [x] 보드 내의 좌표 범위를 검증한다. -- **기물** (추상 클래스) - - [ ] 해당 기물의 이동 규칙에 따라 이동 가능한 좌표를 계산한다. - - **규칙** MoveRule(인터페이스) - - [ ] 각 기물은 고유의 규칙을 가진다. - - 팀 Team(enum) +- **기물** + - [ ] 해당 기물은 팀과 기물 타입을 가진다. + - [ ] PieceType(enum) 작성 + - [ ] 팀 Team(enum) 작성 +- **규칙** + - [ ] 각 기물은 고유의 규칙을 가진다. From 68a19d2c2ebe404afb744d669c2b2bd1e6a64257 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 26 Mar 2026 13:33:42 +0900 Subject: [PATCH 05/30] =?UTF-8?q?feat:=20=ED=95=B4=EB=8B=B9=20=EA=B8=B0?= =?UTF-8?q?=EB=AC=BC=EC=9D=80=20=ED=8C=80=EA=B3=BC=20=EA=B8=B0=EB=AC=BC=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=9D=84=20=EA=B0=80=EC=A7=84=EB=8B=A4.=20?= =?UTF-8?q?=20TDD=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- src/main/java/janggi/domain/Piece.java | 19 ++++++++++++++++++ src/main/java/janggi/domain/PieceType.java | 14 +++++++++++++ src/main/java/janggi/domain/Team.java | 4 ++++ src/test/java/janggi/domain/PieceTest.java | 23 ++++++++++++++++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 src/main/java/janggi/domain/Piece.java create mode 100644 src/main/java/janggi/domain/PieceType.java create mode 100644 src/test/java/janggi/domain/PieceTest.java diff --git a/README.md b/README.md index 236279d729..3c148584c7 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,8 @@ version : 1.2 (구현의 어려움에 따른 도메인 변경 : 돌아가는 코 - **좌표** - [x] 보드 내의 좌표 범위를 검증한다. - **기물** - - [ ] 해당 기물은 팀과 기물 타입을 가진다. - - [ ] PieceType(enum) 작성 - - [ ] 팀 Team(enum) 작성 + - [x] 해당 기물은 팀과 기물 타입을 가진다. + - [x] PieceType(enum) 작성 + - [x] 팀 Team(enum) 작성 - **규칙** - [ ] 각 기물은 고유의 규칙을 가진다. diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java new file mode 100644 index 0000000000..1dbeadd710 --- /dev/null +++ b/src/main/java/janggi/domain/Piece.java @@ -0,0 +1,19 @@ +package janggi.domain; + +public class Piece { + private final Team team; + private final PieceType pieceType; + + public Piece(Team team, PieceType pieceType) { + this.team = team; + this.pieceType = pieceType; + } + + public String getTeamName() { + return team.getName(); + } + + public String getPieceTypeName(){ + return pieceType.getName(); + } +} diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java new file mode 100644 index 0000000000..31dc18e940 --- /dev/null +++ b/src/main/java/janggi/domain/PieceType.java @@ -0,0 +1,14 @@ +package janggi.domain; + +public enum PieceType { + ZOL("졸"); + private final String name; + + PieceType(String name) { + this.name = name; + } + + public String getName(){ + return name; + } +} diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/Team.java index 978fb8d764..9d7c221835 100644 --- a/src/main/java/janggi/domain/Team.java +++ b/src/main/java/janggi/domain/Team.java @@ -9,4 +9,8 @@ public enum Team { Team(String name) { this.name = name; } + + public String getName() { + return name; + } } diff --git a/src/test/java/janggi/domain/PieceTest.java b/src/test/java/janggi/domain/PieceTest.java new file mode 100644 index 0000000000..e894fa0670 --- /dev/null +++ b/src/test/java/janggi/domain/PieceTest.java @@ -0,0 +1,23 @@ +package janggi.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PieceTest { + + @Test + @DisplayName("기물에는 초나라 졸이 있다.") + void 기물은_초나라_졸이_있음(){ + //given + Team cho = Team.CHO; + PieceType zol = PieceType.ZOL; + Piece piece = new Piece(cho,zol); + + //when & then + assertThat(piece.getTeamName()).isEqualTo("초나라"); + assertThat(piece.getPieceTypeName()).isEqualTo("졸"); + } +} From 0dac84926a65d3c4ed4d35ecffe44c72602e75d5 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 26 Mar 2026 17:44:55 +0900 Subject: [PATCH 06/30] =?UTF-8?q?feat:=20=EC=83=81=EC=B0=A8=EB=A6=BC?= =?UTF-8?q?=EC=9D=80=20=EB=A7=88=EC=83=81=EB=A7=88=EC=83=81=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B3=A0=EC=A0=95=ED=95=98=EC=97=AC=20=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EC=B4=88=EA=B8=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (상차림 추후 추가 예정) --- README.md | 2 +- src/main/java/janggi/domain/Board.java | 65 ++++++++++++++++++++++ src/main/java/janggi/domain/Piece.java | 15 +++++ src/main/java/janggi/domain/PieceType.java | 26 ++++++++- src/main/java/janggi/domain/Position.java | 15 +++++ src/test/java/janggi/domain/BoardTest.java | 48 ++++++++++++++++ src/test/java/janggi/domain/PieceTest.java | 1 - 7 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 src/main/java/janggi/domain/Board.java create mode 100644 src/test/java/janggi/domain/BoardTest.java diff --git a/README.md b/README.md index 3c148584c7..9a92c91675 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ version : 1.2 (구현의 어려움에 따른 도메인 변경 : 돌아가는 코 # 도메인 구현 리스트 - **보드** - - [ ] 상차림은 마상마상으로 고정하여 초기화 한다. (추후 추가 예정) + - [x] 상차림은 마상마상으로 고정하여 초기화 한다. (추후 추가 예정) - [ ] 해당 기물의 이동 가능 여부를 판단한다 - 멱에 다른 기물이 있으면 안 되는 경우: 마,상, 졸/병, 차, 장, 사 - 멱 사이에 하나의 기물이 있어야 하는 경우: 포 diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java new file mode 100644 index 0000000000..52f69f7e8c --- /dev/null +++ b/src/main/java/janggi/domain/Board.java @@ -0,0 +1,65 @@ +package janggi.domain; + +import java.util.HashMap; +import java.util.Map; + +public class Board { + + private final Map board; + + public Board() { + this.board = initialize(); + } + + public Map initialize() { + Map initBoard = new HashMap<>(); + + initBoard.put(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); + initBoard.put(new Position(3, 7), new Piece(Team.CHO, PieceType.ZOL)); + initBoard.put(new Position(5, 7), new Piece(Team.CHO, PieceType.ZOL)); + initBoard.put(new Position(7, 7), new Piece(Team.CHO, PieceType.ZOL)); + initBoard.put(new Position(9, 7), new Piece(Team.CHO, PieceType.ZOL)); + + initBoard.put(new Position(2, 8), new Piece(Team.CHO, PieceType.PO)); + initBoard.put(new Position(8, 8), new Piece(Team.CHO, PieceType.PO)); + + initBoard.put(new Position(1, 10), new Piece(Team.CHO, PieceType.CHA)); + initBoard.put(new Position(9, 10), new Piece(Team.CHO, PieceType.CHA)); + + initBoard.put(new Position(2, 10), new Piece(Team.CHO, PieceType.MA)); + initBoard.put(new Position(3, 10), new Piece(Team.CHO, PieceType.SANG)); + initBoard.put(new Position(7, 10), new Piece(Team.CHO, PieceType.MA)); + initBoard.put(new Position(8, 10), new Piece(Team.CHO, PieceType.SANG)); + + initBoard.put(new Position(4, 10), new Piece(Team.CHO, PieceType.SA)); + initBoard.put(new Position(6, 10), new Piece(Team.CHO, PieceType.SA)); + initBoard.put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); + + initBoard.put(new Position(1, 4), new Piece(Team.HAN, PieceType.ZOL)); + initBoard.put(new Position(3, 4), new Piece(Team.HAN, PieceType.ZOL)); + initBoard.put(new Position(5, 4), new Piece(Team.HAN, PieceType.ZOL)); + initBoard.put(new Position(7, 4), new Piece(Team.HAN, PieceType.ZOL)); + initBoard.put(new Position(9, 4), new Piece(Team.HAN, PieceType.ZOL)); + + initBoard.put(new Position(2, 3), new Piece(Team.HAN, PieceType.PO)); + initBoard.put(new Position(8, 3), new Piece(Team.HAN, PieceType.PO)); + + initBoard.put(new Position(1, 1), new Piece(Team.HAN, PieceType.CHA)); + initBoard.put(new Position(9, 1), new Piece(Team.HAN, PieceType.CHA)); + + initBoard.put(new Position(2, 1), new Piece(Team.HAN, PieceType.MA)); + initBoard.put(new Position(3, 1), new Piece(Team.HAN, PieceType.SANG)); + initBoard.put(new Position(7, 1), new Piece(Team.HAN, PieceType.MA)); + initBoard.put(new Position(8, 1), new Piece(Team.HAN, PieceType.SANG)); + + initBoard.put(new Position(4, 1), new Piece(Team.HAN, PieceType.SA)); + initBoard.put(new Position(6, 1), new Piece(Team.HAN, PieceType.SA)); + initBoard.put(new Position(5, 2), new Piece(Team.HAN, PieceType.KING)); + + return initBoard; + } + + public Map getBoard() { + return board; + } +} diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 1dbeadd710..f5e6adb93e 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -1,5 +1,7 @@ package janggi.domain; +import java.util.Objects; + public class Piece { private final Team team; private final PieceType pieceType; @@ -16,4 +18,17 @@ public String getTeamName() { public String getPieceTypeName(){ return pieceType.getName(); } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Piece piece)) { + return false; + } + return team == piece.team && pieceType == piece.pieceType; + } + + @Override + public int hashCode() { + return Objects.hash(team, pieceType); + } } diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index 31dc18e940..467f6f1446 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -1,14 +1,36 @@ package janggi.domain; +import java.util.List; + public enum PieceType { - ZOL("졸"); + KING("왕", List.of(5),9), + SA("사",List.of(4,6),10), + SANG("상",List.of(3,7),10), + MA("마",List.of(2,8),10), + CHA("차",List.of(1,9),10), + PO("포",List.of(2,8),8), + ZOL("졸",List.of(1,3,5,7,9),7); + private final String name; + private final List xPositions; + private final int yPosition; - PieceType(String name) { + PieceType(String name, List xPositions, int yPosition) { this.name = name; + this.xPositions = xPositions; + this.yPosition = yPosition; } public String getName(){ return name; } + + + public List getXPositions() { + return xPositions; + } + + public int getYPosition() { + return yPosition; + } } diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java index 7d4bbee4c4..892d00d0dd 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/Position.java @@ -1,5 +1,7 @@ package janggi.domain; +import java.util.Objects; + public class Position { private final int x; private final int y; @@ -15,4 +17,17 @@ private void validateBoundary(int x, int y) { throw new IllegalArgumentException("[ERROR] 보드 범위를 벗어났습니다."); } } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Position position)) { + return false; + } + return x == position.x && y == position.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } } diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java new file mode 100644 index 0000000000..665bc32983 --- /dev/null +++ b/src/test/java/janggi/domain/BoardTest.java @@ -0,0 +1,48 @@ +package janggi.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + + +public class BoardTest { + + @ParameterizedTest + @CsvSource({ + + "CHO,KING,5,9", + "CHO,SA,4,10","CHO,SA,6,10", + "CHO,SANG,3,10","CHO,SANG,8,10", + "CHO,MA,2,10","CHO,MA,7,10", + "CHO,CHA,1,10","CHO,CHA,9,10", + "CHO,PO,2,8","CHO,PO,8,8", + "CHO,ZOL,1,7", "CHO,ZOL,3,7", "CHO,ZOL,5,7", "CHO,ZOL,7,7", "CHO,ZOL,9,7", + + "HAN,KING,5,2", + "HAN,SA,4,1","HAN,SA,6,1", + "HAN,SANG,3,1","HAN,SANG,8,1", + "HAN,MA,2,1","HAN,MA,7,1", + "HAN,CHA,1,1","HAN,CHA,9,1", + "HAN,PO,2,3","HAN,PO,8,3", + "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4", + + + }) + @DisplayName("초기 위치에 각나라 졸이 있다.") + void 초기_위치에_각나라_졸_세팅(Team team, PieceType pieceType, int x, int y){ + //given + Board board = new Board(); + Position position = new Position(x,y); + Piece zol = new Piece(team,pieceType); + + //when + board.initialize(); + Map checkZol = board.getBoard(); + + //then + assertThat(checkZol.get(position)).isEqualTo(zol); + } +} diff --git a/src/test/java/janggi/domain/PieceTest.java b/src/test/java/janggi/domain/PieceTest.java index e894fa0670..18a47a0de2 100644 --- a/src/test/java/janggi/domain/PieceTest.java +++ b/src/test/java/janggi/domain/PieceTest.java @@ -1,7 +1,6 @@ package janggi.domain; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 7aade2e30810de8257c4ab9adfa2ac4378287728 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Fri, 27 Mar 2026 16:07:34 +0900 Subject: [PATCH 07/30] =?UTF-8?q?feat:=20=EA=B0=81=20=EA=B8=B0=EB=AC=BC?= =?UTF-8?q?=EC=9D=80=20=EA=B3=A0=EC=9C=A0=EC=9D=98=20=EA=B7=9C=EC=B9=99?= =?UTF-8?q?=EC=9D=84=20=EA=B0=80=EC=A7=84=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/main/java/janggi/domain/Direction.java | 23 +++ src/main/java/janggi/domain/MoveRule.java | 78 ++++++++ src/main/java/janggi/domain/Piece.java | 4 + src/main/java/janggi/domain/Route.java | 26 +++ src/test/java/janggi/domain/BoardTest.java | 4 +- src/test/java/janggi/domain/MoveRuleTest.java | 181 ++++++++++++++++++ 7 files changed, 314 insertions(+), 4 deletions(-) create mode 100644 src/main/java/janggi/domain/Direction.java create mode 100644 src/main/java/janggi/domain/MoveRule.java create mode 100644 src/main/java/janggi/domain/Route.java create mode 100644 src/test/java/janggi/domain/MoveRuleTest.java diff --git a/README.md b/README.md index 9a92c91675..72a47ec60f 100644 --- a/README.md +++ b/README.md @@ -41,4 +41,4 @@ version : 1.2 (구현의 어려움에 따른 도메인 변경 : 돌아가는 코 - [x] PieceType(enum) 작성 - [x] 팀 Team(enum) 작성 - **규칙** - - [ ] 각 기물은 고유의 규칙을 가진다. + - [x] 각 기물은 고유의 규칙을 가진다. diff --git a/src/main/java/janggi/domain/Direction.java b/src/main/java/janggi/domain/Direction.java new file mode 100644 index 0000000000..1a42080be7 --- /dev/null +++ b/src/main/java/janggi/domain/Direction.java @@ -0,0 +1,23 @@ +package janggi.domain; + +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; + } + + +} diff --git a/src/main/java/janggi/domain/MoveRule.java b/src/main/java/janggi/domain/MoveRule.java new file mode 100644 index 0000000000..28bf70885e --- /dev/null +++ b/src/main/java/janggi/domain/MoveRule.java @@ -0,0 +1,78 @@ +package janggi.domain; + +import java.util.List; + +public class MoveRule { + + public List findRoute(Piece piece) { + + if(piece.getPieceType() == PieceType.ZOL) { + if(piece.getTeamName().equals(Team.CHO.getName())) { + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + return List.of(route1, route2, route3); + } + Route route1 = new Route(List.of(Direction.DOWN)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + return List.of(route1, route2, route3); + } + + // 마일때 경로를 반환 + if(piece.getPieceType() == PieceType.MA){ + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } + + if(piece.getPieceType() == PieceType.SANG){ + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT, Direction.UP_LEFT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } + if(piece.getPieceType()==PieceType.KING){ + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } + + if(piece.getPieceType()==PieceType.SA){ + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } + + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + return List.of(route1, route2, route3, route4); + } + + +} diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index f5e6adb93e..15ac6ff30f 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -31,4 +31,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(team, pieceType); } + + public PieceType getPieceType() { + return pieceType; + } } diff --git a/src/main/java/janggi/domain/Route.java b/src/main/java/janggi/domain/Route.java new file mode 100644 index 0000000000..d0fb551c29 --- /dev/null +++ b/src/main/java/janggi/domain/Route.java @@ -0,0 +1,26 @@ +package janggi.domain; + +import java.util.List; +import java.util.Objects; + +public class Route { + + private final List routes; + + public Route(List routes) { + this.routes = routes; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Route route)) { + return false; + } + return Objects.equals(routes, route.routes); + } + + @Override + public int hashCode() { + return Objects.hashCode(routes); + } +} diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 665bc32983..55ac831779 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -27,8 +27,7 @@ public class BoardTest { "HAN,MA,2,1","HAN,MA,7,1", "HAN,CHA,1,1","HAN,CHA,9,1", "HAN,PO,2,3","HAN,PO,8,3", - "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4", - + "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4" }) @DisplayName("초기 위치에 각나라 졸이 있다.") @@ -39,7 +38,6 @@ public class BoardTest { Piece zol = new Piece(team,pieceType); //when - board.initialize(); Map checkZol = board.getBoard(); //then diff --git a/src/test/java/janggi/domain/MoveRuleTest.java b/src/test/java/janggi/domain/MoveRuleTest.java new file mode 100644 index 0000000000..38dd048c58 --- /dev/null +++ b/src/test/java/janggi/domain/MoveRuleTest.java @@ -0,0 +1,181 @@ +package janggi.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class MoveRuleTest { + + @Test + @DisplayName("초나라 졸은 위양옆으로 갈 수 있다") + void 초나라_졸_이동규칙() { + //given + MoveRule moveRule = new MoveRule(); + Piece zol = new Piece(Team.CHO, PieceType.ZOL); + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + + List routes = List.of(route1,route2,route3); + + //when + List zolPaths = moveRule.findRoute(zol); + + //then + assertThat(zolPaths).isEqualTo(routes); + } + + @Test + @DisplayName("한나라 졸은 아래양옆으로 갈 수 있다") + void 한나라_졸_이동규칙() { + //given + MoveRule moveRule = new MoveRule(); + Piece zol = new Piece(Team.HAN, PieceType.ZOL); + Route route1 = new Route(List.of(Direction.DOWN)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + + List routes = List.of(route1,route2,route3); + + //when + List zolPaths = moveRule.findRoute(zol); + + //then + assertThat(zolPaths).isEqualTo(routes); + } + + @Test + @DisplayName("마는 직선으로 한 번 대각선으로 한 번 갈 수 있다") + void 마_이동규칙() { + //given + MoveRule moveRule = new MoveRule(); + Piece ma = new Piece(Team.CHO, PieceType.MA); + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); + + List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); + //when + List maRoutes = moveRule.findRoute(ma); + + //then + assertThat(maRoutes).isEqualTo(routes); + } + + @Test + @DisplayName("상은 직선으로 한 번 대각선으로 두 번 갈 수 있다") + void 상_이동규칙() { + //given + MoveRule moveRule = new MoveRule(); + Piece sang = new Piece(Team.CHO, PieceType.SANG); + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT, Direction.UP_LEFT)); + List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); + + //when + List sangRoutes = moveRule.findRoute(sang); + + //then + assertThat(sangRoutes).isEqualTo(routes); + } + + @Test + @DisplayName("왕은 직선과 대각선으로 갈 수 있다.") + void 왕의_이동규칙(){ + //given + MoveRule moveRule = new MoveRule(); + Piece king = new Piece(Team.CHO, PieceType.KING); + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); + + //when + List kingRoutes = moveRule.findRoute(king); + + //then + assertThat(kingRoutes).isEqualTo(routes); + } + + @Test + @DisplayName("사는 직선과 대각선으로 갈 수 있다") + void 사의_이동규칙(){ + //given + MoveRule moveRule = new MoveRule(); + Piece sa = new Piece(Team.CHO, PieceType.SA); + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); + + //when + List saRoutes = moveRule.findRoute(sa); + + //then + assertThat(saRoutes).isEqualTo(routes); + } + + @Test + @DisplayName("차는 직선으로 갈 수 있다") + void 차의_이동규칙(){ + //given + MoveRule moveRule = new MoveRule(); + Piece cha = new Piece(Team.CHO, PieceType.CHA); + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + List routes = List.of(route1, route2, route3, route4); + + //when + List chaRoutes = moveRule.findRoute(cha); + + //then + assertThat(chaRoutes).isEqualTo(routes); + } + + @Test + @DisplayName("차는 직선으로 갈 수 있다") + void 포의_이동규칙(){ + //given + MoveRule moveRule = new MoveRule(); + Piece po = new Piece(Team.CHO, PieceType.PO); + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + List routes = List.of(route1, route2, route3, route4); + + //when + List poRoutes = moveRule.findRoute(po); + + //then + assertThat(poRoutes).isEqualTo(routes); + } + +} From 8e805d5a8bc2fe97ded65ad62350280e8e242f47 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Fri, 27 Mar 2026 17:03:18 +0900 Subject: [PATCH 08/30] =?UTF-8?q?refactor:=20MoveRule=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=8A=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/MoveRule.java | 74 +------ .../janggi/domain/moveRules/ChaMoveRule.java | 19 ++ .../janggi/domain/moveRules/KingMoveRule.java | 23 +++ .../janggi/domain/moveRules/MaMoveRule.java | 23 +++ .../janggi/domain/moveRules/PoMoveRule.java | 19 ++ .../janggi/domain/moveRules/SaMoveRule.java | 23 +++ .../janggi/domain/moveRules/SangMoveRule.java | 23 +++ .../janggi/domain/moveRules/ZolMoveRule.java | 25 +++ src/test/java/janggi/domain/MoveRuleTest.java | 181 ------------------ .../domain/moveRules/ChaMoveRuleTest.java | 34 ++++ .../domain/moveRules/KingMoveRuleTest.java | 37 ++++ .../domain/moveRules/MaMoveRuleTest.java | 39 ++++ .../domain/moveRules/PoMoveRuleTest.java | 33 ++++ .../domain/moveRules/SaMoveRuleTest.java | 37 ++++ .../domain/moveRules/SangMoveRuleTest.java | 37 ++++ .../domain/moveRules/ZolMoveRuleTest.java | 52 +++++ 16 files changed, 426 insertions(+), 253 deletions(-) create mode 100644 src/main/java/janggi/domain/moveRules/ChaMoveRule.java create mode 100644 src/main/java/janggi/domain/moveRules/KingMoveRule.java create mode 100644 src/main/java/janggi/domain/moveRules/MaMoveRule.java create mode 100644 src/main/java/janggi/domain/moveRules/PoMoveRule.java create mode 100644 src/main/java/janggi/domain/moveRules/SaMoveRule.java create mode 100644 src/main/java/janggi/domain/moveRules/SangMoveRule.java create mode 100644 src/main/java/janggi/domain/moveRules/ZolMoveRule.java delete mode 100644 src/test/java/janggi/domain/MoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java create mode 100644 src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java diff --git a/src/main/java/janggi/domain/MoveRule.java b/src/main/java/janggi/domain/MoveRule.java index 28bf70885e..5cd9aaee3f 100644 --- a/src/main/java/janggi/domain/MoveRule.java +++ b/src/main/java/janggi/domain/MoveRule.java @@ -2,77 +2,7 @@ import java.util.List; -public class MoveRule { - - public List findRoute(Piece piece) { - - if(piece.getPieceType() == PieceType.ZOL) { - if(piece.getTeamName().equals(Team.CHO.getName())) { - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.LEFT)); - Route route3 = new Route(List.of(Direction.RIGHT)); - return List.of(route1, route2, route3); - } - Route route1 = new Route(List.of(Direction.DOWN)); - Route route2 = new Route(List.of(Direction.LEFT)); - Route route3 = new Route(List.of(Direction.RIGHT)); - return List.of(route1, route2, route3); - } - - // 마일때 경로를 반환 - if(piece.getPieceType() == PieceType.MA){ - Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); - Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); - Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); - Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); - Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); - Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); - Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); - Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); - return List.of(route1, route2, route3, route4, route5, route6, route7, route8); - } - - if(piece.getPieceType() == PieceType.SANG){ - Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT, Direction.UP_LEFT)); - Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT, Direction.UP_RIGHT)); - Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT, Direction.UP_RIGHT)); - Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); - Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); - Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); - Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); - Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT, Direction.UP_LEFT)); - return List.of(route1, route2, route3, route4, route5, route6, route7, route8); - } - if(piece.getPieceType()==PieceType.KING){ - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - Route route5 = new Route(List.of(Direction.UP_LEFT)); - Route route6 = new Route(List.of(Direction.UP_RIGHT)); - Route route7 = new Route(List.of(Direction.DOWN_LEFT)); - Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); - return List.of(route1, route2, route3, route4, route5, route6, route7, route8); - } - - if(piece.getPieceType()==PieceType.SA){ - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - Route route5 = new Route(List.of(Direction.UP_LEFT)); - Route route6 = new Route(List.of(Direction.UP_RIGHT)); - Route route7 = new Route(List.of(Direction.DOWN_LEFT)); - Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); - return List.of(route1, route2, route3, route4, route5, route6, route7, route8); - } - - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - return List.of(route1, route2, route3, route4); - } - +public interface MoveRule { + List findRoutes(Team team); } diff --git a/src/main/java/janggi/domain/moveRules/ChaMoveRule.java b/src/main/java/janggi/domain/moveRules/ChaMoveRule.java new file mode 100644 index 0000000000..39993bd48f --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/ChaMoveRule.java @@ -0,0 +1,19 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class ChaMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + return List.of(route1, route2, route3, route4); + } +} diff --git a/src/main/java/janggi/domain/moveRules/KingMoveRule.java b/src/main/java/janggi/domain/moveRules/KingMoveRule.java new file mode 100644 index 0000000000..d0174ddb44 --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/KingMoveRule.java @@ -0,0 +1,23 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class KingMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } +} diff --git a/src/main/java/janggi/domain/moveRules/MaMoveRule.java b/src/main/java/janggi/domain/moveRules/MaMoveRule.java new file mode 100644 index 0000000000..99379b9dcf --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/MaMoveRule.java @@ -0,0 +1,23 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class MaMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } +} diff --git a/src/main/java/janggi/domain/moveRules/PoMoveRule.java b/src/main/java/janggi/domain/moveRules/PoMoveRule.java new file mode 100644 index 0000000000..ba61b20f85 --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/PoMoveRule.java @@ -0,0 +1,19 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class PoMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + return List.of(route1, route2, route3, route4); + } +} diff --git a/src/main/java/janggi/domain/moveRules/SaMoveRule.java b/src/main/java/janggi/domain/moveRules/SaMoveRule.java new file mode 100644 index 0000000000..75a1892952 --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/SaMoveRule.java @@ -0,0 +1,23 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class SaMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } +} diff --git a/src/main/java/janggi/domain/moveRules/SangMoveRule.java b/src/main/java/janggi/domain/moveRules/SangMoveRule.java new file mode 100644 index 0000000000..fbc492bcf9 --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/SangMoveRule.java @@ -0,0 +1,23 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class SangMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT, Direction.UP_LEFT)); + return List.of(route1, route2, route3, route4, route5, route6, route7, route8); + } +} diff --git a/src/main/java/janggi/domain/moveRules/ZolMoveRule.java b/src/main/java/janggi/domain/moveRules/ZolMoveRule.java new file mode 100644 index 0000000000..d74cb9011c --- /dev/null +++ b/src/main/java/janggi/domain/moveRules/ZolMoveRule.java @@ -0,0 +1,25 @@ +package janggi.domain.moveRules; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; + +public class ZolMoveRule implements MoveRule { + + @Override + public List findRoutes(Team team) { + if(team == Team.CHO) { + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + return List.of(route1, route2, route3); + } + Route route1 = new Route(List.of(Direction.DOWN)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + return List.of(route1, route2, route3); + } + +} diff --git a/src/test/java/janggi/domain/MoveRuleTest.java b/src/test/java/janggi/domain/MoveRuleTest.java deleted file mode 100644 index 38dd048c58..0000000000 --- a/src/test/java/janggi/domain/MoveRuleTest.java +++ /dev/null @@ -1,181 +0,0 @@ -package janggi.domain; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.EnumSource; - -public class MoveRuleTest { - - @Test - @DisplayName("초나라 졸은 위양옆으로 갈 수 있다") - void 초나라_졸_이동규칙() { - //given - MoveRule moveRule = new MoveRule(); - Piece zol = new Piece(Team.CHO, PieceType.ZOL); - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.LEFT)); - Route route3 = new Route(List.of(Direction.RIGHT)); - - List routes = List.of(route1,route2,route3); - - //when - List zolPaths = moveRule.findRoute(zol); - - //then - assertThat(zolPaths).isEqualTo(routes); - } - - @Test - @DisplayName("한나라 졸은 아래양옆으로 갈 수 있다") - void 한나라_졸_이동규칙() { - //given - MoveRule moveRule = new MoveRule(); - Piece zol = new Piece(Team.HAN, PieceType.ZOL); - Route route1 = new Route(List.of(Direction.DOWN)); - Route route2 = new Route(List.of(Direction.LEFT)); - Route route3 = new Route(List.of(Direction.RIGHT)); - - List routes = List.of(route1,route2,route3); - - //when - List zolPaths = moveRule.findRoute(zol); - - //then - assertThat(zolPaths).isEqualTo(routes); - } - - @Test - @DisplayName("마는 직선으로 한 번 대각선으로 한 번 갈 수 있다") - void 마_이동규칙() { - //given - MoveRule moveRule = new MoveRule(); - Piece ma = new Piece(Team.CHO, PieceType.MA); - Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); - Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); - Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); - Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); - Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); - Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); - Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); - Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); - - List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); - //when - List maRoutes = moveRule.findRoute(ma); - - //then - assertThat(maRoutes).isEqualTo(routes); - } - - @Test - @DisplayName("상은 직선으로 한 번 대각선으로 두 번 갈 수 있다") - void 상_이동규칙() { - //given - MoveRule moveRule = new MoveRule(); - Piece sang = new Piece(Team.CHO, PieceType.SANG); - Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT, Direction.UP_LEFT)); - Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT, Direction.UP_RIGHT)); - Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT, Direction.UP_RIGHT)); - Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); - Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); - Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); - Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); - Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT, Direction.UP_LEFT)); - List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); - - //when - List sangRoutes = moveRule.findRoute(sang); - - //then - assertThat(sangRoutes).isEqualTo(routes); - } - - @Test - @DisplayName("왕은 직선과 대각선으로 갈 수 있다.") - void 왕의_이동규칙(){ - //given - MoveRule moveRule = new MoveRule(); - Piece king = new Piece(Team.CHO, PieceType.KING); - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - Route route5 = new Route(List.of(Direction.UP_LEFT)); - Route route6 = new Route(List.of(Direction.UP_RIGHT)); - Route route7 = new Route(List.of(Direction.DOWN_LEFT)); - Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); - List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); - - //when - List kingRoutes = moveRule.findRoute(king); - - //then - assertThat(kingRoutes).isEqualTo(routes); - } - - @Test - @DisplayName("사는 직선과 대각선으로 갈 수 있다") - void 사의_이동규칙(){ - //given - MoveRule moveRule = new MoveRule(); - Piece sa = new Piece(Team.CHO, PieceType.SA); - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - Route route5 = new Route(List.of(Direction.UP_LEFT)); - Route route6 = new Route(List.of(Direction.UP_RIGHT)); - Route route7 = new Route(List.of(Direction.DOWN_LEFT)); - Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); - List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); - - //when - List saRoutes = moveRule.findRoute(sa); - - //then - assertThat(saRoutes).isEqualTo(routes); - } - - @Test - @DisplayName("차는 직선으로 갈 수 있다") - void 차의_이동규칙(){ - //given - MoveRule moveRule = new MoveRule(); - Piece cha = new Piece(Team.CHO, PieceType.CHA); - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - List routes = List.of(route1, route2, route3, route4); - - //when - List chaRoutes = moveRule.findRoute(cha); - - //then - assertThat(chaRoutes).isEqualTo(routes); - } - - @Test - @DisplayName("차는 직선으로 갈 수 있다") - void 포의_이동규칙(){ - //given - MoveRule moveRule = new MoveRule(); - Piece po = new Piece(Team.CHO, PieceType.PO); - Route route1 = new Route(List.of(Direction.UP)); - Route route2 = new Route(List.of(Direction.RIGHT)); - Route route3 = new Route(List.of(Direction.DOWN)); - Route route4 = new Route(List.of(Direction.LEFT)); - List routes = List.of(route1, route2, route3, route4); - - //when - List poRoutes = moveRule.findRoute(po); - - //then - assertThat(poRoutes).isEqualTo(routes); - } - -} diff --git a/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java new file mode 100644 index 0000000000..6f88af11cd --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java @@ -0,0 +1,34 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class ChaMoveRuleTest { + + @Test + @DisplayName("차는 직선으로 갈 수 있다") + void 차의_이동규칙(){ + //given + MoveRule moveRule = new ChaMoveRule(); + Team team = Team.CHO; + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + List routes = List.of(route1, route2, route3, route4); + + //when + List chaRoutes = moveRule.findRoutes(team); + + //then + assertThat(chaRoutes).isEqualTo(routes); + } + +} diff --git a/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java new file mode 100644 index 0000000000..60a8d48fc9 --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java @@ -0,0 +1,37 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class KingMoveRuleTest { + + @Test + @DisplayName("왕은 직선과 대각선으로 갈 수 있다.") + void 왕의_이동규칙(){ + //given + MoveRule moveRule = new KingMoveRule(); + Team team = Team.CHO; + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); + + //when + List kingRoutes = moveRule.findRoutes(team); + + //then + assertThat(kingRoutes).isEqualTo(routes); + } +} diff --git a/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java new file mode 100644 index 0000000000..e0925db4f2 --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java @@ -0,0 +1,39 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Piece; +import janggi.domain.PieceType; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class MaMoveRuleTest { + + @Test + @DisplayName("마는 직선으로 한 번 대각선으로 한 번 갈 수 있다") + void 마_이동규칙() { + //given + MoveRule moveRule = new MaMoveRule(); + Team team = Team.HAN; + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); + + List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); + //when + List maRoutes = moveRule.findRoutes(team); + + //then + assertThat(maRoutes).isEqualTo(routes); + } +} diff --git a/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java new file mode 100644 index 0000000000..15b35a0794 --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java @@ -0,0 +1,33 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PoMoveRuleTest { + + @Test + @DisplayName("포는 직선으로 갈 수 있다") + void 포의_이동규칙(){ + //given + MoveRule moveRule = new PoMoveRule(); + Team team = Team.CHO; + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + List routes = List.of(route1, route2, route3, route4); + + //when + List poRoutes = moveRule.findRoutes(team); + + //then + assertThat(poRoutes).isEqualTo(routes); + } +} diff --git a/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java new file mode 100644 index 0000000000..148ddf9421 --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java @@ -0,0 +1,37 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class SaMoveRuleTest { + + @Test + @DisplayName("사는 직선과 대각선으로 갈 수 있다") + void 사의_이동규칙(){ + //given + MoveRule moveRule = new SaMoveRule(); + Team team = Team.CHO; + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.RIGHT)); + Route route3 = new Route(List.of(Direction.DOWN)); + Route route4 = new Route(List.of(Direction.LEFT)); + Route route5 = new Route(List.of(Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.UP_RIGHT)); + Route route7 = new Route(List.of(Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.DOWN_RIGHT)); + List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); + + //when + List saRoutes = moveRule.findRoutes(team); + + //then + assertThat(saRoutes).isEqualTo(routes); + } +} diff --git a/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java new file mode 100644 index 0000000000..ab54840159 --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java @@ -0,0 +1,37 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class SangMoveRuleTest { + + @Test + @DisplayName("상은 직선으로 한 번 대각선으로 두 번 갈 수 있다") + void 상_이동규칙() { + //given + MoveRule moveRule = new SangMoveRule(); + Team team = Team.CHO; + Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT, Direction.UP_LEFT)); + Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT, Direction.UP_RIGHT)); + Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT, Direction.DOWN_RIGHT)); + Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT, Direction.UP_LEFT)); + List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); + + //when + List sangRoutes = moveRule.findRoutes(team); + + //then + assertThat(sangRoutes).isEqualTo(routes); + } +} diff --git a/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java new file mode 100644 index 0000000000..fc1dc9e7ff --- /dev/null +++ b/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java @@ -0,0 +1,52 @@ +package janggi.domain.moveRules; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Direction; +import janggi.domain.MoveRule; +import janggi.domain.Route; +import janggi.domain.Team; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class ZolMoveRuleTest { + + @Test + @DisplayName("초나라 졸은 위양옆으로 갈 수 있다") + void 초나라_졸_이동규칙() { + //given + MoveRule moveRule = new ZolMoveRule(); + Team cho = Team.CHO; + Route route1 = new Route(List.of(Direction.UP)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + + List routes = List.of(route1,route2,route3); + + //when + List zolPaths = moveRule.findRoutes(cho); + + //then + assertThat(zolPaths).isEqualTo(routes); + } + + @Test + @DisplayName("한나라 졸은 아래양옆으로 갈 수 있다") + void 한나라_졸_이동규칙() { + //given + MoveRule moveRule = new ZolMoveRule(); + Team han = Team.HAN; + Route route1 = new Route(List.of(Direction.DOWN)); + Route route2 = new Route(List.of(Direction.LEFT)); + Route route3 = new Route(List.of(Direction.RIGHT)); + + List routes = List.of(route1,route2,route3); + + //when + List zolPaths = moveRule.findRoutes(han); + + //then + assertThat(zolPaths).isEqualTo(routes); + } +} From ed501e2351d7bb73f29846c4829d3716fd0fc86d Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 11:16:35 +0900 Subject: [PATCH 09/30] =?UTF-8?q?feat:=20=EC=A1=B8=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 77 ++++++++++++++++++++++ src/main/java/janggi/domain/Direction.java | 25 ++++--- src/main/java/janggi/domain/Piece.java | 4 ++ src/main/java/janggi/domain/PieceType.java | 30 ++++++--- src/main/java/janggi/domain/Position.java | 13 ++++ src/main/java/janggi/domain/Route.java | 4 ++ src/test/java/janggi/domain/BoardTest.java | 41 ++++++++++++ 7 files changed, 176 insertions(+), 18 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 52f69f7e8c..f3e90c31bd 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -1,6 +1,8 @@ package janggi.domain; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class Board { @@ -62,4 +64,79 @@ public Map initialize() { public Map getBoard() { return board; } + + public List findAvailablePositions(Position position) { + Piece piece = board.get(position); + PieceType pieceType = piece.getPieceType(); + + MoveRule moveRule = pieceType.getMoveRule(); + + List routes = moveRule.findRoutes(piece.getTeam()); + + Map> routePositions = convertToPositions(position, routes); + + List availablePositions = new ArrayList<>(); + for (Map.Entry> entry : routePositions.entrySet()) { + Position destination = entry.getKey(); + Piece destinationPiece = board.get(destination); + List route = entry.getValue(); + + if (hasObstacleOnRoute(route)) { + continue; + } + + if (board.containsKey(destination)) { + if (isDestinationIsMyTeam(destinationPiece, piece)) { + continue; + } + } + availablePositions.add(destination); + } + + return availablePositions; + } + + private boolean isDestinationIsMyTeam(Piece destinationPiece, Piece piece) { + return destinationPiece.getTeam() == piece.getTeam(); + } + + private boolean hasObstacleOnRoute(List route) { + for (int i = 0; i < route.size() - 1; i++) { + if (board.containsKey(route.get(i))) { + return true; + } + } + return false; + } + + private Map> convertToPositions(Position position, List routes) { + Map> result = new HashMap<>(); + + return convertToFixedRoutes(position, routes, result); + } + + private Map> convertToFixedRoutes(Position position, List routes, + Map> result) { + for (Route route : routes) { + int currentX = position.getX(); + int currentY = position.getY(); + List routeToPositions = new ArrayList<>(); + List directions = route.getRoutes(); + + boolean isInBoard = true; + for (Direction direction : directions) { + currentX += direction.getX(); + currentY += direction.getY(); + if (!Position.isInsideBoundary(currentX, currentY)) { + isInBoard = false; + break; + } + routeToPositions.add(new Position(currentX, currentY)); + } + if (isInBoard && !routeToPositions.isEmpty()) { + result.put(routeToPositions.getLast(), routeToPositions); + } + } + return result; + } } diff --git a/src/main/java/janggi/domain/Direction.java b/src/main/java/janggi/domain/Direction.java index 1a42080be7..6b942ff3fa 100644 --- a/src/main/java/janggi/domain/Direction.java +++ b/src/main/java/janggi/domain/Direction.java @@ -1,15 +1,15 @@ package janggi.domain; -public enum Direction{ - UP(0,-1), - DOWN(0,1), - LEFT(-1,0), - RIGHT(1,0), +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); + UP_LEFT(-1, -1), + UP_RIGHT(1, -1), + DOWN_LEFT(-1, 1), + DOWN_RIGHT(1, 1); private final int x; private final int y; @@ -20,4 +20,11 @@ public enum Direction{ } + public int getX() { + return x; + } + + public int getY() { + return y; + } } diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 15ac6ff30f..23cf74ae8a 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -35,4 +35,8 @@ public int hashCode() { public PieceType getPieceType() { return pieceType; } + + public Team getTeam() { + return team; + } } diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index 467f6f1446..92c8f3a1a1 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -1,31 +1,39 @@ package janggi.domain; +import janggi.domain.moveRules.ChaMoveRule; +import janggi.domain.moveRules.KingMoveRule; +import janggi.domain.moveRules.MaMoveRule; +import janggi.domain.moveRules.PoMoveRule; +import janggi.domain.moveRules.SaMoveRule; +import janggi.domain.moveRules.SangMoveRule; +import janggi.domain.moveRules.ZolMoveRule; import java.util.List; public enum PieceType { - KING("왕", List.of(5),9), - SA("사",List.of(4,6),10), - SANG("상",List.of(3,7),10), - MA("마",List.of(2,8),10), - CHA("차",List.of(1,9),10), - PO("포",List.of(2,8),8), - ZOL("졸",List.of(1,3,5,7,9),7); + KING("왕", List.of(5),9, new KingMoveRule()), + SA("사",List.of(4,6),10, new SaMoveRule()), + SANG("상",List.of(3,7),10, new SangMoveRule()), + MA("마",List.of(2,8),10, new MaMoveRule()), + CHA("차",List.of(1,9),10, new ChaMoveRule()), + PO("포",List.of(2,8),8, new PoMoveRule()), + ZOL("졸",List.of(1,3,5,7,9),7, new ZolMoveRule()); private final String name; private final List xPositions; private final int yPosition; + private final MoveRule moveRule; - PieceType(String name, List xPositions, int yPosition) { + PieceType(String name, List xPositions, int yPosition, MoveRule moveRule) { this.name = name; this.xPositions = xPositions; this.yPosition = yPosition; + this.moveRule = moveRule; } public String getName(){ return name; } - public List getXPositions() { return xPositions; } @@ -33,4 +41,8 @@ public List getXPositions() { public int getYPosition() { return yPosition; } + + public MoveRule getMoveRule() { + return moveRule; + } } diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java index 892d00d0dd..dda5d90a70 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/Position.java @@ -18,6 +18,11 @@ private void validateBoundary(int x, int y) { } } + + public static boolean isInsideBoundary(int x, int y) { + return x >= 1 && x <= 9 && y >= 1 && y <= 10; + } + @Override public boolean equals(Object o) { if (!(o instanceof Position position)) { @@ -30,4 +35,12 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(x, y); } + + public int getX() { + return x; + } + + public int getY() { + return y; + } } diff --git a/src/main/java/janggi/domain/Route.java b/src/main/java/janggi/domain/Route.java index d0fb551c29..d92b053e5b 100644 --- a/src/main/java/janggi/domain/Route.java +++ b/src/main/java/janggi/domain/Route.java @@ -23,4 +23,8 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(routes); } + + public List getRoutes() { + return routes; + } } diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 55ac831779..33839091fb 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -2,8 +2,10 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; @@ -43,4 +45,43 @@ public class BoardTest { //then assertThat(checkZol.get(position)).isEqualTo(zol); } + + @Test + @DisplayName("졸의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 졸_이동가능_좌표_확인_다_가능() { + //given + Board board = new Board(); + Position position = new Position(5,7); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); + Position zolUp = new Position(5, 6); + Position zolLeft = new Position(4, 7); + Position zolRight = new Position(6, 7); + List rightAnswer = List.of(zolUp, zolRight, zolLeft); + + //when + List zolRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(rightAnswer).isEqualTo(zolRoutesPositions); + } + + @Test + @DisplayName("졸의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 졸_이동가능_좌표_확인_위_불가능() { + //given + Board board = new Board(); + Position position = new Position(5,7); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); + Position zolUp = new Position(5, 6); + board.getBoard().put(zolUp, new Piece(Team.CHO, PieceType.ZOL)); + Position zolLeft = new Position(4, 7); + Position zolRight = new Position(6, 7); + List rightAnswer = List.of(zolRight, zolLeft); + + //when + List zolRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(rightAnswer).isEqualTo(zolRoutesPositions); + } } From e55e727c08ae5391b6009500339690a6fd6e2505 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 11:18:32 +0900 Subject: [PATCH 10/30] =?UTF-8?q?test:=20=EB=A7=88=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/BoardTest.java | 74 ++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 33839091fb..895e0ddadf 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -84,4 +84,78 @@ public class BoardTest { //then assertThat(rightAnswer).isEqualTo(zolRoutesPositions); } + + @Test + @DisplayName("마의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 마_이동가능_좌표_확인_다_가능() { + //given + Board board = new Board(); + Position position = new Position(4,6); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); + Position maPos1 = new Position(3, 4); + Position maPos2 = new Position(5, 4); + Position maPos3 = new Position(6, 5); + Position maPos4 = new Position(6, 7); + Position maPos5 = new Position(3, 8); + Position maPos6 = new Position(5, 8); + Position maPos7 = new Position(2,5); + Position maPos8 = new Position(2,7); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7, maPos8); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(8) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("마의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 마_이동가능_좌표_확인_경로에_다른_기물() { + //given + Board board = new Board(); + Position position = new Position(4,6); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); + board.getBoard().put(new Position(4,5), new Piece(Team.HAN, PieceType.CHA)); + Position maPos1 = new Position(6, 5); + Position maPos2 = new Position(6, 7); + Position maPos3 = new Position(3, 8); + Position maPos4 = new Position(5, 8); + Position maPos5 = new Position(2,5); + Position maPos6 = new Position(2,7); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(6) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("마의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 마_이동가능_좌표_확인_목적지에_같은팀_기물() { + //given + Board board = new Board(); + Position position = new Position(4,6); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); + board.getBoard().put(new Position(2,7), new Piece(Team.CHO, PieceType.CHA)); + Position maPos1 = new Position(3, 4); + Position maPos2 = new Position(5, 4); + Position maPos3 = new Position(6, 5); + Position maPos4 = new Position(6, 7); + Position maPos5 = new Position(3, 8); + Position maPos6 = new Position(5, 8); + Position maPos7 = new Position(2,5); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(7) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } } From 27ffdfc07fdf73e60ef81a3c2881d7a10f0a668a Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 12:54:49 +0900 Subject: [PATCH 11/30] =?UTF-8?q?fix(board):=20=EC=83=9D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B3=B4=EB=93=9C=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=ED=99=94=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 96 ++++++++++++-------------- 1 file changed, 44 insertions(+), 52 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index f3e90c31bd..bfb53fc2e2 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -7,58 +7,50 @@ public class Board { - private final Map board; - - public Board() { - this.board = initialize(); - } - - public Map initialize() { - Map initBoard = new HashMap<>(); - - initBoard.put(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); - initBoard.put(new Position(3, 7), new Piece(Team.CHO, PieceType.ZOL)); - initBoard.put(new Position(5, 7), new Piece(Team.CHO, PieceType.ZOL)); - initBoard.put(new Position(7, 7), new Piece(Team.CHO, PieceType.ZOL)); - initBoard.put(new Position(9, 7), new Piece(Team.CHO, PieceType.ZOL)); - - initBoard.put(new Position(2, 8), new Piece(Team.CHO, PieceType.PO)); - initBoard.put(new Position(8, 8), new Piece(Team.CHO, PieceType.PO)); - - initBoard.put(new Position(1, 10), new Piece(Team.CHO, PieceType.CHA)); - initBoard.put(new Position(9, 10), new Piece(Team.CHO, PieceType.CHA)); - - initBoard.put(new Position(2, 10), new Piece(Team.CHO, PieceType.MA)); - initBoard.put(new Position(3, 10), new Piece(Team.CHO, PieceType.SANG)); - initBoard.put(new Position(7, 10), new Piece(Team.CHO, PieceType.MA)); - initBoard.put(new Position(8, 10), new Piece(Team.CHO, PieceType.SANG)); - - initBoard.put(new Position(4, 10), new Piece(Team.CHO, PieceType.SA)); - initBoard.put(new Position(6, 10), new Piece(Team.CHO, PieceType.SA)); - initBoard.put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); - - initBoard.put(new Position(1, 4), new Piece(Team.HAN, PieceType.ZOL)); - initBoard.put(new Position(3, 4), new Piece(Team.HAN, PieceType.ZOL)); - initBoard.put(new Position(5, 4), new Piece(Team.HAN, PieceType.ZOL)); - initBoard.put(new Position(7, 4), new Piece(Team.HAN, PieceType.ZOL)); - initBoard.put(new Position(9, 4), new Piece(Team.HAN, PieceType.ZOL)); - - initBoard.put(new Position(2, 3), new Piece(Team.HAN, PieceType.PO)); - initBoard.put(new Position(8, 3), new Piece(Team.HAN, PieceType.PO)); - - initBoard.put(new Position(1, 1), new Piece(Team.HAN, PieceType.CHA)); - initBoard.put(new Position(9, 1), new Piece(Team.HAN, PieceType.CHA)); - - initBoard.put(new Position(2, 1), new Piece(Team.HAN, PieceType.MA)); - initBoard.put(new Position(3, 1), new Piece(Team.HAN, PieceType.SANG)); - initBoard.put(new Position(7, 1), new Piece(Team.HAN, PieceType.MA)); - initBoard.put(new Position(8, 1), new Piece(Team.HAN, PieceType.SANG)); - - initBoard.put(new Position(4, 1), new Piece(Team.HAN, PieceType.SA)); - initBoard.put(new Position(6, 1), new Piece(Team.HAN, PieceType.SA)); - initBoard.put(new Position(5, 2), new Piece(Team.HAN, PieceType.KING)); - - return initBoard; + private final Map board = new HashMap<>(); + + public void initialize() { + board.put(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); + board.put(new Position(3, 7), new Piece(Team.CHO, PieceType.ZOL)); + board.put(new Position(5, 7), new Piece(Team.CHO, PieceType.ZOL)); + board.put(new Position(7, 7), new Piece(Team.CHO, PieceType.ZOL)); + board.put(new Position(9, 7), new Piece(Team.CHO, PieceType.ZOL)); + + board.put(new Position(2, 8), new Piece(Team.CHO, PieceType.PO)); + board.put(new Position(8, 8), new Piece(Team.CHO, PieceType.PO)); + + board.put(new Position(1, 10), new Piece(Team.CHO, PieceType.CHA)); + board.put(new Position(9, 10), new Piece(Team.CHO, PieceType.CHA)); + + board.put(new Position(2, 10), new Piece(Team.CHO, PieceType.MA)); + board.put(new Position(3, 10), new Piece(Team.CHO, PieceType.SANG)); + board.put(new Position(7, 10), new Piece(Team.CHO, PieceType.MA)); + board.put(new Position(8, 10), new Piece(Team.CHO, PieceType.SANG)); + + board.put(new Position(4, 10), new Piece(Team.CHO, PieceType.SA)); + board.put(new Position(6, 10), new Piece(Team.CHO, PieceType.SA)); + board.put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); + + board.put(new Position(1, 4), new Piece(Team.HAN, PieceType.ZOL)); + board.put(new Position(3, 4), new Piece(Team.HAN, PieceType.ZOL)); + board.put(new Position(5, 4), new Piece(Team.HAN, PieceType.ZOL)); + board.put(new Position(7, 4), new Piece(Team.HAN, PieceType.ZOL)); + board.put(new Position(9, 4), new Piece(Team.HAN, PieceType.ZOL)); + + board.put(new Position(2, 3), new Piece(Team.HAN, PieceType.PO)); + board.put(new Position(8, 3), new Piece(Team.HAN, PieceType.PO)); + + board.put(new Position(1, 1), new Piece(Team.HAN, PieceType.CHA)); + board.put(new Position(9, 1), new Piece(Team.HAN, PieceType.CHA)); + + board.put(new Position(2, 1), new Piece(Team.HAN, PieceType.MA)); + board.put(new Position(3, 1), new Piece(Team.HAN, PieceType.SANG)); + board.put(new Position(7, 1), new Piece(Team.HAN, PieceType.MA)); + board.put(new Position(8, 1), new Piece(Team.HAN, PieceType.SANG)); + + board.put(new Position(4, 1), new Piece(Team.HAN, PieceType.SA)); + board.put(new Position(6, 1), new Piece(Team.HAN, PieceType.SA)); + board.put(new Position(5, 2), new Piece(Team.HAN, PieceType.KING)); } public Map getBoard() { From 361391c8507b8163af53866de3a7628f3df32263 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 12:57:14 +0900 Subject: [PATCH 12/30] =?UTF-8?q?test:=20=EC=83=81,=EC=82=AC,=EC=99=95?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=8F=99=EA=B0=80=EB=8A=A5=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=EB=A5=BC=20=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/BoardTest.java | 244 +++++++++++++++++++++ 1 file changed, 244 insertions(+) diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 895e0ddadf..b4b2500d15 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -36,6 +36,7 @@ public class BoardTest { void 초기_위치에_각나라_졸_세팅(Team team, PieceType pieceType, int x, int y){ //given Board board = new Board(); + board.initialize(); Position position = new Position(x,y); Piece zol = new Piece(team,pieceType); @@ -158,4 +159,247 @@ public class BoardTest { assertThat(maRoutesPositions).hasSize(7) .containsExactlyInAnyOrderElementsOf(rightAnswer); } + + @Test + @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 상_이동가능_좌표_확인_다_가능() { + //given + Board board = new Board(); + Position position = new Position(5,7); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); + Position maPos1 = new Position(3, 4); + Position maPos2 = new Position(7, 4); + Position maPos3 = new Position(8, 5); + Position maPos4 = new Position(8, 9); + Position maPos5 = new Position(3, 10); + Position maPos6 = new Position(7, 10); + Position maPos7 = new Position(2,5); + Position maPos8 = new Position(2,9); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7, maPos8); + + //when + List sangRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(sangRoutesPositions).hasSize(8) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 상_이동가능_좌표_확인_경로에_다른_기물_대각선() { + //given + Board board = new Board(); + Position position = new Position(5,7); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); + board.getBoard().put(new Position(6,5), new Piece(Team.CHO, PieceType.ZOL)); + Position maPos1 = new Position(3, 4); + Position maPos2 = new Position(8, 5); + Position maPos3 = new Position(8, 9); + Position maPos4 = new Position(3, 10); + Position maPos5 = new Position(7, 10); + Position maPos6 = new Position(2,5); + Position maPos7 = new Position(2,9); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7); + + //when + List sangRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(sangRoutesPositions).hasSize(7) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 상_이동가능_좌표_확인_경로에_다른_기물_직선() { + //given + Board board = new Board(); + Position position = new Position(5,7); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); + board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.ZOL)); + Position maPos1 = new Position(8, 5); + Position maPos2 = new Position(8, 9); + Position maPos3 = new Position(3, 10); + Position maPos4 = new Position(7, 10); + Position maPos5 = new Position(2,5); + Position maPos6 = new Position(2,9); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6); + + //when + List sangRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(sangRoutesPositions).hasSize(6) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 상_이동가능_좌표_확인_목적지에_같은팀_기물() { + //given + Board board = new Board(); + Position position = new Position(5,7); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); + board.getBoard().put(new Position(2,9), new Piece(Team.CHO, PieceType.ZOL)); + Position maPos1 = new Position(3, 4); + Position maPos2 = new Position(7, 4); + Position maPos3 = new Position(8, 5); + Position maPos4 = new Position(8, 9); + Position maPos5 = new Position(3, 10); + Position maPos6 = new Position(7, 10); + Position maPos7 = new Position(2,5); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7); + + //when + List sangRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(sangRoutesPositions).hasSize(7) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("사의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") + void 사_이동가능_좌표_확인_초기_위치에서_모든_방향_가능() { + //given + Board board = new Board(); + Position position = new Position(4,10); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); + Position maPos1 = new Position(4, 9); + Position maPos2 = new Position(5, 9); + Position maPos3 = new Position(5, 10); + Position maPos4 = new Position(3, 9); + Position maPos5 = new Position(3, 10); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(5) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("사의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") + void 사_이동가능_좌표_확인_초기_위치에서_목적지에_같은_팀() { + //given + Board board = new Board(); + Position position = new Position(4,10); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); + board.getBoard().put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); + Position maPos1 = new Position(4, 9); + Position maPos2 = new Position(5, 10); + Position maPos3 = new Position(3, 9); + Position maPos4 = new Position(3, 10); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(4) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("사의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") + void 사_이동가능_좌표_확인_초기_위치에서_목적지에_다른_팀() { + //given + Board board = new Board(); + Position position = new Position(4,10); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); + board.getBoard().put(new Position(5, 9), new Piece(Team.HAN, PieceType.CHA)); + Position maPos1 = new Position(4, 9); + Position maPos2 = new Position(5, 10); + Position maPos3 = new Position(3, 9); + Position maPos4 = new Position(3, 10); + Position maPos5 = new Position(5, 9); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(5) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("왕의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") + void 왕_이동가능_좌표_확인_초기_위치에서_모든_방향_가능() { + //given + Board board = new Board(); + Position position = new Position(5,9); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); + Position maPos1 = new Position(4, 8); + Position maPos2 = new Position(5, 8); + Position maPos3 = new Position(6, 8); + Position maPos4 = new Position(6, 9); + Position maPos5 = new Position(6, 10); + Position maPos6 = new Position(5, 10); + Position maPos7 = new Position(4, 10); + Position maPos8 = new Position(4, 9); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7, maPos8); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(8) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("왕의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") + void 왕_이동가능_좌표_확인_초기_위치에서_목적지에_같은_팀() { + //given + Board board = new Board(); + Position position = new Position(5,9); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); + board.getBoard().put(new Position(4, 9), new Piece(Team.CHO, PieceType.SA)); + board.getBoard().put(new Position(4, 10), new Piece(Team.CHO, PieceType.SA)); + Position maPos1 = new Position(4, 8); + Position maPos2 = new Position(5, 8); + Position maPos3 = new Position(6, 8); + Position maPos4 = new Position(6, 9); + Position maPos5 = new Position(6, 10); + Position maPos6 = new Position(5, 10); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(6) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("왕의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") + void 왕_이동가능_좌표_확인_초기_위치에서_목적지에_다른_팀() { + //given + Board board = new Board(); + Position position = new Position(5,9); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); + board.getBoard().put(new Position(4, 9), new Piece(Team.HAN, PieceType.ZOL)); + board.getBoard().put(new Position(4, 10), new Piece(Team.HAN, PieceType.CHA)); + Position maPos1 = new Position(4, 8); + Position maPos2 = new Position(5, 8); + Position maPos3 = new Position(6, 8); + Position maPos4 = new Position(6, 9); + Position maPos5 = new Position(6, 10); + Position maPos6 = new Position(5, 10); + Position maPos7 = new Position(4, 10); + Position maPos8 = new Position(4, 9); + List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7, maPos8); + + //when + List maRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(maRoutesPositions).hasSize(8) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } } From a49a2c4d599a47ef55f0812f98cd3cedb8f8b644 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 13:12:52 +0900 Subject: [PATCH 13/30] =?UTF-8?q?feat:=20=EC=B0=A8=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 32 +++++++- src/main/java/janggi/domain/Piece.java | 8 ++ src/test/java/janggi/domain/BoardTest.java | 89 ++++++++++++++++++++++ 3 files changed, 127 insertions(+), 2 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index bfb53fc2e2..c5019056d0 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -65,7 +65,7 @@ public List findAvailablePositions(Position position) { List routes = moveRule.findRoutes(piece.getTeam()); - Map> routePositions = convertToPositions(position, routes); + Map> routePositions = convertToPositions(position, piece, routes); List availablePositions = new ArrayList<>(); for (Map.Entry> entry : routePositions.entrySet()) { @@ -101,9 +101,13 @@ private boolean hasObstacleOnRoute(List route) { return false; } - private Map> convertToPositions(Position position, List routes) { + private Map> convertToPositions(Position position, Piece piece, List routes) { Map> result = new HashMap<>(); + if(piece.isCha()) { + return convertToContinuousRoutes(position, routes, result); + } + return convertToFixedRoutes(position, routes, result); } @@ -131,4 +135,28 @@ private Map> convertToFixedRoutes(Position position, Li } return result; } + + private Map> convertToContinuousRoutes(Position position, List routes, Map> result) { + for(Route route: routes) { + int currentX = position.getX(); + int currentY = position.getY(); + List directions = route.getRoutes(); + + for(Direction direction:directions) { + List routeToPositions = new ArrayList<>(); + currentX += direction.getX(); + currentY += direction.getY(); + while(Position.isInsideBoundary(currentX, currentY)) { + Position movePosition = new Position(currentX, currentY); + routeToPositions.add(movePosition); + + result.put(movePosition, new ArrayList<>(routeToPositions)); + + currentX += direction.getX(); + currentY += direction.getY(); + } + } + } + return result; + } } diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 23cf74ae8a..1eb2b2ad58 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -39,4 +39,12 @@ public PieceType getPieceType() { public Team getTeam() { return team; } + + public boolean isCha(){ + return pieceType == PieceType.CHA; + } + + public boolean isPo(){ + return pieceType ==PieceType.PO; + } } diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index b4b2500d15..9c0663bf01 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.jupiter.api.DisplayName; @@ -402,4 +403,92 @@ public class BoardTest { assertThat(maRoutesPositions).hasSize(8) .containsExactlyInAnyOrderElementsOf(rightAnswer); } + + @Test + @DisplayName("차의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 차_이동가능_좌표_확인_초기_위치에서_모두_다_가능() { + //given + Board board = new Board(); + Position position = new Position(1,10); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); + List upRoutes = List.of( + new Position(1, 9), new Position(1, 8), new Position(1, 7), + new Position(1, 6), new Position(1, 5), new Position(1, 4), + new Position(1, 3), new Position(1, 2), new Position(1, 1) + ); + + List rightRoutes = List.of( + new Position(2, 10), new Position(3, 10), new Position(4, 10), + new Position(5, 10), new Position(6, 10), new Position(7, 10), + new Position(8, 10), new Position(9, 10) + ); + List rightAnswer = new ArrayList<>(); + rightAnswer.addAll(upRoutes); + rightAnswer.addAll(rightRoutes); + + //when + List chaRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(chaRoutesPositions).hasSize(17) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("차의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 차_이동가능_좌표_확인_초기_위치에서_위쪽에_같은_팀() { + //given + Board board = new Board(); + Position position = new Position(1,10); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); + board.getBoard().put(new Position(1,7), new Piece(Team.CHO, PieceType.ZOL)); + List upRoutes = List.of( + new Position(1, 9), new Position(1,8) + ); + + List rightRoutes = List.of( + new Position(2, 10), new Position(3, 10), new Position(4, 10), + new Position(5, 10), new Position(6, 10), new Position(7, 10), + new Position(8, 10), new Position(9, 10) + ); + List rightAnswer = new ArrayList<>(); + rightAnswer.addAll(upRoutes); + rightAnswer.addAll(rightRoutes); + + //when + List chaRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(chaRoutesPositions).hasSize(10) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("차의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 차_이동가능_좌표_확인_초기_위치에서_위쪽에_다른_팀() { + //given + Board board = new Board(); + Position position = new Position(1,10); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); + board.getBoard().put(new Position(1,7), new Piece(Team.HAN, PieceType.CHA)); + List upRoutes = List.of( + new Position(1, 9), new Position(1, 8), new Position(1, 7) + ); + + List rightRoutes = List.of( + new Position(2, 10), new Position(3, 10), new Position(4, 10), + new Position(5, 10), new Position(6, 10), new Position(7, 10), + new Position(8, 10), new Position(9, 10) + ); + List rightAnswer = new ArrayList<>(); + rightAnswer.addAll(upRoutes); + rightAnswer.addAll(rightRoutes); + + //when + List chaRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(chaRoutesPositions).hasSize(11) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } } From adac323a7675a039c59f1403e0f972e3346a1809 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 13:45:31 +0900 Subject: [PATCH 14/30] =?UTF-8?q?feat:=20=ED=8F=AC=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EA=B0=80=EB=8A=A5=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=ED=8C=90=EB=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 44 ++++++++++++--- src/test/java/janggi/domain/BoardTest.java | 65 ++++++++++++++++++++++ 2 files changed, 101 insertions(+), 8 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index c5019056d0..d57b2d0d52 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -73,18 +73,29 @@ public List findAvailablePositions(Position position) { Piece destinationPiece = board.get(destination); List route = entry.getValue(); - if (hasObstacleOnRoute(route)) { - continue; - } + if(piece.getPieceType() == PieceType.PO) { + if(!hasOneObstacleAndNotPo(route)) { + continue; + } - if (board.containsKey(destination)) { - if (isDestinationIsMyTeam(destinationPiece, piece)) { + if(board.containsKey(destination)) { + if(isDestinationIsMyTeam(destinationPiece, piece) || isDestinationIsPo(destinationPiece)) { + continue; + } + } + availablePositions.add(destination); + } else { + if(hasObstacleOnRoute(route)) { continue; } + if(board.containsKey(destination)) { + if(isDestinationIsMyTeam(destinationPiece, piece)) { + continue; + } + } + availablePositions.add(destination); } - availablePositions.add(destination); } - return availablePositions; } @@ -104,7 +115,7 @@ private boolean hasObstacleOnRoute(List route) { private Map> convertToPositions(Position position, Piece piece, List routes) { Map> result = new HashMap<>(); - if(piece.isCha()) { + if(piece.isCha()|| piece.isPo()) { return convertToContinuousRoutes(position, routes, result); } @@ -159,4 +170,21 @@ private Map> convertToContinuousRoutes(Position positio } return result; } + + private boolean isDestinationIsPo(Piece destinationPiece) { + return destinationPiece.getPieceType() == PieceType.PO; + } + + private boolean hasOneObstacleAndNotPo(List route) { + int count = 0; + List obstacles = new ArrayList<>(); + // 마지막 경로는 목적지이므로 빼고 검사 + for(int i = 0; i < route.size() -1; i++) { + if(board.containsKey(route.get(i))) { + count+=1; + obstacles.add(board.get(route.get(i))); + } + } + return count == 1 && obstacles.getFirst().getPieceType() != PieceType.PO; + } } diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 9c0663bf01..bf30e949a8 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -491,4 +491,69 @@ public class BoardTest { assertThat(chaRoutesPositions).hasSize(11) .containsExactlyInAnyOrderElementsOf(rightAnswer); } + + @Test + @DisplayName("포의_위쪽경로에_포다리_존재") + void 포의_위쪽경로에_포다리_존재() { + //given + Board board = new Board(); + Position position = new Position(5,8); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); + board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.CHA)); + List upRoutes = List.of( + new Position(5, 5), new Position(5, 4), new Position(5, 3), + new Position(5, 2), new Position(5, 1) + ); + + List rightAnswer = new ArrayList<>(upRoutes); + + //when + List chaRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(chaRoutesPositions).hasSize(5) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("포의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 포의_위쪽경로에_포다리1개와_포가_붙어있음() { + //given + Board board = new Board(); + Position position = new Position(5,8); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); + board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(5,5), new Piece(Team.HAN, PieceType.PO)); + List upRoutes = List.of(); + + List rightAnswer = new ArrayList<>(upRoutes); + + //when + List chaRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(chaRoutesPositions).hasSize(0) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("포의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") + void 포의_위쪽경로에_포다리1개와_포가아닌_상대팀_기물_존재() { + //given + Board board = new Board(); + Position position = new Position(5,8); + board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); + board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(5,5), new Piece(Team.HAN, PieceType.ZOL)); + List upRoutes = List.of(new Position(5, 5)); + + List rightAnswer = new ArrayList<>(upRoutes); + + //when + List chaRoutesPositions = board.findAvailablePositions(position); + + //then + assertThat(chaRoutesPositions).hasSize(1) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } } From 08f4aad33bde19750dcf1745d6794675eb47d2af Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 14:22:36 +0900 Subject: [PATCH 15/30] =?UTF-8?q?test:=20DisplayName=EA=B3=BC=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/BoardTest.java | 88 +++++++++++----------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index bf30e949a8..e3a3dbdecb 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -33,8 +33,8 @@ public class BoardTest { "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4" }) - @DisplayName("초기 위치에 각나라 졸이 있다.") - void 초기_위치에_각나라_졸_세팅(Team team, PieceType pieceType, int x, int y){ + @DisplayName("초기화된 보드의 지정된 위치에 각 나라의 기물이 알맞게 배치되어 있다") + void 보드_초기화_기물_배치_확인(Team team, PieceType pieceType, int x, int y){ //given Board board = new Board(); board.initialize(); @@ -49,8 +49,8 @@ public class BoardTest { } @Test - @DisplayName("졸의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 졸_이동가능_좌표_확인_다_가능() { + @DisplayName("초나라 졸은 경로에 장애물이 없으면 위쪽, 왼쪽, 오른쪽으로 이동할 수 있다") + void 초나라_졸_장애물_없을때_이동_성공() { //given Board board = new Board(); Position position = new Position(5,7); @@ -68,8 +68,8 @@ public class BoardTest { } @Test - @DisplayName("졸의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 졸_이동가능_좌표_확인_위_불가능() { + @DisplayName("초나라 졸의 이동 방향에 아군 기물이 있으면 해당 방향으로는 이동할 수 없다") + void 초나라_졸_아군이_막고있을때_이동_불가() { //given Board board = new Board(); Position position = new Position(5,7); @@ -88,8 +88,8 @@ public class BoardTest { } @Test - @DisplayName("마의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 마_이동가능_좌표_확인_다_가능() { + @DisplayName("마는 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") + void 마_장애물_없을때_8방향_이동_성공() { //given Board board = new Board(); Position position = new Position(4,6); @@ -113,8 +113,8 @@ public class BoardTest { } @Test - @DisplayName("마의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 마_이동가능_좌표_확인_경로에_다른_기물() { + @DisplayName("마는 이동 경로(멱)에 다른 기물이 있으면 해당 방향으로 이동할 수 없다") + void 마_멱이_막혀있을때_해당_방향_이동_불가() { //given Board board = new Board(); Position position = new Position(4,6); @@ -137,8 +137,8 @@ public class BoardTest { } @Test - @DisplayName("마의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 마_이동가능_좌표_확인_목적지에_같은팀_기물() { + @DisplayName("마의 최종 목적지에 아군 기물이 있으면 해당 좌표로 이동할 수 없다") + void 마_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); Position position = new Position(4,6); @@ -162,8 +162,8 @@ public class BoardTest { } @Test - @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 상_이동가능_좌표_확인_다_가능() { + @DisplayName("상은 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") + void 상_장애물_없을때_8방향_이동_성공() { //given Board board = new Board(); Position position = new Position(5,7); @@ -187,8 +187,8 @@ public class BoardTest { } @Test - @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 상_이동가능_좌표_확인_경로에_다른_기물_대각선() { + @DisplayName("상은 대각선 경로(멱)에 다른 기물이 있으면 해당 방향으로 이동할 수 없다") + void 상_대각선_멱이_막혀있을때_이동_불가() { //given Board board = new Board(); Position position = new Position(5,7); @@ -212,8 +212,8 @@ public class BoardTest { } @Test - @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 상_이동가능_좌표_확인_경로에_다른_기물_직선() { + @DisplayName("상은 직선 경로(멱)에 다른 기물이 있으면 해당 방향으로 이동할 수 없다") + void 상_직선_멱이_막혀있을때_이동_불가() { //given Board board = new Board(); Position position = new Position(5,7); @@ -236,8 +236,8 @@ public class BoardTest { } @Test - @DisplayName("상의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 상_이동가능_좌표_확인_목적지에_같은팀_기물() { + @DisplayName("상의 최종 목적지에 아군 기물이 있으면 해당 좌표로 이동할 수 없다") + void 상_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); Position position = new Position(5,7); @@ -261,8 +261,8 @@ public class BoardTest { } @Test - @DisplayName("사의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") - void 사_이동가능_좌표_확인_초기_위치에서_모든_방향_가능() { + @DisplayName("사는 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)") + void 사_장애물_없을때_이동_성공() { //given Board board = new Board(); Position position = new Position(4,10); @@ -283,8 +283,8 @@ public class BoardTest { } @Test - @DisplayName("사의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") - void 사_이동가능_좌표_확인_초기_위치에서_목적지에_같은_팀() { + @DisplayName("사의 목적지에 아군 기물이 있으면 이동할 수 없다 (사이클1 규칙)") + void 사_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); Position position = new Position(4,10); @@ -305,8 +305,8 @@ public class BoardTest { } @Test - @DisplayName("사의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") - void 사_이동가능_좌표_확인_초기_위치에서_목적지에_다른_팀() { + @DisplayName("사의 목적지에 적군 기물이 있으면 이동할 수 있다 (사이클1 규칙)") + void 사_목적지에_적군_존재시_이동_가능() { //given Board board = new Board(); Position position = new Position(4,10); @@ -328,8 +328,8 @@ public class BoardTest { } @Test - @DisplayName("왕의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") - void 왕_이동가능_좌표_확인_초기_위치에서_모든_방향_가능() { + @DisplayName("왕은 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)" ) + void 왕_장애물_없을때_이동_성공() { //given Board board = new Board(); Position position = new Position(5,9); @@ -353,8 +353,8 @@ public class BoardTest { } @Test - @DisplayName("왕의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") - void 왕_이동가능_좌표_확인_초기_위치에서_목적지에_같은_팀() { + @DisplayName("왕의 이동하려는 목적지에 아군 기물이 있으면 이동할 수 없다(사이클1 규칙)") + void 왕_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); Position position = new Position(5,9); @@ -378,8 +378,8 @@ public class BoardTest { } @Test - @DisplayName("왕의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다(사이클1에서는 아직 궁성 영역 구현X)") - void 왕_이동가능_좌표_확인_초기_위치에서_목적지에_다른_팀() { + @DisplayName("왕의 목적지에 적군 기물이 있으면 이동할 수 있다 (사이클1 규칙)") + void 왕_목적있지에_적군_존재시_이동_가능() { //given Board board = new Board(); Position position = new Position(5,9); @@ -405,8 +405,8 @@ public class BoardTest { } @Test - @DisplayName("차의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 차_이동가능_좌표_확인_초기_위치에서_모두_다_가능() { + @DisplayName("차는 직선 경로상에 장애물이 없으면 끝까지 이동할 수 있다") + void 차_장애물_없을때_직선_끝까지_이동_성공() { //given Board board = new Board(); Position position = new Position(1,10); @@ -435,8 +435,8 @@ public class BoardTest { } @Test - @DisplayName("차의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 차_이동가능_좌표_확인_초기_위치에서_위쪽에_같은_팀() { + @DisplayName("차는 직선 경로상에 아군 기물이 있으면 아군 기물 직전까지만 이동할 수 있다") + void 차_경로에_아군_존재시_아군_직전까지_이동_가능() { //given Board board = new Board(); Position position = new Position(1,10); @@ -464,8 +464,8 @@ public class BoardTest { } @Test - @DisplayName("차의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 차_이동가능_좌표_확인_초기_위치에서_위쪽에_다른_팀() { + @DisplayName("차는 직선 경로상에 적군 기물이 있으면 포획할 수 있는 적군 기물 위치까지만 이동할 수 있다") + void 차_경로에_적군_존재시_적군_위치까지_이동_가능() { //given Board board = new Board(); Position position = new Position(1,10); @@ -493,8 +493,8 @@ public class BoardTest { } @Test - @DisplayName("포의_위쪽경로에_포다리_존재") - void 포의_위쪽경로에_포다리_존재() { + @DisplayName("포는 이동 경로상에 일반 기물(포다리)이 딱 1개 존재하면 그 너머로 이동할 수 있다") + void 포_경로에_일반_기물_포다리가_1개_있을때_이동_성공() { //given Board board = new Board(); Position position = new Position(5,8); @@ -516,8 +516,8 @@ public class BoardTest { } @Test - @DisplayName("포의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 포의_위쪽경로에_포다리1개와_포가_붙어있음() { + @DisplayName("포는 넘어가려는 목적지에 또 다른 포가 있으면, 포는 포를 포획할 수 없으므로 이동할 수 없다") + void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { //given Board board = new Board(); Position position = new Position(5,8); @@ -537,8 +537,8 @@ public class BoardTest { } @Test - @DisplayName("포의 이동규칙을 통해 갈 수 있는 경로의 위치를 알아낼 수 있다") - void 포의_위쪽경로에_포다리1개와_포가아닌_상대팀_기물_존재() { + @DisplayName("포는 포다리 너머에 일반 적군 기물이 존재하면 해당 기물을 포획하며 이동할 수 있다") + void 포_목적지에_일반_적군_기물이_있을때_이동_성공() { //given Board board = new Board(); Position position = new Position(5,8); From f7f0f3eb8478faa871069d94ff3f72a970c6ecb1 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 14:52:27 +0900 Subject: [PATCH 16/30] =?UTF-8?q?feat:=20=EB=B7=B0=EC=99=80=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- src/main/java/janggi/Application.java | 10 ++ .../janggi/controller/JanggiController.java | 39 ++++++++ src/main/java/janggi/domain/Board.java | 7 +- src/main/java/janggi/view/InputView.java | 16 ++++ src/main/java/janggi/view/OutputView.java | 96 +++++++++++++++++++ 6 files changed, 169 insertions(+), 3 deletions(-) create mode 100644 src/main/java/janggi/Application.java create mode 100644 src/main/java/janggi/controller/JanggiController.java create mode 100644 src/main/java/janggi/view/InputView.java create mode 100644 src/main/java/janggi/view/OutputView.java diff --git a/README.md b/README.md index 72a47ec60f..053acf52cf 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,12 @@ version : 1.2 (구현의 어려움에 따른 도메인 변경 : 돌아가는 코 - **보드** - [x] 상차림은 마상마상으로 고정하여 초기화 한다. (추후 추가 예정) - - [ ] 해당 기물의 이동 가능 여부를 판단한다 + - [x] 해당 기물의 이동 가능 여부를 판단한다 - 멱에 다른 기물이 있으면 안 되는 경우: 마,상, 졸/병, 차, 장, 사 - 멱 사이에 하나의 기물이 있어야 하는 경우: 포 - 그 기물이 포여서는 안 된다. - 이동하고자 하는 좌표 자체가 포 or 아군이면 안 된다. - - [ ] 기물을 이동시킨다. + - [x] 기물을 이동시킨다. - **좌표** - [x] 보드 내의 좌표 범위를 검증한다. - **기물** diff --git a/src/main/java/janggi/Application.java b/src/main/java/janggi/Application.java new file mode 100644 index 0000000000..59fa0394a5 --- /dev/null +++ b/src/main/java/janggi/Application.java @@ -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(); + } +} diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java new file mode 100644 index 0000000000..c596d80fea --- /dev/null +++ b/src/main/java/janggi/controller/JanggiController.java @@ -0,0 +1,39 @@ +package janggi.controller; + +import janggi.domain.Board; +import janggi.domain.Position; +import janggi.view.InputView; +import janggi.view.OutputView; +import java.util.List; + +public class JanggiController { + private final InputView inputView = new InputView(); + private final OutputView outputView = new OutputView(); + + public void run() { + Board board = new Board(); + board.initialize(); + boolean isChoTurn = true; + + outputView.printBoard(board.getBoard()); + + while(true) { + outputView.printTurnMessage(isChoTurn); + + outputView.printMoveInfo(); + Position movePiecePosition = inputView.readPosition(); + + List availablePositions = board.findAvailablePositions(movePiecePosition); + outputView.printAvailablePositions(board.getBoard(), availablePositions); + + outputView.printMoveChoiceInfo(); + Position movePosition = inputView.readPosition(); + + board.movePiece(movePiecePosition, movePosition); + + outputView.printBoard(board.getBoard()); + + isChoTurn = !isChoTurn; + } + } +} diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index d57b2d0d52..d422609945 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -178,7 +178,6 @@ private boolean isDestinationIsPo(Piece destinationPiece) { private boolean hasOneObstacleAndNotPo(List route) { int count = 0; List obstacles = new ArrayList<>(); - // 마지막 경로는 목적지이므로 빼고 검사 for(int i = 0; i < route.size() -1; i++) { if(board.containsKey(route.get(i))) { count+=1; @@ -187,4 +186,10 @@ private boolean hasOneObstacleAndNotPo(List route) { } return count == 1 && obstacles.getFirst().getPieceType() != PieceType.PO; } + + public void movePiece(Position movePiecePosition, Position movePosition) { + Piece piece = board.get(movePiecePosition); + board.remove(movePiecePosition); + board.put(movePosition, piece); + } } diff --git a/src/main/java/janggi/view/InputView.java b/src/main/java/janggi/view/InputView.java new file mode 100644 index 0000000000..52f67e5ef6 --- /dev/null +++ b/src/main/java/janggi/view/InputView.java @@ -0,0 +1,16 @@ +package janggi.view; + +import janggi.domain.Position; +import java.util.Scanner; + +public class InputView { + private final Scanner scanner = new Scanner(System.in); + + public Position readPosition() { + System.out.println("예시: 1 7 "); + String input = scanner.nextLine(); + + String[] position = input.split(" "); + return new Position(Integer.parseInt(position[0]), Integer.parseInt(position[1])); + } +} diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java new file mode 100644 index 0000000000..cfdc4a1839 --- /dev/null +++ b/src/main/java/janggi/view/OutputView.java @@ -0,0 +1,96 @@ +package janggi.view; + +import janggi.domain.Piece; +import janggi.domain.Position; +import janggi.domain.Team; +import java.util.List; +import java.util.Map; + +public class OutputView { + + public static final String HAN_COLOR = "\u001B[31m"; + public static final String CHO_COLOR = "\u001B[34m"; + public static final String AVAILABLE_COLOR = "\u001B[32m"; + public static final String RESET = "\u001B[0m"; + private static final String[] X_VALUES = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; + + public void printBoard(Map board) { + System.out.print(" "); + for (int x = 1; x <= 9; x++) { + System.out.print(X_VALUES[x - 1] + " "); + } + System.out.println(); + + for (int y = 1; y <= 10; y++) { + System.out.print(String.format("%2d ", y)); + + for (int x = 1; x <= 9; x++) { + Position currentPos = new Position(x, y); + if (board.containsKey(currentPos)) { + Piece piece = board.get(currentPos); + String color = getColorByTeam(piece); + + System.out.print(color + piece.getPieceTypeName() + RESET + " "); + } else { + System.out.print(". "); + } + } + System.out.println(); + } + } + + public void printAvailablePositions(Map board, List availablePositions) { + System.out.print(" "); + for (int x = 1; x <= 9; x++) { + System.out.print(X_VALUES[x - 1] + " "); + } + System.out.println(); + + for (int y = 1; y <= 10; y++) { + System.out.print(String.format("%2d ", y)); + + for (int x = 1; x <= 9; x++) { + Position currentPos = new Position(x, y); + + if (availablePositions.contains(currentPos)) { + if (board.containsKey(currentPos)) { + System.out.print(AVAILABLE_COLOR + board.get(currentPos).getPieceTypeName() + RESET + " "); + } else { + System.out.print(AVAILABLE_COLOR + "O" + RESET + " "); + } + continue; + } + + if (board.containsKey(currentPos)) { + Piece piece = board.get(currentPos); + String color = getColorByTeam(piece); + System.out.print(color + piece.getPieceTypeName() + RESET + " "); + } else { + System.out.print(". "); + } + } + System.out.println(); + } + } + + private String getColorByTeam(Piece piece) { + if(piece.getTeam() == Team.CHO) return CHO_COLOR; + return HAN_COLOR; + } + + public void printTurnMessage(boolean isChoTurn) { + if(isChoTurn) { + System.out.println(OutputView.CHO_COLOR + "\n현재 초나라 차례입니다" + OutputView.RESET); + } else { + System.out.println(OutputView.HAN_COLOR + "\n한나라 차례입니다" + OutputView.RESET); + } + } + + public void printMoveInfo() { + System.out.println("이동하고 싶은 기물의 좌표를 입력하세요."); + } + + public void printMoveChoiceInfo() { + System.out.println("이동하고자 하는 목표 지점의 좌표를 입력하세요."); + } +} From 61a69038ff1868549d4c20c6e868147921c3b389 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 16:06:32 +0900 Subject: [PATCH 17/30] =?UTF-8?q?feat:=20=EC=9E=AC=EC=9E=85=EB=A0=A5=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../janggi/controller/JanggiController.java | 30 +++++++++++++++---- src/main/java/janggi/domain/Board.java | 23 ++++++++++++-- src/main/java/janggi/view/OutputView.java | 4 +++ 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index c596d80fea..a6a2260d89 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -5,6 +5,7 @@ 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(); @@ -20,14 +21,23 @@ public void run() { while(true) { outputView.printTurnMessage(isChoTurn); - outputView.printMoveInfo(); - Position movePiecePosition = inputView.readPosition(); + Position movePiecePosition = doLoop(() -> { + outputView.printMoveInfo(); + Position position = inputView.readPosition(); + board.findAvailablePositions(position); + return position; + }); + + List availablePositions = board.findAvailablePositions(movePiecePosition); - List availablePositions = board.findAvailablePositions(movePiecePosition); outputView.printAvailablePositions(board.getBoard(), availablePositions); - outputView.printMoveChoiceInfo(); - Position movePosition = inputView.readPosition(); + Position movePosition = doLoop(()->{ + outputView.printMoveChoiceInfo(); + Position position = inputView.readPosition(); + board.validateDestination(movePiecePosition, position); + return position; + }); board.movePiece(movePiecePosition, movePosition); @@ -36,4 +46,14 @@ public void run() { isChoTurn = !isChoTurn; } } + + private T doLoop(Supplier inputFunction) { + while (true) { + try { + return inputFunction.get(); + } catch (IllegalArgumentException e) { + OutputView.printErrorMessage(e.getMessage()); + } + } + } } diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index d422609945..a81b0a6a44 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -96,6 +96,10 @@ public List findAvailablePositions(Position position) { availablePositions.add(destination); } } + + if(availablePositions.isEmpty()) { + throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); + } return availablePositions; } @@ -187,9 +191,24 @@ private boolean hasOneObstacleAndNotPo(List route) { return count == 1 && obstacles.getFirst().getPieceType() != PieceType.PO; } - public void movePiece(Position movePiecePosition, Position movePosition) { + public void movePiece(Position movePiecePosition, Position destination) { Piece piece = board.get(movePiecePosition); board.remove(movePiecePosition); - board.put(movePosition, piece); + board.put(destination, piece); + } + + public void validateDestination(Position movePiecePosition, Position destination) { + List availablePositions = findAvailablePositions(movePiecePosition); + boolean hasPosition = false; + for(Position position:availablePositions) { + if (position == destination) { + hasPosition = true; + break; + } + } + + if(!hasPosition) { + throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); + } } } diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index cfdc4a1839..8d26cc8376 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -14,6 +14,10 @@ public class OutputView { public static final String RESET = "\u001B[0m"; private static final String[] X_VALUES = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; + public static void printErrorMessage(String message) { + System.out.printf("%s%n", message); + } + public void printBoard(Map board) { System.out.print(" "); for (int x = 1; x <= 9; x++) { From 3ed382f27aed9482f082c5f238c5d62e8c899c9f Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Mon, 30 Mar 2026 16:19:26 +0900 Subject: [PATCH 18/30] =?UTF-8?q?refactor:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../janggi/controller/JanggiController.java | 7 ++-- src/main/java/janggi/domain/Direction.java | 12 ++----- src/main/java/janggi/domain/MoveRule.java | 1 - src/main/java/janggi/domain/Piece.java | 34 ++++++++++--------- src/main/java/janggi/domain/PieceType.java | 16 ++++----- src/main/java/janggi/domain/Position.java | 26 ++++++++------ .../domain/moveRules/ChaMoveRuleTest.java | 3 +- .../domain/moveRules/KingMoveRuleTest.java | 2 +- .../domain/moveRules/MaMoveRuleTest.java | 12 +++---- .../domain/moveRules/SaMoveRuleTest.java | 2 +- 10 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index a6a2260d89..56a4105d74 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -8,6 +8,7 @@ import java.util.function.Supplier; public class JanggiController { + private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); @@ -18,7 +19,7 @@ public void run() { outputView.printBoard(board.getBoard()); - while(true) { + while (true) { outputView.printTurnMessage(isChoTurn); Position movePiecePosition = doLoop(() -> { @@ -28,11 +29,11 @@ public void run() { return position; }); - List availablePositions = board.findAvailablePositions(movePiecePosition); + List availablePositions = board.findAvailablePositions(movePiecePosition); outputView.printAvailablePositions(board.getBoard(), availablePositions); - Position movePosition = doLoop(()->{ + Position movePosition = doLoop(() -> { outputView.printMoveChoiceInfo(); Position position = inputView.readPosition(); board.validateDestination(movePiecePosition, position); diff --git a/src/main/java/janggi/domain/Direction.java b/src/main/java/janggi/domain/Direction.java index 6b942ff3fa..4e08a73f13 100644 --- a/src/main/java/janggi/domain/Direction.java +++ b/src/main/java/janggi/domain/Direction.java @@ -1,15 +1,8 @@ package janggi.domain; 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); + 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; @@ -19,7 +12,6 @@ public enum Direction { this.y = y; } - public int getX() { return x; } diff --git a/src/main/java/janggi/domain/MoveRule.java b/src/main/java/janggi/domain/MoveRule.java index 5cd9aaee3f..3337cf6c6e 100644 --- a/src/main/java/janggi/domain/MoveRule.java +++ b/src/main/java/janggi/domain/MoveRule.java @@ -3,6 +3,5 @@ import java.util.List; public interface MoveRule { - List findRoutes(Team team); } diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 1eb2b2ad58..19175436d5 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -3,6 +3,7 @@ import java.util.Objects; public class Piece { + private final Team team; private final PieceType pieceType; @@ -15,22 +16,10 @@ public String getTeamName() { return team.getName(); } - public String getPieceTypeName(){ + public String getPieceTypeName() { return pieceType.getName(); } - @Override - public boolean equals(Object o) { - if (!(o instanceof Piece piece)) { - return false; - } - return team == piece.team && pieceType == piece.pieceType; - } - - @Override - public int hashCode() { - return Objects.hash(team, pieceType); - } public PieceType getPieceType() { return pieceType; @@ -40,11 +29,24 @@ public Team getTeam() { return team; } - public boolean isCha(){ + public boolean isCha() { return pieceType == PieceType.CHA; } - public boolean isPo(){ - return pieceType ==PieceType.PO; + public boolean isPo() { + return pieceType == PieceType.PO; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof Piece piece)) { + return false; + } + return team == piece.team && pieceType == piece.pieceType; + } + + @Override + public int hashCode() { + return Objects.hash(team, pieceType); } } diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index 92c8f3a1a1..7f06f17886 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -10,13 +10,13 @@ import java.util.List; public enum PieceType { - KING("왕", List.of(5),9, new KingMoveRule()), - SA("사",List.of(4,6),10, new SaMoveRule()), - SANG("상",List.of(3,7),10, new SangMoveRule()), - MA("마",List.of(2,8),10, new MaMoveRule()), - CHA("차",List.of(1,9),10, new ChaMoveRule()), - PO("포",List.of(2,8),8, new PoMoveRule()), - ZOL("졸",List.of(1,3,5,7,9),7, new ZolMoveRule()); + KING("왕", List.of(5), 9, new KingMoveRule()), + SA("사", List.of(4, 6), 10, new SaMoveRule()), + SANG("상", List.of(3, 7), 10, new SangMoveRule()), + MA("마", List.of(2, 8), 10, new MaMoveRule()), + CHA("차", List.of(1, 9), 10, new ChaMoveRule()), + PO("포", List.of(2, 8), 8, new PoMoveRule()), + ZOL("졸", List.of(1, 3, 5, 7, 9), 7, new ZolMoveRule()); private final String name; private final List xPositions; @@ -30,7 +30,7 @@ public enum PieceType { this.moveRule = moveRule; } - public String getName(){ + public String getName() { return name; } diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java index dda5d90a70..539efcacc3 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/Position.java @@ -3,6 +3,11 @@ import java.util.Objects; public class Position { + + private static final int MIN_X = 1; + private static final int MAX_X = 9; + private static final int MIN_Y = 1; + private static final int MAX_Y = 10; private final int x; private final int y; @@ -13,14 +18,21 @@ public Position(int x, int y) { } private void validateBoundary(int x, int y) { - if(x < 1 || x > 9 || y < 1 || y > 10) { + if (x < MIN_X || x > MAX_X || y < MIN_Y || y > MAX_Y) { throw new IllegalArgumentException("[ERROR] 보드 범위를 벗어났습니다."); } } - public static boolean isInsideBoundary(int x, int y) { - return x >= 1 && x <= 9 && y >= 1 && y <= 10; + return x >= MIN_X && x <= MAX_X && y >= MIN_Y && y <= MAX_Y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; } @Override @@ -35,12 +47,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(x, y); } - - public int getX() { - return x; - } - - public int getY() { - return y; - } } diff --git a/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java index 6f88af11cd..5c52f61be0 100644 --- a/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java @@ -14,7 +14,7 @@ class ChaMoveRuleTest { @Test @DisplayName("차는 직선으로 갈 수 있다") - void 차의_이동규칙(){ + void 차의_이동규칙() { //given MoveRule moveRule = new ChaMoveRule(); Team team = Team.CHO; @@ -30,5 +30,4 @@ class ChaMoveRuleTest { //then assertThat(chaRoutes).isEqualTo(routes); } - } diff --git a/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java index 60a8d48fc9..eac266c091 100644 --- a/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java @@ -14,7 +14,7 @@ public class KingMoveRuleTest { @Test @DisplayName("왕은 직선과 대각선으로 갈 수 있다.") - void 왕의_이동규칙(){ + void 왕의_이동규칙() { //given MoveRule moveRule = new KingMoveRule(); Team team = Team.CHO; diff --git a/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java index e0925db4f2..4564af4dd4 100644 --- a/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java @@ -4,8 +4,6 @@ import janggi.domain.Direction; import janggi.domain.MoveRule; -import janggi.domain.Piece; -import janggi.domain.PieceType; import janggi.domain.Route; import janggi.domain.Team; import java.util.List; @@ -21,15 +19,15 @@ public class MaMoveRuleTest { MoveRule moveRule = new MaMoveRule(); Team team = Team.HAN; Route route1 = new Route(List.of(Direction.UP, Direction.UP_LEFT)); - Route route2 = new Route( List.of(Direction.UP, Direction.UP_RIGHT)); + Route route2 = new Route(List.of(Direction.UP, Direction.UP_RIGHT)); Route route3 = new Route(List.of(Direction.RIGHT, Direction.UP_RIGHT)); Route route4 = new Route(List.of(Direction.RIGHT, Direction.DOWN_RIGHT)); Route route5 = new Route(List.of(Direction.DOWN, Direction.DOWN_RIGHT)); - Route route6 = new Route( List.of(Direction.DOWN, Direction.DOWN_LEFT)); - Route route7 = new Route( List.of(Direction.LEFT, Direction.DOWN_LEFT)); - Route route8 = new Route( List.of(Direction.LEFT, Direction.UP_LEFT)); + Route route6 = new Route(List.of(Direction.DOWN, Direction.DOWN_LEFT)); + Route route7 = new Route(List.of(Direction.LEFT, Direction.DOWN_LEFT)); + Route route8 = new Route(List.of(Direction.LEFT, Direction.UP_LEFT)); - List routes = List.of(route1,route2,route3,route4,route5,route6,route7,route8); + List routes = List.of(route1, route2, route3, route4, route5, route6, route7, route8); //when List maRoutes = moveRule.findRoutes(team); diff --git a/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java index 148ddf9421..8250d074eb 100644 --- a/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java @@ -14,7 +14,7 @@ public class SaMoveRuleTest { @Test @DisplayName("사는 직선과 대각선으로 갈 수 있다") - void 사의_이동규칙(){ + void 사의_이동규칙() { //given MoveRule moveRule = new SaMoveRule(); Team team = Team.CHO; From 6f2249e35317320fc7d8e2958d1826423a6f4e47 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Tue, 31 Mar 2026 17:07:17 +0900 Subject: [PATCH 19/30] =?UTF-8?q?test(BoardTest):=20=ED=8F=AC=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EB=B6=88=EA=B0=80=20=EC=8B=9C=20=EB=B0=9C=EC=83=9D?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=98=88=EC=99=B8=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/BoardTest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index e3a3dbdecb..3730bd2531 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -528,12 +528,10 @@ public class BoardTest { List rightAnswer = new ArrayList<>(upRoutes); - //when - List chaRoutesPositions = board.findAvailablePositions(position); - - //then - assertThat(chaRoutesPositions).hasSize(0) - .containsExactlyInAnyOrderElementsOf(rightAnswer); + //when & then + assertThatThrownBy(() -> board.findAvailablePositions(position)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("[ERROR] 이동할 수 없는 좌표입니다."); } @Test From 2e77c2414dc05e9760122a3b1659a03a5a94d17e Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Tue, 31 Mar 2026 17:09:22 +0900 Subject: [PATCH 20/30] =?UTF-8?q?style(BoardTest):=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8F=AC=EB=A7=A4=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/BoardTest.java | 124 ++++++++++----------- 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 3730bd2531..167528cf59 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -1,6 +1,7 @@ package janggi.domain; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.ArrayList; import java.util.List; @@ -17,29 +18,29 @@ public class BoardTest { @CsvSource({ "CHO,KING,5,9", - "CHO,SA,4,10","CHO,SA,6,10", - "CHO,SANG,3,10","CHO,SANG,8,10", - "CHO,MA,2,10","CHO,MA,7,10", - "CHO,CHA,1,10","CHO,CHA,9,10", - "CHO,PO,2,8","CHO,PO,8,8", + "CHO,SA,4,10", "CHO,SA,6,10", + "CHO,SANG,3,10", "CHO,SANG,8,10", + "CHO,MA,2,10", "CHO,MA,7,10", + "CHO,CHA,1,10", "CHO,CHA,9,10", + "CHO,PO,2,8", "CHO,PO,8,8", "CHO,ZOL,1,7", "CHO,ZOL,3,7", "CHO,ZOL,5,7", "CHO,ZOL,7,7", "CHO,ZOL,9,7", "HAN,KING,5,2", - "HAN,SA,4,1","HAN,SA,6,1", - "HAN,SANG,3,1","HAN,SANG,8,1", - "HAN,MA,2,1","HAN,MA,7,1", - "HAN,CHA,1,1","HAN,CHA,9,1", - "HAN,PO,2,3","HAN,PO,8,3", + "HAN,SA,4,1", "HAN,SA,6,1", + "HAN,SANG,3,1", "HAN,SANG,8,1", + "HAN,MA,2,1", "HAN,MA,7,1", + "HAN,CHA,1,1", "HAN,CHA,9,1", + "HAN,PO,2,3", "HAN,PO,8,3", "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4" }) @DisplayName("초기화된 보드의 지정된 위치에 각 나라의 기물이 알맞게 배치되어 있다") - void 보드_초기화_기물_배치_확인(Team team, PieceType pieceType, int x, int y){ + void 보드_초기화_기물_배치_확인(Team team, PieceType pieceType, int x, int y) { //given Board board = new Board(); board.initialize(); - Position position = new Position(x,y); - Piece zol = new Piece(team,pieceType); + Position position = new Position(x, y); + Piece zol = new Piece(team, pieceType); //when Map checkZol = board.getBoard(); @@ -53,7 +54,7 @@ public class BoardTest { void 초나라_졸_장애물_없을때_이동_성공() { //given Board board = new Board(); - Position position = new Position(5,7); + Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); Position zolUp = new Position(5, 6); Position zolLeft = new Position(4, 7); @@ -72,7 +73,7 @@ public class BoardTest { void 초나라_졸_아군이_막고있을때_이동_불가() { //given Board board = new Board(); - Position position = new Position(5,7); + Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); Position zolUp = new Position(5, 6); board.getBoard().put(zolUp, new Piece(Team.CHO, PieceType.ZOL)); @@ -92,7 +93,7 @@ public class BoardTest { void 마_장애물_없을때_8방향_이동_성공() { //given Board board = new Board(); - Position position = new Position(4,6); + Position position = new Position(4, 6); board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); Position maPos1 = new Position(3, 4); Position maPos2 = new Position(5, 4); @@ -100,8 +101,8 @@ public class BoardTest { Position maPos4 = new Position(6, 7); Position maPos5 = new Position(3, 8); Position maPos6 = new Position(5, 8); - Position maPos7 = new Position(2,5); - Position maPos8 = new Position(2,7); + Position maPos7 = new Position(2, 5); + Position maPos8 = new Position(2, 7); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7, maPos8); //when @@ -117,15 +118,15 @@ public class BoardTest { void 마_멱이_막혀있을때_해당_방향_이동_불가() { //given Board board = new Board(); - Position position = new Position(4,6); + Position position = new Position(4, 6); board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); - board.getBoard().put(new Position(4,5), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(4, 5), new Piece(Team.HAN, PieceType.CHA)); Position maPos1 = new Position(6, 5); Position maPos2 = new Position(6, 7); Position maPos3 = new Position(3, 8); Position maPos4 = new Position(5, 8); - Position maPos5 = new Position(2,5); - Position maPos6 = new Position(2,7); + Position maPos5 = new Position(2, 5); + Position maPos6 = new Position(2, 7); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6); //when @@ -141,16 +142,16 @@ public class BoardTest { void 마_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); - Position position = new Position(4,6); + Position position = new Position(4, 6); board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); - board.getBoard().put(new Position(2,7), new Piece(Team.CHO, PieceType.CHA)); + board.getBoard().put(new Position(2, 7), new Piece(Team.CHO, PieceType.CHA)); Position maPos1 = new Position(3, 4); Position maPos2 = new Position(5, 4); Position maPos3 = new Position(6, 5); Position maPos4 = new Position(6, 7); Position maPos5 = new Position(3, 8); Position maPos6 = new Position(5, 8); - Position maPos7 = new Position(2,5); + Position maPos7 = new Position(2, 5); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7); //when @@ -166,7 +167,7 @@ public class BoardTest { void 상_장애물_없을때_8방향_이동_성공() { //given Board board = new Board(); - Position position = new Position(5,7); + Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); Position maPos1 = new Position(3, 4); Position maPos2 = new Position(7, 4); @@ -174,8 +175,8 @@ public class BoardTest { Position maPos4 = new Position(8, 9); Position maPos5 = new Position(3, 10); Position maPos6 = new Position(7, 10); - Position maPos7 = new Position(2,5); - Position maPos8 = new Position(2,9); + Position maPos7 = new Position(2, 5); + Position maPos8 = new Position(2, 9); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7, maPos8); //when @@ -191,16 +192,16 @@ public class BoardTest { void 상_대각선_멱이_막혀있을때_이동_불가() { //given Board board = new Board(); - Position position = new Position(5,7); + Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); - board.getBoard().put(new Position(6,5), new Piece(Team.CHO, PieceType.ZOL)); + board.getBoard().put(new Position(6, 5), new Piece(Team.CHO, PieceType.ZOL)); Position maPos1 = new Position(3, 4); Position maPos2 = new Position(8, 5); Position maPos3 = new Position(8, 9); Position maPos4 = new Position(3, 10); Position maPos5 = new Position(7, 10); - Position maPos6 = new Position(2,5); - Position maPos7 = new Position(2,9); + Position maPos6 = new Position(2, 5); + Position maPos7 = new Position(2, 9); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7); //when @@ -216,15 +217,15 @@ public class BoardTest { void 상_직선_멱이_막혀있을때_이동_불가() { //given Board board = new Board(); - Position position = new Position(5,7); + Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); - board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.ZOL)); + board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.ZOL)); Position maPos1 = new Position(8, 5); Position maPos2 = new Position(8, 9); Position maPos3 = new Position(3, 10); Position maPos4 = new Position(7, 10); - Position maPos5 = new Position(2,5); - Position maPos6 = new Position(2,9); + Position maPos5 = new Position(2, 5); + Position maPos6 = new Position(2, 9); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6); //when @@ -240,16 +241,16 @@ public class BoardTest { void 상_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); - Position position = new Position(5,7); + Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); - board.getBoard().put(new Position(2,9), new Piece(Team.CHO, PieceType.ZOL)); + board.getBoard().put(new Position(2, 9), new Piece(Team.CHO, PieceType.ZOL)); Position maPos1 = new Position(3, 4); Position maPos2 = new Position(7, 4); Position maPos3 = new Position(8, 5); Position maPos4 = new Position(8, 9); Position maPos5 = new Position(3, 10); Position maPos6 = new Position(7, 10); - Position maPos7 = new Position(2,5); + Position maPos7 = new Position(2, 5); List rightAnswer = List.of(maPos1, maPos2, maPos3, maPos4, maPos5, maPos6, maPos7); //when @@ -265,7 +266,7 @@ public class BoardTest { void 사_장애물_없을때_이동_성공() { //given Board board = new Board(); - Position position = new Position(4,10); + Position position = new Position(4, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); Position maPos1 = new Position(4, 9); Position maPos2 = new Position(5, 9); @@ -287,7 +288,7 @@ public class BoardTest { void 사_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); - Position position = new Position(4,10); + Position position = new Position(4, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); board.getBoard().put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); Position maPos1 = new Position(4, 9); @@ -309,7 +310,7 @@ public class BoardTest { void 사_목적지에_적군_존재시_이동_가능() { //given Board board = new Board(); - Position position = new Position(4,10); + Position position = new Position(4, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); board.getBoard().put(new Position(5, 9), new Piece(Team.HAN, PieceType.CHA)); Position maPos1 = new Position(4, 9); @@ -328,11 +329,11 @@ public class BoardTest { } @Test - @DisplayName("왕은 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)" ) + @DisplayName("왕은 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)") void 왕_장애물_없을때_이동_성공() { //given Board board = new Board(); - Position position = new Position(5,9); + Position position = new Position(5, 9); board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); Position maPos1 = new Position(4, 8); Position maPos2 = new Position(5, 8); @@ -357,7 +358,7 @@ public class BoardTest { void 왕_목적지에_아군_존재시_이동_불가() { //given Board board = new Board(); - Position position = new Position(5,9); + Position position = new Position(5, 9); board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); board.getBoard().put(new Position(4, 9), new Piece(Team.CHO, PieceType.SA)); board.getBoard().put(new Position(4, 10), new Piece(Team.CHO, PieceType.SA)); @@ -382,7 +383,7 @@ public class BoardTest { void 왕_목적있지에_적군_존재시_이동_가능() { //given Board board = new Board(); - Position position = new Position(5,9); + Position position = new Position(5, 9); board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); board.getBoard().put(new Position(4, 9), new Piece(Team.HAN, PieceType.ZOL)); board.getBoard().put(new Position(4, 10), new Piece(Team.HAN, PieceType.CHA)); @@ -409,7 +410,7 @@ public class BoardTest { void 차_장애물_없을때_직선_끝까지_이동_성공() { //given Board board = new Board(); - Position position = new Position(1,10); + Position position = new Position(1, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); List upRoutes = List.of( new Position(1, 9), new Position(1, 8), new Position(1, 7), @@ -439,11 +440,11 @@ public class BoardTest { void 차_경로에_아군_존재시_아군_직전까지_이동_가능() { //given Board board = new Board(); - Position position = new Position(1,10); + Position position = new Position(1, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); - board.getBoard().put(new Position(1,7), new Piece(Team.CHO, PieceType.ZOL)); + board.getBoard().put(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); List upRoutes = List.of( - new Position(1, 9), new Position(1,8) + new Position(1, 9), new Position(1, 8) ); List rightRoutes = List.of( @@ -468,9 +469,9 @@ public class BoardTest { void 차_경로에_적군_존재시_적군_위치까지_이동_가능() { //given Board board = new Board(); - Position position = new Position(1,10); + Position position = new Position(1, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); - board.getBoard().put(new Position(1,7), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(1, 7), new Piece(Team.HAN, PieceType.CHA)); List upRoutes = List.of( new Position(1, 9), new Position(1, 8), new Position(1, 7) ); @@ -497,9 +498,9 @@ public class BoardTest { void 포_경로에_일반_기물_포다리가_1개_있을때_이동_성공() { //given Board board = new Board(); - Position position = new Position(5,8); + Position position = new Position(5, 8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); - board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); List upRoutes = List.of( new Position(5, 5), new Position(5, 4), new Position(5, 3), new Position(5, 2), new Position(5, 1) @@ -520,13 +521,10 @@ public class BoardTest { void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { //given Board board = new Board(); - Position position = new Position(5,8); + Position position = new Position(5, 8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); - board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.CHA)); - board.getBoard().put(new Position(5,5), new Piece(Team.HAN, PieceType.PO)); - List upRoutes = List.of(); - - List rightAnswer = new ArrayList<>(upRoutes); + board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(5, 5), new Piece(Team.HAN, PieceType.PO)); //when & then assertThatThrownBy(() -> board.findAvailablePositions(position)) @@ -539,10 +537,10 @@ public class BoardTest { void 포_목적지에_일반_적군_기물이_있을때_이동_성공() { //given Board board = new Board(); - Position position = new Position(5,8); + Position position = new Position(5, 8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); - board.getBoard().put(new Position(5,6), new Piece(Team.HAN, PieceType.CHA)); - board.getBoard().put(new Position(5,5), new Piece(Team.HAN, PieceType.ZOL)); + board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); + board.getBoard().put(new Position(5, 5), new Piece(Team.HAN, PieceType.ZOL)); List upRoutes = List.of(new Position(5, 5)); List rightAnswer = new ArrayList<>(upRoutes); From e0ab7619fdcd7839a3bfaba0966938bc9df004e2 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Tue, 31 Mar 2026 17:32:48 +0900 Subject: [PATCH 21/30] =?UTF-8?q?refactor:=20=EC=B1=85=EC=9E=84=EA=B3=BC?= =?UTF-8?q?=20=EC=84=B1=EA=B2=A9=EC=97=90=20=EB=A7=9E=EA=B2=8C=20JanggiCon?= =?UTF-8?q?troller=20->=20JanggiGame=20=EC=9C=BC=EB=A1=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/Application.java | 6 +++--- .../controller/{JanggiController.java => JanggiGame.java} | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/janggi/controller/{JanggiController.java => JanggiGame.java} (98%) diff --git a/src/main/java/janggi/Application.java b/src/main/java/janggi/Application.java index 59fa0394a5..1fd259dd3d 100644 --- a/src/main/java/janggi/Application.java +++ b/src/main/java/janggi/Application.java @@ -1,10 +1,10 @@ package janggi; -import janggi.controller.JanggiController; +import janggi.controller.JanggiGame; public class Application { public static void main(String[] args) { - JanggiController janggiController = new JanggiController(); - janggiController.run(); + JanggiGame janggiGame = new JanggiGame(); + janggiGame.run(); } } diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiGame.java similarity index 98% rename from src/main/java/janggi/controller/JanggiController.java rename to src/main/java/janggi/controller/JanggiGame.java index 56a4105d74..aa9145f50b 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiGame.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.function.Supplier; -public class JanggiController { +public class JanggiGame { private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); From a03d4eea6e2197c1828d64fd475d12649ea16730 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Tue, 31 Mar 2026 20:44:34 +0900 Subject: [PATCH 22/30] =?UTF-8?q?refactor(JanggiGame):=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=2010=EC=A4=84=20=EC=9D=B4=ED=95=98=20?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/janggi/controller/JanggiGame.java | 66 +++++++++++-------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/src/main/java/janggi/controller/JanggiGame.java b/src/main/java/janggi/controller/JanggiGame.java index aa9145f50b..c39ce00f3a 100644 --- a/src/main/java/janggi/controller/JanggiGame.java +++ b/src/main/java/janggi/controller/JanggiGame.java @@ -1,6 +1,7 @@ package janggi.controller; import janggi.domain.Board; +import janggi.domain.BoardFactory; import janggi.domain.Position; import janggi.view.InputView; import janggi.view.OutputView; @@ -9,46 +10,55 @@ public class JanggiGame { + private boolean isChoTurn = true; private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); public void run() { - Board board = new Board(); - board.initialize(); - boolean isChoTurn = true; - + Board board = initializeBoard(); outputView.printBoard(board.getBoard()); - while (true) { - outputView.printTurnMessage(isChoTurn); - - Position movePiecePosition = doLoop(() -> { - outputView.printMoveInfo(); - Position position = inputView.readPosition(); - board.findAvailablePositions(position); - return position; - }); - - List availablePositions = board.findAvailablePositions(movePiecePosition); - - outputView.printAvailablePositions(board.getBoard(), availablePositions); + isChoTurn = playTurn(board); + } + } - Position movePosition = doLoop(() -> { - outputView.printMoveChoiceInfo(); - Position position = inputView.readPosition(); - board.validateDestination(movePiecePosition, position); - return position; - }); + private boolean playTurn(Board board) { + outputView.printTurnMessage(isChoTurn); + Position movePiecePosition = choosePieceToMove(board); + List availablePositions = board.findAvailablePositions(movePiecePosition); + outputView.printAvailablePositions(board.getBoard(), availablePositions); + Position targetPosition = chooseTargetPosition(board, movePiecePosition); + board.movePiece(movePiecePosition, targetPosition); + outputView.printBoard(board.getBoard()); + isChoTurn = !isChoTurn; + return isChoTurn; + } - board.movePiece(movePiecePosition, movePosition); + private Board initializeBoard() { + Board board = new Board(); + BoardFactory.settingUpBoard(); + return board; + } - outputView.printBoard(board.getBoard()); + private Position chooseTargetPosition(Board board, Position movePiecePosition) { + return retry(() -> { + outputView.printMoveChoiceInfo(); + Position position = inputView.readPosition(); + board.validateDestination(movePiecePosition, position); + return position; + }); + } - isChoTurn = !isChoTurn; - } + private Position choosePieceToMove(Board board) { + return retry(() -> { + outputView.printMoveInfo(); + Position position = inputView.readPosition(); + board.findAvailablePositions(position); + return position; + }); } - private T doLoop(Supplier inputFunction) { + private T retry(Supplier inputFunction) { while (true) { try { return inputFunction.get(); From 740cc33adb0ee5dbfd741a0771e7b9f9080355d7 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Wed, 1 Apr 2026 17:35:15 +0900 Subject: [PATCH 23/30] =?UTF-8?q?refactor:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=ED=99=94=20=EB=A1=9C=EC=A7=81=20BoardFactory?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/janggi/controller/JanggiGame.java | 7 +- src/main/java/janggi/domain/Board.java | 87 ++++----------- src/main/java/janggi/domain/BoardFactory.java | 103 ++++++++++++++++++ .../java/janggi/domain/BoardFactoryTest.java | 44 ++++++++ src/test/java/janggi/domain/BoardTest.java | 101 ++++++++--------- 5 files changed, 218 insertions(+), 124 deletions(-) create mode 100644 src/main/java/janggi/domain/BoardFactory.java create mode 100644 src/test/java/janggi/domain/BoardFactoryTest.java diff --git a/src/main/java/janggi/controller/JanggiGame.java b/src/main/java/janggi/controller/JanggiGame.java index c39ce00f3a..b3868bee5b 100644 --- a/src/main/java/janggi/controller/JanggiGame.java +++ b/src/main/java/janggi/controller/JanggiGame.java @@ -2,10 +2,12 @@ import janggi.domain.Board; import janggi.domain.BoardFactory; +import janggi.domain.Piece; import janggi.domain.Position; import janggi.view.InputView; import janggi.view.OutputView; import java.util.List; +import java.util.Map; import java.util.function.Supplier; public class JanggiGame { @@ -35,9 +37,8 @@ private boolean playTurn(Board board) { } private Board initializeBoard() { - Board board = new Board(); - BoardFactory.settingUpBoard(); - return board; + Map initBoard = BoardFactory.settingUpBoard(); + return new Board(initBoard); } private Position chooseTargetPosition(Board board, Position movePiecePosition) { diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index a81b0a6a44..9445c68285 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -6,53 +6,13 @@ import java.util.Map; public class Board { + private final Map board; - private final Map board = new HashMap<>(); - - public void initialize() { - board.put(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); - board.put(new Position(3, 7), new Piece(Team.CHO, PieceType.ZOL)); - board.put(new Position(5, 7), new Piece(Team.CHO, PieceType.ZOL)); - board.put(new Position(7, 7), new Piece(Team.CHO, PieceType.ZOL)); - board.put(new Position(9, 7), new Piece(Team.CHO, PieceType.ZOL)); - - board.put(new Position(2, 8), new Piece(Team.CHO, PieceType.PO)); - board.put(new Position(8, 8), new Piece(Team.CHO, PieceType.PO)); - - board.put(new Position(1, 10), new Piece(Team.CHO, PieceType.CHA)); - board.put(new Position(9, 10), new Piece(Team.CHO, PieceType.CHA)); - - board.put(new Position(2, 10), new Piece(Team.CHO, PieceType.MA)); - board.put(new Position(3, 10), new Piece(Team.CHO, PieceType.SANG)); - board.put(new Position(7, 10), new Piece(Team.CHO, PieceType.MA)); - board.put(new Position(8, 10), new Piece(Team.CHO, PieceType.SANG)); - - board.put(new Position(4, 10), new Piece(Team.CHO, PieceType.SA)); - board.put(new Position(6, 10), new Piece(Team.CHO, PieceType.SA)); - board.put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); - - board.put(new Position(1, 4), new Piece(Team.HAN, PieceType.ZOL)); - board.put(new Position(3, 4), new Piece(Team.HAN, PieceType.ZOL)); - board.put(new Position(5, 4), new Piece(Team.HAN, PieceType.ZOL)); - board.put(new Position(7, 4), new Piece(Team.HAN, PieceType.ZOL)); - board.put(new Position(9, 4), new Piece(Team.HAN, PieceType.ZOL)); - - board.put(new Position(2, 3), new Piece(Team.HAN, PieceType.PO)); - board.put(new Position(8, 3), new Piece(Team.HAN, PieceType.PO)); - - board.put(new Position(1, 1), new Piece(Team.HAN, PieceType.CHA)); - board.put(new Position(9, 1), new Piece(Team.HAN, PieceType.CHA)); - - board.put(new Position(2, 1), new Piece(Team.HAN, PieceType.MA)); - board.put(new Position(3, 1), new Piece(Team.HAN, PieceType.SANG)); - board.put(new Position(7, 1), new Piece(Team.HAN, PieceType.MA)); - board.put(new Position(8, 1), new Piece(Team.HAN, PieceType.SANG)); - - board.put(new Position(4, 1), new Piece(Team.HAN, PieceType.SA)); - board.put(new Position(6, 1), new Piece(Team.HAN, PieceType.SA)); - board.put(new Position(5, 2), new Piece(Team.HAN, PieceType.KING)); + public Board(Map initBoard) { + this.board = initBoard; } + public Map getBoard() { return board; } @@ -73,23 +33,23 @@ public List findAvailablePositions(Position position) { Piece destinationPiece = board.get(destination); List route = entry.getValue(); - if(piece.getPieceType() == PieceType.PO) { - if(!hasOneObstacleAndNotPo(route)) { + if (piece.getPieceType() == PieceType.PO) { + if (!hasOneObstacleAndNotPo(route)) { continue; } - if(board.containsKey(destination)) { - if(isDestinationIsMyTeam(destinationPiece, piece) || isDestinationIsPo(destinationPiece)) { + if (board.containsKey(destination)) { + if (isDestinationIsMyTeam(destinationPiece, piece) || isDestinationIsPo(destinationPiece)) { continue; } } availablePositions.add(destination); } else { - if(hasObstacleOnRoute(route)) { + if (hasObstacleOnRoute(route)) { continue; } - if(board.containsKey(destination)) { - if(isDestinationIsMyTeam(destinationPiece, piece)) { + if (board.containsKey(destination)) { + if (isDestinationIsMyTeam(destinationPiece, piece)) { continue; } } @@ -97,7 +57,7 @@ public List findAvailablePositions(Position position) { } } - if(availablePositions.isEmpty()) { + if (availablePositions.isEmpty()) { throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); } return availablePositions; @@ -119,7 +79,7 @@ private boolean hasObstacleOnRoute(List route) { private Map> convertToPositions(Position position, Piece piece, List routes) { Map> result = new HashMap<>(); - if(piece.isCha()|| piece.isPo()) { + if (piece.isCha() || piece.isPo()) { return convertToContinuousRoutes(position, routes, result); } @@ -151,17 +111,18 @@ private Map> convertToFixedRoutes(Position position, Li return result; } - private Map> convertToContinuousRoutes(Position position, List routes, Map> result) { - for(Route route: routes) { + private Map> convertToContinuousRoutes(Position position, List routes, + Map> result) { + for (Route route : routes) { int currentX = position.getX(); int currentY = position.getY(); List directions = route.getRoutes(); - for(Direction direction:directions) { + for (Direction direction : directions) { List routeToPositions = new ArrayList<>(); currentX += direction.getX(); currentY += direction.getY(); - while(Position.isInsideBoundary(currentX, currentY)) { + while (Position.isInsideBoundary(currentX, currentY)) { Position movePosition = new Position(currentX, currentY); routeToPositions.add(movePosition); @@ -182,9 +143,9 @@ private boolean isDestinationIsPo(Piece destinationPiece) { private boolean hasOneObstacleAndNotPo(List route) { int count = 0; List obstacles = new ArrayList<>(); - for(int i = 0; i < route.size() -1; i++) { - if(board.containsKey(route.get(i))) { - count+=1; + for (int i = 0; i < route.size() - 1; i++) { + if (board.containsKey(route.get(i))) { + count += 1; obstacles.add(board.get(route.get(i))); } } @@ -200,14 +161,14 @@ public void movePiece(Position movePiecePosition, Position destination) { public void validateDestination(Position movePiecePosition, Position destination) { List availablePositions = findAvailablePositions(movePiecePosition); boolean hasPosition = false; - for(Position position:availablePositions) { - if (position == destination) { + for (Position position : availablePositions) { + if (position.equals(destination)) { hasPosition = true; break; } } - if(!hasPosition) { + if (!hasPosition) { throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); } } diff --git a/src/main/java/janggi/domain/BoardFactory.java b/src/main/java/janggi/domain/BoardFactory.java new file mode 100644 index 0000000000..ab45c22c49 --- /dev/null +++ b/src/main/java/janggi/domain/BoardFactory.java @@ -0,0 +1,103 @@ +package janggi.domain; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BoardFactory { + + public static Map settingUpBoard() { + Map board = new HashMap<>(); + settingUpZol(board); + settingUpPo(board); + settingUpCha(board); + settingUpMa(board); + settingUpSang(board); + settingUpSa(board); + settingUpKing(board); + return board; + } + + + private static void settingUpZol(Map board) { + final int CHO_ZOL_Y = 7; + final int HAN_ZOL_Y = 4; + + List zolPositions = List.of(1, 3, 5, 7, 9); + + for (int x : zolPositions) { + board.put(new Position(x, CHO_ZOL_Y), new Piece(Team.CHO, PieceType.ZOL)); + board.put(new Position(x, HAN_ZOL_Y), new Piece(Team.HAN, PieceType.ZOL)); + } + } + + private static void settingUpPo(Map board) { + final int CHO_PO_Y = 8; + final int HAN_PO_Y = 3; + + List poPositions = List.of(2, 8); + + for (int x : poPositions) { + board.put(new Position(x, CHO_PO_Y), new Piece(Team.CHO, PieceType.PO)); + board.put(new Position(x, HAN_PO_Y), new Piece(Team.HAN, PieceType.PO)); + } + } + + private static void settingUpCha(Map board) { + final int CHO_CHA_Y = 10; + final int HAN_CHA_Y = 1; + + List chaPositions = List.of(1, 9); + + for (int x : chaPositions) { + board.put(new Position(x, CHO_CHA_Y), new Piece(Team.CHO, PieceType.CHA)); + board.put(new Position(x, HAN_CHA_Y), new Piece(Team.HAN, PieceType.CHA)); + } + } + + private static void settingUpMa(Map board) { + final int CHO_MA_Y = 10; + final int HAN_MA_Y = 1; + + List chaPositions = List.of(2, 7); + + for (int x : chaPositions) { + board.put(new Position(x, CHO_MA_Y), new Piece(Team.CHO, PieceType.MA)); + board.put(new Position(x, HAN_MA_Y), new Piece(Team.HAN, PieceType.MA)); + } + } + + private static void settingUpSang(Map board) { + final int CHO_SANG_Y = 10; + final int HAN_SANG_Y = 1; + + List chaPositions = List.of(3, 8); + + for (int x : chaPositions) { + board.put(new Position(x, CHO_SANG_Y), new Piece(Team.CHO, PieceType.SANG)); + board.put(new Position(x, HAN_SANG_Y), new Piece(Team.HAN, PieceType.SANG)); + } + } + + private static void settingUpSa(Map board) { + final int CHO_SA_Y = 10; + final int HAN_SA_Y = 1; + + List chaPositions = List.of(4, 6); + + for (int x : chaPositions) { + board.put(new Position(x, CHO_SA_Y), new Piece(Team.CHO, PieceType.SA)); + board.put(new Position(x, HAN_SA_Y), new Piece(Team.HAN, PieceType.SA)); + } + } + + private static void settingUpKing(Map board) { + final int CHO_KING_X = 5; + final int CHO_KING_Y = 9; + final int HAN_KING_X = 5; + final int HAN_KING_Y = 2; + + board.put(new Position(CHO_KING_X, CHO_KING_Y), new Piece(Team.CHO, PieceType.KING)); + board.put(new Position(HAN_KING_X, HAN_KING_Y), new Piece(Team.HAN, PieceType.KING)); + } +} diff --git a/src/test/java/janggi/domain/BoardFactoryTest.java b/src/test/java/janggi/domain/BoardFactoryTest.java new file mode 100644 index 0000000000..2951a45d23 --- /dev/null +++ b/src/test/java/janggi/domain/BoardFactoryTest.java @@ -0,0 +1,44 @@ +package janggi.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class BoardFactoryTest { + @ParameterizedTest + @CsvSource({ + + "CHO,KING,5,9", + "CHO,SA,4,10", "CHO,SA,6,10", + "CHO,SANG,3,10", "CHO,SANG,8,10", + "CHO,MA,2,10", "CHO,MA,7,10", + "CHO,CHA,1,10", "CHO,CHA,9,10", + "CHO,PO,2,8", "CHO,PO,8,8", + "CHO,ZOL,1,7", "CHO,ZOL,3,7", "CHO,ZOL,5,7", "CHO,ZOL,7,7", "CHO,ZOL,9,7", + + "HAN,KING,5,2", + "HAN,SA,4,1", "HAN,SA,6,1", + "HAN,SANG,3,1", "HAN,SANG,8,1", + "HAN,MA,2,1", "HAN,MA,7,1", + "HAN,CHA,1,1", "HAN,CHA,9,1", + "HAN,PO,2,3", "HAN,PO,8,3", + "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4" + + }) + @DisplayName("초기화된 보드의 지정된 위치에 각 나라의 기물이 알맞게 배치되어 있다") + void 보드_초기화_기물_배치_확인(Team team, PieceType pieceType, int x, int y) { + //given + Board board = new Board(BoardFactory.settingUpBoard()); + Position position = new Position(x, y); + Piece piece = new Piece(team, pieceType); + + //when + Map checkPiece = board.getBoard(); + + //then + assertThat(checkPiece.get(position)).isEqualTo(piece); + } +} diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 167528cf59..0496578944 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -4,56 +4,21 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; public class BoardTest { - @ParameterizedTest - @CsvSource({ - - "CHO,KING,5,9", - "CHO,SA,4,10", "CHO,SA,6,10", - "CHO,SANG,3,10", "CHO,SANG,8,10", - "CHO,MA,2,10", "CHO,MA,7,10", - "CHO,CHA,1,10", "CHO,CHA,9,10", - "CHO,PO,2,8", "CHO,PO,8,8", - "CHO,ZOL,1,7", "CHO,ZOL,3,7", "CHO,ZOL,5,7", "CHO,ZOL,7,7", "CHO,ZOL,9,7", - - "HAN,KING,5,2", - "HAN,SA,4,1", "HAN,SA,6,1", - "HAN,SANG,3,1", "HAN,SANG,8,1", - "HAN,MA,2,1", "HAN,MA,7,1", - "HAN,CHA,1,1", "HAN,CHA,9,1", - "HAN,PO,2,3", "HAN,PO,8,3", - "HAN,ZOL,1,4", "HAN,ZOL,3,4", "HAN,ZOL,5,4", "HAN,ZOL,7,4", "HAN,ZOL,9,4" - - }) - @DisplayName("초기화된 보드의 지정된 위치에 각 나라의 기물이 알맞게 배치되어 있다") - void 보드_초기화_기물_배치_확인(Team team, PieceType pieceType, int x, int y) { - //given - Board board = new Board(); - board.initialize(); - Position position = new Position(x, y); - Piece zol = new Piece(team, pieceType); - - //when - Map checkZol = board.getBoard(); - - //then - assertThat(checkZol.get(position)).isEqualTo(zol); - } - @Test @DisplayName("초나라 졸은 경로에 장애물이 없으면 위쪽, 왼쪽, 오른쪽으로 이동할 수 있다") void 초나라_졸_장애물_없을때_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); Position zolUp = new Position(5, 6); @@ -72,7 +37,8 @@ public class BoardTest { @DisplayName("초나라 졸의 이동 방향에 아군 기물이 있으면 해당 방향으로는 이동할 수 없다") void 초나라_졸_아군이_막고있을때_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); Position zolUp = new Position(5, 6); @@ -92,7 +58,8 @@ public class BoardTest { @DisplayName("마는 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") void 마_장애물_없을때_8방향_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(4, 6); board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); Position maPos1 = new Position(3, 4); @@ -117,7 +84,8 @@ public class BoardTest { @DisplayName("마는 이동 경로(멱)에 다른 기물이 있으면 해당 방향으로 이동할 수 없다") void 마_멱이_막혀있을때_해당_방향_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(4, 6); board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); board.getBoard().put(new Position(4, 5), new Piece(Team.HAN, PieceType.CHA)); @@ -141,7 +109,8 @@ public class BoardTest { @DisplayName("마의 최종 목적지에 아군 기물이 있으면 해당 좌표로 이동할 수 없다") void 마_목적지에_아군_존재시_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(4, 6); board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); board.getBoard().put(new Position(2, 7), new Piece(Team.CHO, PieceType.CHA)); @@ -166,7 +135,8 @@ public class BoardTest { @DisplayName("상은 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") void 상_장애물_없을때_8방향_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); Position maPos1 = new Position(3, 4); @@ -191,7 +161,8 @@ public class BoardTest { @DisplayName("상은 대각선 경로(멱)에 다른 기물이 있으면 해당 방향으로 이동할 수 없다") void 상_대각선_멱이_막혀있을때_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); board.getBoard().put(new Position(6, 5), new Piece(Team.CHO, PieceType.ZOL)); @@ -216,7 +187,8 @@ public class BoardTest { @DisplayName("상은 직선 경로(멱)에 다른 기물이 있으면 해당 방향으로 이동할 수 없다") void 상_직선_멱이_막혀있을때_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.ZOL)); @@ -240,7 +212,8 @@ public class BoardTest { @DisplayName("상의 최종 목적지에 아군 기물이 있으면 해당 좌표로 이동할 수 없다") void 상_목적지에_아군_존재시_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 7); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); board.getBoard().put(new Position(2, 9), new Piece(Team.CHO, PieceType.ZOL)); @@ -265,7 +238,8 @@ public class BoardTest { @DisplayName("사는 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)") void 사_장애물_없을때_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(4, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); Position maPos1 = new Position(4, 9); @@ -287,7 +261,8 @@ public class BoardTest { @DisplayName("사의 목적지에 아군 기물이 있으면 이동할 수 없다 (사이클1 규칙)") void 사_목적지에_아군_존재시_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(4, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); board.getBoard().put(new Position(5, 9), new Piece(Team.CHO, PieceType.KING)); @@ -309,7 +284,8 @@ public class BoardTest { @DisplayName("사의 목적지에 적군 기물이 있으면 이동할 수 있다 (사이클1 규칙)") void 사_목적지에_적군_존재시_이동_가능() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(4, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); board.getBoard().put(new Position(5, 9), new Piece(Team.HAN, PieceType.CHA)); @@ -332,7 +308,8 @@ public class BoardTest { @DisplayName("왕은 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)") void 왕_장애물_없을때_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 9); board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); Position maPos1 = new Position(4, 8); @@ -357,7 +334,8 @@ public class BoardTest { @DisplayName("왕의 이동하려는 목적지에 아군 기물이 있으면 이동할 수 없다(사이클1 규칙)") void 왕_목적지에_아군_존재시_이동_불가() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 9); board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); board.getBoard().put(new Position(4, 9), new Piece(Team.CHO, PieceType.SA)); @@ -382,7 +360,8 @@ public class BoardTest { @DisplayName("왕의 목적지에 적군 기물이 있으면 이동할 수 있다 (사이클1 규칙)") void 왕_목적있지에_적군_존재시_이동_가능() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 9); board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); board.getBoard().put(new Position(4, 9), new Piece(Team.HAN, PieceType.ZOL)); @@ -409,7 +388,8 @@ public class BoardTest { @DisplayName("차는 직선 경로상에 장애물이 없으면 끝까지 이동할 수 있다") void 차_장애물_없을때_직선_끝까지_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(1, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); List upRoutes = List.of( @@ -439,7 +419,8 @@ public class BoardTest { @DisplayName("차는 직선 경로상에 아군 기물이 있으면 아군 기물 직전까지만 이동할 수 있다") void 차_경로에_아군_존재시_아군_직전까지_이동_가능() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(1, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); board.getBoard().put(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); @@ -468,7 +449,8 @@ public class BoardTest { @DisplayName("차는 직선 경로상에 적군 기물이 있으면 포획할 수 있는 적군 기물 위치까지만 이동할 수 있다") void 차_경로에_적군_존재시_적군_위치까지_이동_가능() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(1, 10); board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); board.getBoard().put(new Position(1, 7), new Piece(Team.HAN, PieceType.CHA)); @@ -497,7 +479,8 @@ public class BoardTest { @DisplayName("포는 이동 경로상에 일반 기물(포다리)이 딱 1개 존재하면 그 너머로 이동할 수 있다") void 포_경로에_일반_기물_포다리가_1개_있을때_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); @@ -520,7 +503,8 @@ public class BoardTest { @DisplayName("포는 넘어가려는 목적지에 또 다른 포가 있으면, 포는 포를 포획할 수 없으므로 이동할 수 없다") void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { //given - Board board = new Board(); + Map zeroBoard = new HashMap<>(); + Board board = new Board(zeroBoard); Position position = new Position(5, 8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); @@ -536,7 +520,8 @@ public class BoardTest { @DisplayName("포는 포다리 너머에 일반 적군 기물이 존재하면 해당 기물을 포획하며 이동할 수 있다") void 포_목적지에_일반_적군_기물이_있을때_이동_성공() { //given - Board board = new Board(); + Map emptyBoard = new HashMap<>(); + Board board = new Board(emptyBoard); Position position = new Position(5, 8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); board.getBoard().put(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); From 52041ea11c3761773c8e7ad4fec93fdf8741cb89 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 17:14:10 +0900 Subject: [PATCH 24/30] =?UTF-8?q?refactor(Board):=20for=EB=AC=B8=EC=9D=84?= =?UTF-8?q?=20stream=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 9445c68285..5937e75179 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -68,12 +68,10 @@ private boolean isDestinationIsMyTeam(Piece destinationPiece, Piece piece) { } private boolean hasObstacleOnRoute(List route) { - for (int i = 0; i < route.size() - 1; i++) { - if (board.containsKey(route.get(i))) { - return true; - } - } - return false; + Position targetPosition = route.getLast(); + return route.stream() + .filter(position -> position != targetPosition) + .anyMatch(board::containsKey); } private Map> convertToPositions(Position position, Piece piece, List routes) { From de84fcc7513511ff7bdeb906ec759e0ed1bd6124 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 17:15:03 +0900 Subject: [PATCH 25/30] =?UTF-8?q?refactor(PieceType):=20=EB=AF=B8=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=20=ED=95=84=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/PieceType.java | 29 ++++++---------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index 7f06f17886..6e18835e9e 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -7,26 +7,21 @@ import janggi.domain.moveRules.SaMoveRule; import janggi.domain.moveRules.SangMoveRule; import janggi.domain.moveRules.ZolMoveRule; -import java.util.List; public enum PieceType { - KING("왕", List.of(5), 9, new KingMoveRule()), - SA("사", List.of(4, 6), 10, new SaMoveRule()), - SANG("상", List.of(3, 7), 10, new SangMoveRule()), - MA("마", List.of(2, 8), 10, new MaMoveRule()), - CHA("차", List.of(1, 9), 10, new ChaMoveRule()), - PO("포", List.of(2, 8), 8, new PoMoveRule()), - ZOL("졸", List.of(1, 3, 5, 7, 9), 7, new ZolMoveRule()); + KING("왕", new KingMoveRule()), + SA("사", new SaMoveRule()), + SANG("상", new SangMoveRule()), + MA("마", new MaMoveRule()), + CHA("차", new ChaMoveRule()), + PO("포", new PoMoveRule()), + ZOL("졸", new ZolMoveRule()); private final String name; - private final List xPositions; - private final int yPosition; private final MoveRule moveRule; - PieceType(String name, List xPositions, int yPosition, MoveRule moveRule) { + PieceType(String name, MoveRule moveRule) { this.name = name; - this.xPositions = xPositions; - this.yPosition = yPosition; this.moveRule = moveRule; } @@ -34,14 +29,6 @@ public String getName() { return name; } - public List getXPositions() { - return xPositions; - } - - public int getYPosition() { - return yPosition; - } - public MoveRule getMoveRule() { return moveRule; } From d0a52be4eed01ca4c2cbb603ceb80299af9f1a5c Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 17:17:18 +0900 Subject: [PATCH 26/30] =?UTF-8?q?refactor(ZolMoveRule):=20=EB=B6=88?= =?UTF-8?q?=ED=95=84=EC=9A=94=20=ED=96=89=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/moveRules/ZolMoveRule.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/janggi/domain/moveRules/ZolMoveRule.java b/src/main/java/janggi/domain/moveRules/ZolMoveRule.java index d74cb9011c..d1c86f04f2 100644 --- a/src/main/java/janggi/domain/moveRules/ZolMoveRule.java +++ b/src/main/java/janggi/domain/moveRules/ZolMoveRule.java @@ -10,7 +10,7 @@ public class ZolMoveRule implements MoveRule { @Override public List findRoutes(Team team) { - if(team == Team.CHO) { + if (team == Team.CHO) { Route route1 = new Route(List.of(Direction.UP)); Route route2 = new Route(List.of(Direction.LEFT)); Route route3 = new Route(List.of(Direction.RIGHT)); @@ -21,5 +21,4 @@ public List findRoutes(Team team) { Route route3 = new Route(List.of(Direction.RIGHT)); return List.of(route1, route2, route3); } - } From 50a774fc54622a6c6fd8be2a6afe356c3d4b167d Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 21:44:08 +0900 Subject: [PATCH 27/30] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/.gitkeep | 0 src/main/java/janggi/controller/JanggiGame.java | 6 +++--- src/main/java/janggi/domain/Direction.java | 11 +++++++++-- src/main/java/janggi/domain/Piece.java | 5 +++++ src/main/java/janggi/domain/Position.java | 13 +++++++------ src/main/java/janggi/domain/Route.java | 8 ++++---- src/main/java/janggi/domain/Team.java | 3 ++- .../janggi/domain/{ => board}/BoardFactory.java | 6 +++++- src/test/java/.gitkeep | 0 src/test/java/janggi/domain/BoardFactoryTest.java | 2 ++ src/test/java/janggi/domain/BoardTest.java | 1 + 11 files changed, 38 insertions(+), 17 deletions(-) delete mode 100644 src/main/java/.gitkeep rename src/main/java/janggi/domain/{ => board}/BoardFactory.java (95%) delete mode 100644 src/test/java/.gitkeep diff --git a/src/main/java/.gitkeep b/src/main/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/janggi/controller/JanggiGame.java b/src/main/java/janggi/controller/JanggiGame.java index b3868bee5b..71b954d756 100644 --- a/src/main/java/janggi/controller/JanggiGame.java +++ b/src/main/java/janggi/controller/JanggiGame.java @@ -1,9 +1,9 @@ package janggi.controller; -import janggi.domain.Board; -import janggi.domain.BoardFactory; import janggi.domain.Piece; import janggi.domain.Position; +import janggi.domain.board.Board; +import janggi.domain.board.BoardFactory; import janggi.view.InputView; import janggi.view.OutputView; import java.util.List; @@ -12,9 +12,9 @@ public class JanggiGame { - private boolean isChoTurn = true; private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); + private boolean isChoTurn = true; public void run() { Board board = initializeBoard(); diff --git a/src/main/java/janggi/domain/Direction.java b/src/main/java/janggi/domain/Direction.java index 4e08a73f13..0184cacb3d 100644 --- a/src/main/java/janggi/domain/Direction.java +++ b/src/main/java/janggi/domain/Direction.java @@ -1,8 +1,15 @@ package janggi.domain; 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); + 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; diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 19175436d5..c48b7ceb28 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -1,5 +1,6 @@ package janggi.domain; +import java.util.List; import java.util.Objects; public class Piece { @@ -37,6 +38,10 @@ public boolean isPo() { return pieceType == PieceType.PO; } + public List findRoutes() { + return pieceType.getMoveRule().findRoutes(this.team); + } + @Override public boolean equals(Object o) { if (!(o instanceof Piece piece)) { diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java index 539efcacc3..9aa38b6195 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/Position.java @@ -8,6 +8,7 @@ public class Position { private static final int MAX_X = 9; private static final int MIN_Y = 1; private static final int MAX_Y = 10; + private final int x; private final int y; @@ -17,12 +18,6 @@ public Position(int x, int y) { this.y = y; } - private void validateBoundary(int x, int y) { - if (x < MIN_X || x > MAX_X || y < MIN_Y || y > MAX_Y) { - throw new IllegalArgumentException("[ERROR] 보드 범위를 벗어났습니다."); - } - } - public static boolean isInsideBoundary(int x, int y) { return x >= MIN_X && x <= MAX_X && y >= MIN_Y && y <= MAX_Y; } @@ -47,4 +42,10 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(x, y); } + + private void validateBoundary(int x, int y) { + if (x < MIN_X || x > MAX_X || y < MIN_Y || y > MAX_Y) { + throw new IllegalArgumentException("[ERROR] 보드 범위를 벗어났습니다."); + } + } } diff --git a/src/main/java/janggi/domain/Route.java b/src/main/java/janggi/domain/Route.java index d92b053e5b..42587bbe3a 100644 --- a/src/main/java/janggi/domain/Route.java +++ b/src/main/java/janggi/domain/Route.java @@ -11,6 +11,10 @@ public Route(List routes) { this.routes = routes; } + public List getRoutes() { + return routes; + } + @Override public boolean equals(Object o) { if (!(o instanceof Route route)) { @@ -23,8 +27,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(routes); } - - public List getRoutes() { - return routes; - } } diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/Team.java index 9d7c221835..cdbc870075 100644 --- a/src/main/java/janggi/domain/Team.java +++ b/src/main/java/janggi/domain/Team.java @@ -2,7 +2,8 @@ public enum Team { CHO("초나라"), - HAN("한나라"); + HAN("한나라"), + ; private final String name; diff --git a/src/main/java/janggi/domain/BoardFactory.java b/src/main/java/janggi/domain/board/BoardFactory.java similarity index 95% rename from src/main/java/janggi/domain/BoardFactory.java rename to src/main/java/janggi/domain/board/BoardFactory.java index ab45c22c49..5c6bf2cb65 100644 --- a/src/main/java/janggi/domain/BoardFactory.java +++ b/src/main/java/janggi/domain/board/BoardFactory.java @@ -1,5 +1,9 @@ -package janggi.domain; +package janggi.domain.board; +import janggi.domain.Piece; +import janggi.domain.PieceType; +import janggi.domain.Position; +import janggi.domain.Team; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/src/test/java/.gitkeep b/src/test/java/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/java/janggi/domain/BoardFactoryTest.java b/src/test/java/janggi/domain/BoardFactoryTest.java index 2951a45d23..ff11f7103a 100644 --- a/src/test/java/janggi/domain/BoardFactoryTest.java +++ b/src/test/java/janggi/domain/BoardFactoryTest.java @@ -2,6 +2,8 @@ import static org.assertj.core.api.Assertions.assertThat; +import janggi.domain.board.Board; +import janggi.domain.board.BoardFactory; import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 0496578944..3e1d7d6c7c 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import janggi.domain.board.Board; import java.util.ArrayList; import java.util.HashMap; import java.util.List; From d0557f7a0977281f67f27bfedad0ba28464e8347 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 22:35:28 +0900 Subject: [PATCH 28/30] =?UTF-8?q?refactor(Board):=20=EB=A9=94=EC=84=9C?= =?UTF-8?q?=EB=93=9C=EA=B0=80=20=ED=95=9C=EA=B0=80=EC=A7=80=20=EC=9D=BC?= =?UTF-8?q?=EC=9D=84=20=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/janggi/domain/{ => board}/Board.java | 159 ++++++++++-------- 1 file changed, 87 insertions(+), 72 deletions(-) rename src/main/java/janggi/domain/{ => board}/Board.java (54%) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/board/Board.java similarity index 54% rename from src/main/java/janggi/domain/Board.java rename to src/main/java/janggi/domain/board/Board.java index 5937e75179..b9466917c1 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/board/Board.java @@ -1,70 +1,79 @@ -package janggi.domain; +package janggi.domain.board; +import janggi.domain.Direction; +import janggi.domain.Piece; +import janggi.domain.PieceType; +import janggi.domain.Position; +import janggi.domain.Route; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Board { + private final Map board; public Board(Map initBoard) { this.board = initBoard; } - public Map getBoard() { return board; } public List findAvailablePositions(Position position) { Piece piece = board.get(position); - PieceType pieceType = piece.getPieceType(); - - MoveRule moveRule = pieceType.getMoveRule(); - - List routes = moveRule.findRoutes(piece.getTeam()); - + List routes = piece.findRoutes(); Map> routePositions = convertToPositions(position, piece, routes); List availablePositions = new ArrayList<>(); for (Map.Entry> entry : routePositions.entrySet()) { Position destination = entry.getKey(); - Piece destinationPiece = board.get(destination); List route = entry.getValue(); - - if (piece.getPieceType() == PieceType.PO) { - if (!hasOneObstacleAndNotPo(route)) { - continue; - } - - if (board.containsKey(destination)) { - if (isDestinationIsMyTeam(destinationPiece, piece) || isDestinationIsPo(destinationPiece)) { - continue; - } - } - availablePositions.add(destination); - } else { - if (hasObstacleOnRoute(route)) { - continue; - } - if (board.containsKey(destination)) { - if (isDestinationIsMyTeam(destinationPiece, piece)) { - continue; - } - } + if (canPieceMove(piece, destination, route)) { availablePositions.add(destination); } } + validateCantMovePiece(availablePositions); + return availablePositions; + } - if (availablePositions.isEmpty()) { - throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); + + private boolean canPieceMove(Piece piece, Position destination, List route) { + Piece destinationPiece = board.get(destination); + if (piece.isPo()) { + return canPoMove(piece, destinationPiece, route); } - return availablePositions; + return canGeneralPieceMove(piece, destinationPiece, route); } - private boolean isDestinationIsMyTeam(Piece destinationPiece, Piece piece) { - return destinationPiece.getTeam() == piece.getTeam(); + private boolean canPoMove(Piece piece, Piece destinationPiece, List route) { + if (!hasOneObstacleAndNotPo(route)) { + return false; + } + if (destinationPiece == null) { + return true; + } + return isDestinationIsEnemy(destinationPiece, piece) && !isDestinationIsPo(destinationPiece); + } + + private boolean canGeneralPieceMove(Piece piece, Piece destinationPiece, List route) { + if (hasObstacleOnRoute(route)) { + return false; + } + if (destinationPiece == null) { + return true; + } + return isDestinationIsEnemy(destinationPiece, piece); + } + + private boolean isDestinationIsPo(Piece destinationPiece) { + return destinationPiece.getPieceType() == PieceType.PO; + } + + private boolean isDestinationIsEnemy(Piece destinationPiece, Piece piece) { + return destinationPiece.getTeam() != piece.getTeam(); } private boolean hasObstacleOnRoute(List route) { @@ -87,55 +96,55 @@ private Map> convertToPositions(Position position, Piec private Map> convertToFixedRoutes(Position position, List routes, Map> result) { for (Route route : routes) { - int currentX = position.getX(); - int currentY = position.getY(); - List routeToPositions = new ArrayList<>(); - List directions = route.getRoutes(); + addValidFixedRoute(position, result, route); + } + return result; + } - boolean isInBoard = true; - for (Direction direction : directions) { - currentX += direction.getX(); - currentY += direction.getY(); - if (!Position.isInsideBoundary(currentX, currentY)) { - isInBoard = false; - break; - } - routeToPositions.add(new Position(currentX, currentY)); - } - if (isInBoard && !routeToPositions.isEmpty()) { - result.put(routeToPositions.getLast(), routeToPositions); + private static void addValidFixedRoute(Position position, Map> result, Route route) { + int currentX = position.getX(); + int currentY = position.getY(); + List routeToPositions = new ArrayList<>(); + + for (Direction direction : route.getRoutes()) { + currentX += direction.getX(); + currentY += direction.getY(); + if (!Position.isInsideBoundary(currentX, currentY)) { + return; } + routeToPositions.add(new Position(currentX, currentY)); + } + if (!routeToPositions.isEmpty()) { + result.put(routeToPositions.getLast(), routeToPositions); } - return result; } private Map> convertToContinuousRoutes(Position position, List routes, Map> result) { for (Route route : routes) { - int currentX = position.getX(); - int currentY = position.getY(); - List directions = route.getRoutes(); + addValidContinuousPosition(position, result, route); + } + return result; + } + + private static void addValidContinuousPosition(Position position, Map> result, + Route route) { + int currentX = position.getX(); + int currentY = position.getY(); + List directions = route.getRoutes(); - for (Direction direction : directions) { - List routeToPositions = new ArrayList<>(); + for (Direction direction : directions) { + List routeToPositions = new ArrayList<>(); + currentX += direction.getX(); + currentY += direction.getY(); + while (Position.isInsideBoundary(currentX, currentY)) { + Position movePosition = new Position(currentX, currentY); + routeToPositions.add(movePosition); + result.put(movePosition, new ArrayList<>(routeToPositions)); currentX += direction.getX(); currentY += direction.getY(); - while (Position.isInsideBoundary(currentX, currentY)) { - Position movePosition = new Position(currentX, currentY); - routeToPositions.add(movePosition); - - result.put(movePosition, new ArrayList<>(routeToPositions)); - - currentX += direction.getX(); - currentY += direction.getY(); - } } } - return result; - } - - private boolean isDestinationIsPo(Piece destinationPiece) { - return destinationPiece.getPieceType() == PieceType.PO; } private boolean hasOneObstacleAndNotPo(List route) { @@ -143,7 +152,7 @@ private boolean hasOneObstacleAndNotPo(List route) { List obstacles = new ArrayList<>(); for (int i = 0; i < route.size() - 1; i++) { if (board.containsKey(route.get(i))) { - count += 1; + count++; obstacles.add(board.get(route.get(i))); } } @@ -170,4 +179,10 @@ public void validateDestination(Position movePiecePosition, Position destination throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); } } + + private static void validateCantMovePiece(List availablePositions) { + if (availablePositions.isEmpty()) { + throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); + } + } } From 7635d5ff7b7dddb759d897fa9e35a01db043f482 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 22:36:32 +0900 Subject: [PATCH 29/30] =?UTF-8?q?refactor(OutputView):=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=EB=90=98=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/view/OutputView.java | 84 ++++++++++------------- 1 file changed, 38 insertions(+), 46 deletions(-) diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index 8d26cc8376..f3a43056d5 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -3,6 +3,7 @@ import janggi.domain.Piece; import janggi.domain.Position; import janggi.domain.Team; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -12,81 +13,72 @@ public class OutputView { public static final String CHO_COLOR = "\u001B[34m"; public static final String AVAILABLE_COLOR = "\u001B[32m"; public static final String RESET = "\u001B[0m"; + private static final String[] X_VALUES = {"1", "2", "3", "4", "5", "6", "7", "8", "9"}; + private static final String EMPTY_MARK = ". "; + private static final String AVAILABLE_MARK = "O "; public static void printErrorMessage(String message) { System.out.printf("%s%n", message); } public void printBoard(Map board) { - System.out.print(" "); - for (int x = 1; x <= 9; x++) { - System.out.print(X_VALUES[x - 1] + " "); - } - System.out.println(); + printGrid(board, Collections.emptyList()); + } - for (int y = 1; y <= 10; y++) { - System.out.print(String.format("%2d ", y)); + public void printAvailablePositions(Map board, List availablePositions) { + printGrid(board, availablePositions); + } + + private void printGrid(Map board, List availablePositions) { + printXAxis(); + for (int y = 1; y <= 10; y++) { + System.out.printf("%2d ", y); for (int x = 1; x <= 9; x++) { Position currentPos = new Position(x, y); - if (board.containsKey(currentPos)) { - Piece piece = board.get(currentPos); - String color = getColorByTeam(piece); - - System.out.print(color + piece.getPieceTypeName() + RESET + " "); - } else { - System.out.print(". "); - } + printCell(board, availablePositions, currentPos); } System.out.println(); } } - public void printAvailablePositions(Map board, List availablePositions) { + private void printXAxis() { System.out.print(" "); - for (int x = 1; x <= 9; x++) { - System.out.print(X_VALUES[x - 1] + " "); + for (String xValue : X_VALUES) { + System.out.print(xValue + " "); } System.out.println(); + } - for (int y = 1; y <= 10; y++) { - System.out.print(String.format("%2d ", y)); - - for (int x = 1; x <= 9; x++) { - Position currentPos = new Position(x, y); - - if (availablePositions.contains(currentPos)) { - if (board.containsKey(currentPos)) { - System.out.print(AVAILABLE_COLOR + board.get(currentPos).getPieceTypeName() + RESET + " "); - } else { - System.out.print(AVAILABLE_COLOR + "O" + RESET + " "); - } - continue; - } - - if (board.containsKey(currentPos)) { - Piece piece = board.get(currentPos); - String color = getColorByTeam(piece); - System.out.print(color + piece.getPieceTypeName() + RESET + " "); - } else { - System.out.print(". "); - } - } - System.out.println(); + private void printCell(Map board, List availablePositions, Position position) { + boolean isAvailable = availablePositions.contains(position); + boolean hasPiece = board.containsKey(position); + + if (isAvailable && hasPiece) { + System.out.print(AVAILABLE_COLOR + board.get(position).getPieceTypeName() + RESET + " "); + } else if (isAvailable) { + System.out.print(AVAILABLE_COLOR + AVAILABLE_MARK + RESET); + } else if (hasPiece) { + Piece piece = board.get(position); + System.out.print(getColorByTeam(piece) + piece.getPieceTypeName() + RESET + " "); + } else { + System.out.print(EMPTY_MARK); } } private String getColorByTeam(Piece piece) { - if(piece.getTeam() == Team.CHO) return CHO_COLOR; + if (piece.getTeam() == Team.CHO) { + return CHO_COLOR; + } return HAN_COLOR; } public void printTurnMessage(boolean isChoTurn) { - if(isChoTurn) { - System.out.println(OutputView.CHO_COLOR + "\n현재 초나라 차례입니다" + OutputView.RESET); + if (isChoTurn) { + System.out.println(CHO_COLOR + "\n현재 초나라 차례입니다" + RESET); } else { - System.out.println(OutputView.HAN_COLOR + "\n한나라 차례입니다" + OutputView.RESET); + System.out.println(HAN_COLOR + "\n한나라 차례입니다" + RESET); } } From 1a9affe02fdc462b811460abc6b6cfe7307ba752 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Thu, 2 Apr 2026 22:46:04 +0900 Subject: [PATCH 30/30] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=EC=97=90=EC=84=9C=20View=EB=A1=9C=EC=A7=81=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Piece.java | 9 -------- src/main/java/janggi/domain/Team.java | 14 ++---------- src/main/java/janggi/view/OutputView.java | 25 ++++++++++++++++++---- src/test/java/janggi/domain/PieceTest.java | 22 ------------------- 4 files changed, 23 insertions(+), 47 deletions(-) delete mode 100644 src/test/java/janggi/domain/PieceTest.java diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index c48b7ceb28..742ee4d44e 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -13,15 +13,6 @@ public Piece(Team team, PieceType pieceType) { this.pieceType = pieceType; } - public String getTeamName() { - return team.getName(); - } - - public String getPieceTypeName() { - return pieceType.getName(); - } - - public PieceType getPieceType() { return pieceType; } diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/Team.java index cdbc870075..ed86b28d23 100644 --- a/src/main/java/janggi/domain/Team.java +++ b/src/main/java/janggi/domain/Team.java @@ -1,17 +1,7 @@ package janggi.domain; public enum Team { - CHO("초나라"), - HAN("한나라"), + CHO, + HAN, ; - - private final String name; - - Team(String name) { - this.name = name; - } - - public String getName() { - return name; - } } diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index f3a43056d5..e7cff6fcd1 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -1,6 +1,7 @@ package janggi.view; import janggi.domain.Piece; +import janggi.domain.PieceType; import janggi.domain.Position; import janggi.domain.Team; import java.util.Collections; @@ -56,19 +57,35 @@ private void printCell(Map board, List availablePosit boolean hasPiece = board.containsKey(position); if (isAvailable && hasPiece) { - System.out.print(AVAILABLE_COLOR + board.get(position).getPieceTypeName() + RESET + " "); + Piece piece = board.get(position); + String pieceName = resolvePieceName(piece.getPieceType()); + System.out.print(AVAILABLE_COLOR + pieceName + RESET + " "); } else if (isAvailable) { System.out.print(AVAILABLE_COLOR + AVAILABLE_MARK + RESET); } else if (hasPiece) { Piece piece = board.get(position); - System.out.print(getColorByTeam(piece) + piece.getPieceTypeName() + RESET + " "); + String pieceName = resolvePieceName(piece.getPieceType()); + String color = getColorByTeam(piece.getTeam()); + System.out.print(color + pieceName + RESET + " "); } else { System.out.print(EMPTY_MARK); } } - private String getColorByTeam(Piece piece) { - if (piece.getTeam() == Team.CHO) { + private String resolvePieceName(PieceType pieceType) { + return switch (pieceType) { + case KING -> "왕"; + case SA -> "사"; + case SANG -> "상"; + case MA -> "마"; + case CHA -> "차"; + case PO -> "포"; + case ZOL -> "졸"; + }; + } + + private String getColorByTeam(Team team) { + if (team == Team.CHO) { return CHO_COLOR; } return HAN_COLOR; diff --git a/src/test/java/janggi/domain/PieceTest.java b/src/test/java/janggi/domain/PieceTest.java deleted file mode 100644 index 18a47a0de2..0000000000 --- a/src/test/java/janggi/domain/PieceTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package janggi.domain; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -public class PieceTest { - - @Test - @DisplayName("기물에는 초나라 졸이 있다.") - void 기물은_초나라_졸이_있음(){ - //given - Team cho = Team.CHO; - PieceType zol = PieceType.ZOL; - Piece piece = new Piece(cho,zol); - - //when & then - assertThat(piece.getTeamName()).isEqualTo("초나라"); - assertThat(piece.getPieceTypeName()).isEqualTo("졸"); - } -}