From d4bacf5b1f823a93087815c2ad7ea10bc70932f6 Mon Sep 17 00:00:00 2001 From: haechanmoon Date: Wed, 25 Mar 2026 13:53:56 +0900 Subject: [PATCH 01/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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/37] =?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 c6d763ace47bd7972bd1a2122547d84992fa2ae9 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Mon, 30 Mar 2026 23:17:15 +0900 Subject: [PATCH 19/37] =?UTF-8?q?test:=20=EC=8B=A4=ED=8C=A8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=8F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=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 | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index e3a3dbdecb..07677c4520 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.junit.jupiter.api.Assertions.assertThrows; import java.util.ArrayList; import java.util.List; @@ -518,7 +519,6 @@ public class BoardTest { @Test @DisplayName("포는 넘어가려는 목적지에 또 다른 포가 있으면, 포는 포를 포획할 수 없으므로 이동할 수 없다") void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { - //given Board board = new Board(); Position position = new Position(5,8); board.getBoard().put(position, new Piece(Team.CHO, PieceType.PO)); @@ -528,12 +528,9 @@ public class BoardTest { List rightAnswer = new ArrayList<>(upRoutes); - //when - List chaRoutesPositions = board.findAvailablePositions(position); - - //then - assertThat(chaRoutesPositions).hasSize(0) - .containsExactlyInAnyOrderElementsOf(rightAnswer); + assertThrows(IllegalArgumentException.class, () -> { + board.findAvailablePositions(position); + }); } @Test From 8bf002963f2f6c9296da520e85c1faa595d32736 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Tue, 31 Mar 2026 13:51:15 +0900 Subject: [PATCH 20/37] =?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=20=EB=B0=98?= =?UTF-8?q?=EB=B3=B5=EB=AC=B8=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=ED=98=84(?= =?UTF-8?q?=EC=83=81=EC=B0=A8=EB=A6=BC:=20=EB=A7=88=EC=83=81=EB=A7=88?= =?UTF-8?q?=EC=83=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 63 ++++++++-------------- src/main/java/janggi/domain/PieceType.java | 4 +- 2 files changed, 24 insertions(+), 43 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index a81b0a6a44..7716b0b141 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -10,47 +10,28 @@ public class 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)); + for(Team team:Team.values()) { + for(PieceType pieceType:PieceType.values()) { + List xPositions = pieceType.getXPositions(); + int yPosition = pieceType.getYPosition(); + if(team == Team.CHO) { + for(int xPosition:xPositions) { + Position position = new Position(xPosition, yPosition); + Piece piece = new Piece(team, pieceType); + board.put(position, piece); + } + } + + if(team == Team.HAN) { + int hanYPosition = 11 - yPosition; + for(int xPosition:xPositions) { + Position position = new Position(xPosition, hanYPosition); + Piece piece = new Piece(team, pieceType); + board.put(position, piece); + } + } + } + } } public Map getBoard() { diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index 7f06f17886..caeb27bbb7 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -12,8 +12,8 @@ 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()), + SANG("상", List.of(3, 8), 10, new SangMoveRule()), + MA("마", List.of(2, 7), 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()); From 2111fbf1efad7f2db9d535f8662b2a6c71a741fa Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Tue, 31 Mar 2026 14:06:00 +0900 Subject: [PATCH 21/37] =?UTF-8?q?refactor:=20y=EC=A2=8C=ED=91=9C=EB=A5=BC?= =?UTF-8?q?=20=EB=82=98=EB=9D=BC=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EA=B3=84?= =?UTF-8?q?=EC=82=B0=ED=95=98=EB=8A=94=20=EB=A1=9C=EC=A7=81=EC=9D=84=20tea?= =?UTF-8?q?m=EC=97=90=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 25 +++++++++---------------- src/main/java/janggi/domain/Team.java | 7 +++++++ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 7716b0b141..11d65f7d2a 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -14,26 +14,19 @@ public void initialize() { for(PieceType pieceType:PieceType.values()) { List xPositions = pieceType.getXPositions(); int yPosition = pieceType.getYPosition(); - if(team == Team.CHO) { - for(int xPosition:xPositions) { - Position position = new Position(xPosition, yPosition); - Piece piece = new Piece(team, pieceType); - board.put(position, piece); - } - } - - if(team == Team.HAN) { - int hanYPosition = 11 - yPosition; - for(int xPosition:xPositions) { - Position position = new Position(xPosition, hanYPosition); - Piece piece = new Piece(team, pieceType); - board.put(position, piece); - } - } + setPieces(team, pieceType, xPositions, yPosition); } } } + private void setPieces(Team team, PieceType pieceType, List xPositions, int yPosition) { + for(int xPosition: xPositions) { + Position position = new Position(xPosition, team.calculateYPosition(team, yPosition)); + Piece piece = new Piece(team, pieceType); + board.put(position, piece); + } + } + public Map getBoard() { return board; } diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/Team.java index 9d7c221835..6050254084 100644 --- a/src/main/java/janggi/domain/Team.java +++ b/src/main/java/janggi/domain/Team.java @@ -13,4 +13,11 @@ public enum Team { public String getName() { return name; } + + public int calculateYPosition(Team team, int yPosition) { + if(team == HAN) { + return 11 - yPosition; + } + return yPosition; + } } From 0587fe5763668c560524cec9c3b3a64898bbcb94 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Tue, 31 Mar 2026 14:31:07 +0900 Subject: [PATCH 22/37] =?UTF-8?q?refactor:=20PieceType=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EB=B3=B4=EB=93=9C=EC=97=90=20=ED=95=B4=EB=8B=B9=20=EA=B8=B0?= =?UTF-8?q?=EB=AC=BC=20=EB=B0=B0=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 14 ++++---------- src/main/java/janggi/domain/PieceType.java | 15 +++++++++++++++ src/main/java/janggi/domain/Team.java | 7 ------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 11d65f7d2a..811ea85c98 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -12,19 +12,13 @@ public class Board { public void initialize() { for(Team team:Team.values()) { for(PieceType pieceType:PieceType.values()) { - List xPositions = pieceType.getXPositions(); - int yPosition = pieceType.getYPosition(); - setPieces(team, pieceType, xPositions, yPosition); + pieceType.placeOnBoard(this, team); } } } - private void setPieces(Team team, PieceType pieceType, List xPositions, int yPosition) { - for(int xPosition: xPositions) { - Position position = new Position(xPosition, team.calculateYPosition(team, yPosition)); - Piece piece = new Piece(team, pieceType); - board.put(position, piece); - } + public void place(Position positoin, Piece piece) { + board.put(positoin, piece); } public Map getBoard() { @@ -181,7 +175,7 @@ public void validateDestination(Position movePiecePosition, Position destination } } - if(!hasPosition) { + if(hasPosition == false) { throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); } } diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index caeb27bbb7..3be9b77075 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -45,4 +45,19 @@ public int getYPosition() { public MoveRule getMoveRule() { return moveRule; } + + public void placeOnBoard(Board board, Team team) { + for(int xPosition:xPositions) { + Position position = new Position(xPosition, calculateYPositionByTeam(team)); + Piece piece = new Piece(team, this); + board.place(position, piece); + } + } + + private int calculateYPositionByTeam(Team team) { + if(team == Team.HAN) { + return 11 - yPosition; + } + return yPosition; + } } diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/Team.java index 6050254084..9d7c221835 100644 --- a/src/main/java/janggi/domain/Team.java +++ b/src/main/java/janggi/domain/Team.java @@ -13,11 +13,4 @@ public enum Team { public String getName() { return name; } - - public int calculateYPosition(Team team, int yPosition) { - if(team == HAN) { - return 11 - yPosition; - } - return yPosition; - } } From 8e93874f1b939d21e0541ac6b65b27d9ced9e714 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Tue, 31 Mar 2026 16:11:16 +0900 Subject: [PATCH 23/37] =?UTF-8?q?refactor:=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=B0=BE=EA=B8=B0=20=EA=B8=B0=EB=AC=BC=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 9 +++------ src/main/java/janggi/domain/Piece.java | 5 +++++ src/main/java/janggi/domain/PieceType.java | 16 ++++------------ 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 811ea85c98..69da5720bc 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -17,8 +17,8 @@ public void initialize() { } } - public void place(Position positoin, Piece piece) { - board.put(positoin, piece); + public void place(Position position, Piece piece) { + board.put(position, piece); } public Map getBoard() { @@ -27,11 +27,8 @@ public Map getBoard() { 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); diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 19175436d5..c17fb2d2b7 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.findRoutes(team); + } + @Override public boolean equals(Object o) { if (!(o instanceof Piece piece)) { diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index 3be9b77075..8ba5ab8b5c 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -34,18 +34,6 @@ public String getName() { return name; } - public List getXPositions() { - return xPositions; - } - - public int getYPosition() { - return yPosition; - } - - public MoveRule getMoveRule() { - return moveRule; - } - public void placeOnBoard(Board board, Team team) { for(int xPosition:xPositions) { Position position = new Position(xPosition, calculateYPositionByTeam(team)); @@ -60,4 +48,8 @@ private int calculateYPositionByTeam(Team team) { } return yPosition; } + + public List findRoutes(Team team) { + return moveRule.findRoutes(team); + } } From 5dc1bdc3297aa66dfba1d07c6c1ba2336ead00d7 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Tue, 31 Mar 2026 23:37:55 +0900 Subject: [PATCH 24/37] =?UTF-8?q?refactor:=20convertToPositions=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=B1=85=EC=9E=84=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/Board.java | 57 +++++----------------- src/main/java/janggi/domain/Direction.java | 12 +++-- src/main/java/janggi/domain/Position.java | 25 ++++++++-- src/main/java/janggi/domain/Route.java | 28 +++++++++-- 4 files changed, 64 insertions(+), 58 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 69da5720bc..4fa26dc10e 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -82,60 +82,28 @@ private boolean hasObstacleOnRoute(List route) { } private Map> convertToPositions(Position position, Piece piece, List routes) { - Map> result = new HashMap<>(); - if(piece.isCha()|| piece.isPo()) { - return convertToContinuousRoutes(position, routes, result); + return convertToContinuousRoutes(position, routes); } - - return convertToFixedRoutes(position, routes, result); + return convertToFixedRoutes(position, routes); } - 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); + private Map> convertToFixedRoutes(Position position, List routes) { + Map> result = new HashMap<>(); + for(Route route:routes) { + List positionRoute = route.applyDirections(position); + if(positionRoute.isEmpty()) { + continue; } + result.put(positionRoute.getLast(), positionRoute); } return result; } - private Map> convertToContinuousRoutes(Position position, List routes, Map> result) { + private Map> convertToContinuousRoutes(Position position, List routes) { + Map> result = new HashMap<>(); 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(); - } - } + route.applyContinuousDirections(position, result); } return result; } @@ -171,7 +139,6 @@ public void validateDestination(Position movePiecePosition, Position destination break; } } - if(hasPosition == false) { throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); } diff --git a/src/main/java/janggi/domain/Direction.java b/src/main/java/janggi/domain/Direction.java index 4e08a73f13..01dcfb2929 100644 --- a/src/main/java/janggi/domain/Direction.java +++ b/src/main/java/janggi/domain/Direction.java @@ -1,5 +1,9 @@ package janggi.domain; +import java.util.List; +import java.util.Map; +import java.util.Optional; + public enum Direction { UP(0, -1), DOWN(0, 1), LEFT(-1, 0), RIGHT(1, 0), UP_LEFT(-1, -1), UP_RIGHT(1, -1), DOWN_LEFT(-1, 1), DOWN_RIGHT(1, 1); @@ -12,11 +16,11 @@ public enum Direction { this.y = y; } - public int getX() { - return x; + public Optional nextPosition(Position position) { + return position.applyDirection(x, y); } - public int getY() { - return y; + public void nextContinuousPosition(Position position, Map> continuousRoute) { + position.applyContinuousDirection(x, y, continuousRoute); } } diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java index 539efcacc3..ae84d36bd6 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/Position.java @@ -1,6 +1,10 @@ package janggi.domain; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; public class Position { @@ -23,16 +27,27 @@ private void validateBoundary(int x, int y) { } } - public static boolean isInsideBoundary(int x, int y) { + public boolean isInsideBoundary(int x, int y) { return x >= MIN_X && x <= MAX_X && y >= MIN_Y && y <= MAX_Y; } - public int getX() { - return x; + public Optional applyDirection(int dx, int dy) { + if(isInsideBoundary(x + dx, y + dy)) { + return Optional.of(new Position(x + dx, y + dy)); + } + return Optional.empty(); } - public int getY() { - return y; + public void applyContinuousDirection(int dx, int dy, Map> continuousRoute) { + List result = new ArrayList<>(); + int nextX = x + dx; + int nextY = y + dy; + while(isInsideBoundary(nextX, nextY)) { + result.add(new Position(nextX, nextY)); + continuousRoute.put(new Position(nextX, nextY), new ArrayList<>(result)); + nextX += dx; + nextY += dy; + } } @Override diff --git a/src/main/java/janggi/domain/Route.java b/src/main/java/janggi/domain/Route.java index d92b053e5b..d4ed719679 100644 --- a/src/main/java/janggi/domain/Route.java +++ b/src/main/java/janggi/domain/Route.java @@ -1,7 +1,10 @@ package janggi.domain; +import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.Optional; public class Route { @@ -11,6 +14,27 @@ public Route(List routes) { this.routes = routes; } + public List applyDirections(Position position) { + List routePositions = new ArrayList<>(); + Position startPosition = position; + for(Direction direction:routes) { + Optional nextPosition = direction.nextPosition(startPosition); + if(nextPosition.isEmpty()) { + return new ArrayList<>(); + } + startPosition = nextPosition.get(); + routePositions.add(startPosition); + } + return routePositions; + } + + public void applyContinuousDirections(Position position, Map> continuousRoutes) { + Position startPosition = position; + for(Direction direction:routes) { + direction.nextContinuousPosition(startPosition, continuousRoutes); + } + } + @Override public boolean equals(Object o) { if (!(o instanceof Route route)) { @@ -23,8 +47,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hashCode(routes); } - - public List getRoutes() { - return routes; - } } From 7a995a56cc99efaef4b9839908611c5b98018067 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 01:14:33 +0900 Subject: [PATCH 25/37] =?UTF-8?q?refactor:=20=EC=9D=B4=EC=9A=A9=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=ED=95=9C=20=EC=A2=8C=ED=91=9C=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 98 +++++++++++++------------- src/main/java/janggi/domain/Piece.java | 5 +- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 4fa26dc10e..6e7b8e05c5 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -32,35 +32,7 @@ public List findAvailablePositions(Position position) { 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; - } - } - availablePositions.add(destination); - } - } + List availablePositions = calculateAvailablePositions(piece, routePositions); if(availablePositions.isEmpty()) { throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); @@ -68,8 +40,32 @@ public List findAvailablePositions(Position position) { return availablePositions; } - private boolean isDestinationIsMyTeam(Piece destinationPiece, Piece piece) { - return destinationPiece.getTeam() == piece.getTeam(); + public void movePiece(Position movePiecePosition, Position destination) { + Piece piece = board.get(movePiecePosition); + board.remove(movePiecePosition); + 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 == false) { + throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); + } + } + + private boolean isDestinationIsMyTeam(Position destination, Piece piece) { + Piece destinationPiece = board.get(destination); + if(board.containsKey(destination)) { + return piece.isSameTeam(destinationPiece); + } + return false; } private boolean hasObstacleOnRoute(List route) { @@ -108,8 +104,12 @@ private Map> convertToContinuousRoutes(Position positio return result; } - private boolean isDestinationIsPo(Piece destinationPiece) { - return destinationPiece.getPieceType() == PieceType.PO; + private boolean isDestinationIsPo(Position destination) { + Piece destinationPiece = board.get(destination); + if(board.containsKey(destination)) { + return destinationPiece.isPo(); + } + return false; } private boolean hasOneObstacleAndNotPo(List route) { @@ -121,26 +121,28 @@ private boolean hasOneObstacleAndNotPo(List route) { obstacles.add(board.get(route.get(i))); } } - return count == 1 && obstacles.getFirst().getPieceType() != PieceType.PO; + return count == 1 && !obstacles.getFirst().isPo(); } - public void movePiece(Position movePiecePosition, Position destination) { - Piece piece = board.get(movePiecePosition); - board.remove(movePiecePosition); - board.put(destination, piece); - } + private List calculateAvailablePositions(Piece piece, Map> routePositions) { + List result = new ArrayList<>(); + for (Map.Entry> entry : routePositions.entrySet()) { + Position destination = entry.getKey(); + List route = entry.getValue(); - 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(canMove(piece, route, destination)){ + result.add(destination); } } - if(hasPosition == false) { - throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); + return result; + } + + private boolean canMove(Piece movePiece, List route, Position destination) { + if(movePiece.isPo()) { + return hasOneObstacleAndNotPo(route) + && !isDestinationIsMyTeam(destination, movePiece) + && !isDestinationIsPo(destination); } + return !hasObstacleOnRoute(route) && !isDestinationIsMyTeam(destination, movePiece); } } diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index c17fb2d2b7..4070065121 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -21,7 +21,6 @@ public String getPieceTypeName() { return pieceType.getName(); } - public PieceType getPieceType() { return pieceType; } @@ -42,6 +41,10 @@ public List findRoutes() { return pieceType.findRoutes(team); } + public boolean isSameTeam(Piece other) { + return team == other.team; + } + @Override public boolean equals(Object o) { if (!(o instanceof Piece piece)) { From 09ebf2cbd33c190d50656b82dbb1b1ca6a220f69 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 13:29:07 +0900 Subject: [PATCH 26/37] =?UTF-8?q?fix:=20=EB=8F=84=EC=B0=A9=EC=A7=80=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A9=94=EC=84=9C=EB=93=9C=EC=97=90?= =?UTF-8?q?=EC=84=9C=20equals=EB=A1=9C=20=EB=B9=84=EA=B5=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/janggi/domain/Board.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index 6e7b8e05c5..a671c484f7 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -50,7 +50,7 @@ public void validateDestination(Position movePiecePosition, Position destination List availablePositions = findAvailablePositions(movePiecePosition); boolean hasPosition = false; for(Position position:availablePositions) { - if (position == destination) { + if (position.equals(destination)) { hasPosition = true; break; } From cd99a6a18e55efd030621394564b1a3a0245a571 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 14:36:10 +0900 Subject: [PATCH 27/37] =?UTF-8?q?test(PieceTest):=20=EC=B0=A8=EC=9D=B8?= =?UTF-8?q?=EC=A7=80,=20=ED=8F=AC=EC=9D=B8=EC=A7=80,=20=EA=B0=99=EC=9D=80?= =?UTF-8?q?=20=ED=8C=80=EC=9D=B8=EC=A7=80=20=ED=99=95=EC=9D=B8=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/PieceTest.java | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/src/test/java/janggi/domain/PieceTest.java b/src/test/java/janggi/domain/PieceTest.java index 18a47a0de2..7e1ef483db 100644 --- a/src/test/java/janggi/domain/PieceTest.java +++ b/src/test/java/janggi/domain/PieceTest.java @@ -1,6 +1,8 @@ package janggi.domain; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -19,4 +21,54 @@ public class PieceTest { assertThat(piece.getTeamName()).isEqualTo("초나라"); assertThat(piece.getPieceTypeName()).isEqualTo("졸"); } + + @Test + @DisplayName("기물이 차인지 확인할 수 있다") + void 기물이_차인지_확인() { + // given + Piece cha = new Piece(Team.CHO, PieceType.CHA); + Piece zol = new Piece(Team.HAN, PieceType.ZOL); + + // when + boolean isCha = cha.isCha(); + boolean isCha2 = zol.isCha(); + + //then + assertThat(isCha).isTrue(); + assertThat(isCha2).isFalse(); + } + + @Test + @DisplayName("기물이 포인지 확인할 수 있다") + void 기물이_포인지_확인() { + // given + Piece po = new Piece(Team.CHO, PieceType.PO); + Piece zol = new Piece(Team.HAN, PieceType.ZOL); + + // when + boolean isPo = po.isPo(); + boolean isPo2 = zol.isPo(); + + //then + assertThat(isPo).isTrue(); + assertThat(isPo2).isFalse(); + } + + @Test + @DisplayName("같은 팀인지 확인할 수 있다") + void 같은_팀인지_확인() { + // given + Piece sameTeam1 = new Piece(Team.CHO, PieceType.CHA); + Piece sameTeam2 = new Piece(Team.CHO, PieceType.MA); + Piece differentTeam1 = new Piece(Team.CHO, PieceType.PO); + Piece differentTeam2 = new Piece(Team.HAN, PieceType.KING); + + // when + boolean same = sameTeam1.isSameTeam(sameTeam2); + boolean different = differentTeam1.isSameTeam(differentTeam2); + + // then + assertThat(same).isTrue(); + assertThat(different).isFalse(); + } } From 3a0ad8f381e886db593faec3f66a16a82f485448 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 15:07:56 +0900 Subject: [PATCH 28/37] =?UTF-8?q?test(PositionTest):=20=EB=B0=A9=ED=96=A5?= =?UTF-8?q?=20=EC=A0=81=EC=9A=A9=20=ED=9B=84=20=EC=A2=8C=ED=91=9C=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=20=ED=99=95=EC=9D=B8=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/janggi/domain/PositionTest.java | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/test/java/janggi/domain/PositionTest.java diff --git a/src/test/java/janggi/domain/PositionTest.java b/src/test/java/janggi/domain/PositionTest.java new file mode 100644 index 0000000000..77b0f4a731 --- /dev/null +++ b/src/test/java/janggi/domain/PositionTest.java @@ -0,0 +1,67 @@ +package janggi.domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PositionTest { + + @Test + @DisplayName("보드 범위 내에 있는 좌표라면 좌표를 반환한다") + void 보드_범위_내_좌표_반환() { + // given + Position position = new Position(1, 9); + + // when + Optional result = position.applyDirection(0, 1); + + // then + assertThat(result).isPresent().contains(new Position(1,10)); + } + + @Test + @DisplayName("보드 범위 밖에 있는 y좌표라면 좌표를 Optional") + void 보드_범위_밖_y좌표_반환_() { + // given + Position position = new Position(1, 10); + + // when + Optional result = position.applyDirection(0, 1); + + // then + assertThat(result).isEmpty(); + } + + @Test + @DisplayName("보드 범위 밖에 있는 x좌표라면 좌표를 Optional") + void 보드_범위_밖_x좌표_반환_() { + // given + Position position = new Position(9, 1); + + // when + Optional result = position.applyDirection(1, 0); + + // then + assertThat(result).isEmpty(); + } + + @Test + @DisplayName("보드 범위 내에 있는 좌표라면 연속적으로 추가할 수 있다") + void 보드_범위_내에_연속_좌표() { + // given + Position position = new Position(1, 5); + Map> continuousRoute = new HashMap<>(); + + // when + position.applyContinuousDirection(0, 1, continuousRoute); + + // then + assertThat(continuousRoute).hasSize(5) + .containsKey(new Position(1,10)); + } +} From e0bc2e98c73f4edbc431d0912b0cb5a90607f5eb Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 15:20:26 +0900 Subject: [PATCH 29/37] =?UTF-8?q?refactor:=20=EB=A9=94=EC=84=9C=EB=93=9C?= =?UTF-8?q?=20=EB=B0=B0=EC=B9=98=20=EC=88=9C=EC=84=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/Piece.java | 4 ---- src/main/java/janggi/domain/PieceType.java | 12 ++++++------ src/main/java/janggi/domain/Position.java | 20 ++++++++++---------- src/main/java/janggi/view/OutputView.java | 14 ++++++++------ 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/main/java/janggi/domain/Piece.java b/src/main/java/janggi/domain/Piece.java index 4070065121..17c784be9d 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/Piece.java @@ -21,10 +21,6 @@ public String getPieceTypeName() { return pieceType.getName(); } - 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 8ba5ab8b5c..cd29c6011f 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -35,21 +35,21 @@ public String getName() { } public void placeOnBoard(Board board, Team team) { - for(int xPosition:xPositions) { + for (int xPosition : xPositions) { Position position = new Position(xPosition, calculateYPositionByTeam(team)); Piece piece = new Piece(team, this); board.place(position, piece); } } + public List findRoutes(Team team) { + return moveRule.findRoutes(team); + } + private int calculateYPositionByTeam(Team team) { - if(team == Team.HAN) { + if (team == Team.HAN) { return 11 - yPosition; } return yPosition; } - - public List findRoutes(Team team) { - return moveRule.findRoutes(team); - } } diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/Position.java index ae84d36bd6..00aa36c93a 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/Position.java @@ -21,16 +21,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 boolean isInsideBoundary(int x, int y) { - return x >= MIN_X && x <= MAX_X && y >= MIN_Y && y <= MAX_Y; - } - public Optional applyDirection(int dx, int dy) { if(isInsideBoundary(x + dx, y + dy)) { return Optional.of(new Position(x + dx, y + dy)); @@ -50,6 +40,16 @@ public void applyContinuousDirection(int dx, int dy, Map MAX_X || y < MIN_Y || y > MAX_Y) { + throw new IllegalArgumentException("[ERROR] 보드 범위를 벗어났습니다."); + } + } + + private boolean isInsideBoundary(int x, int y) { + return x >= MIN_X && x <= MAX_X && y >= MIN_Y && y <= MAX_Y; + } + @Override public boolean equals(Object o) { if (!(o instanceof Position position)) { diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index 8d26cc8376..c522921111 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -77,13 +77,8 @@ public void printAvailablePositions(Map board, List a } } - private String getColorByTeam(Piece piece) { - if(piece.getTeam() == Team.CHO) return CHO_COLOR; - return HAN_COLOR; - } - public void printTurnMessage(boolean isChoTurn) { - if(isChoTurn) { + if (isChoTurn) { System.out.println(OutputView.CHO_COLOR + "\n현재 초나라 차례입니다" + OutputView.RESET); } else { System.out.println(OutputView.HAN_COLOR + "\n한나라 차례입니다" + OutputView.RESET); @@ -97,4 +92,11 @@ public void printMoveInfo() { public void printMoveChoiceInfo() { System.out.println("이동하고자 하는 목표 지점의 좌표를 입력하세요."); } + + private String getColorByTeam(Piece piece) { + if (piece.getTeam() == Team.CHO) { + return CHO_COLOR; + } + return HAN_COLOR; + } } From e46df4287947a549ab135b99fb63d4329462934f Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 15:45:51 +0900 Subject: [PATCH 30/37] =?UTF-8?q?refactor(JanggiController):=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../janggi/controller/JanggiController.java | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index 56a4105d74..cee84a7779 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -20,32 +20,44 @@ public void run() { outputView.printBoard(board.getBoard()); while (true) { - outputView.printTurnMessage(isChoTurn); + playGame(isChoTurn, board); - Position movePiecePosition = doLoop(() -> { - outputView.printMoveInfo(); - Position position = inputView.readPosition(); - board.findAvailablePositions(position); - return position; - }); + isChoTurn = changeTurn(isChoTurn); + } + } - List availablePositions = board.findAvailablePositions(movePiecePosition); + private void playGame(boolean isChoTurn, Board board) { + outputView.printTurnMessage(isChoTurn); - outputView.printAvailablePositions(board.getBoard(), availablePositions); + Position movePiecePosition = doLoop(() -> askMovePiecePosition(board)); - Position movePosition = doLoop(() -> { - outputView.printMoveChoiceInfo(); - Position position = inputView.readPosition(); - board.validateDestination(movePiecePosition, position); - return position; - }); + List availablePositions = board.findAvailablePositions(movePiecePosition); - board.movePiece(movePiecePosition, movePosition); + outputView.printAvailablePositions(board.getBoard(), availablePositions); - outputView.printBoard(board.getBoard()); + Position movePosition = doLoop(() -> askMovePosition(board, movePiecePosition)); - isChoTurn = !isChoTurn; - } + board.movePiece(movePiecePosition, movePosition); + + outputView.printBoard(board.getBoard()); + } + + private boolean changeTurn(boolean isChoTurn) { + return !isChoTurn; + } + + private Position askMovePosition(Board board, Position movePiecePosition) { + outputView.printMoveChoiceInfo(); + Position position = inputView.readPosition(); + board.validateDestination(movePiecePosition, position); + return position; + } + + private Position askMovePiecePosition(Board board) { + outputView.printMoveInfo(); + Position position = inputView.readPosition(); + board.findAvailablePositions(position); + return position; } private T doLoop(Supplier inputFunction) { From f300e60f762478f8f928b12e125e1840d597e638 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Wed, 1 Apr 2026 19:22:30 +0900 Subject: [PATCH 31/37] =?UTF-8?q?feat:=20=EC=83=81=EC=B0=A8=EB=A6=BC=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=20=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 | 18 +- src/main/java/janggi/domain/Board.java | 37 ++-- .../java/janggi/domain/BoardFormation.java | 54 ++++++ src/main/java/janggi/domain/PieceType.java | 12 +- src/main/java/janggi/view/InputView.java | 5 + src/main/java/janggi/view/OutputView.java | 8 + src/test/java/janggi/domain/BoardTest.java | 169 +++++++++++------- 7 files changed, 218 insertions(+), 85 deletions(-) create mode 100644 src/main/java/janggi/domain/BoardFormation.java diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index cee84a7779..19c1f0c8dd 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -1,7 +1,9 @@ package janggi.controller; import janggi.domain.Board; +import janggi.domain.BoardFormation; import janggi.domain.Position; +import janggi.domain.Team; import janggi.view.InputView; import janggi.view.OutputView; import java.util.List; @@ -14,7 +16,9 @@ public class JanggiController { public void run() { Board board = new Board(); - board.initialize(); + + choiceBoardFormation(board); + boolean isChoTurn = true; outputView.printBoard(board.getBoard()); @@ -26,6 +30,18 @@ public void run() { } } + private void choiceBoardFormation(Board board) { + askBoardFormation(board, Team.HAN); + askBoardFormation(board, Team.CHO); + } + + private void askBoardFormation(Board board, Team team) { + outputView.printBoardFormation(team); + int boardFormationChoice = inputView.readBoardFormationChoice(); + BoardFormation hanFormation = BoardFormation.selectByChoice(boardFormationChoice); + board.initializeByFormation(hanFormation, team); + } + private void playGame(boolean isChoTurn, Board board) { outputView.printTurnMessage(isChoTurn); diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/Board.java index a671c484f7..7990715e87 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/Board.java @@ -9,11 +9,10 @@ public class Board { private final Map board = new HashMap<>(); - public void initialize() { - for(Team team:Team.values()) { - for(PieceType pieceType:PieceType.values()) { - pieceType.placeOnBoard(this, team); - } + public void initializeByFormation(BoardFormation boardFormation, Team team) { + for (PieceType pieceType : PieceType.values()) { + pieceType.changeXPositionsByFormation(boardFormation); + pieceType.placeOnBoard(this, team); } } @@ -34,7 +33,7 @@ public List findAvailablePositions(Position position) { List availablePositions = calculateAvailablePositions(piece, routePositions); - if(availablePositions.isEmpty()) { + if (availablePositions.isEmpty()) { throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); } return availablePositions; @@ -49,20 +48,20 @@ 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) { + for (Position position : availablePositions) { if (position.equals(destination)) { hasPosition = true; break; } } - if(hasPosition == false) { + if (hasPosition == false) { throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); } } private boolean isDestinationIsMyTeam(Position destination, Piece piece) { Piece destinationPiece = board.get(destination); - if(board.containsKey(destination)) { + if (board.containsKey(destination)) { return piece.isSameTeam(destinationPiece); } return false; @@ -78,7 +77,7 @@ private boolean hasObstacleOnRoute(List route) { } private Map> convertToPositions(Position position, Piece piece, List routes) { - if(piece.isCha()|| piece.isPo()) { + if (piece.isCha() || piece.isPo()) { return convertToContinuousRoutes(position, routes); } return convertToFixedRoutes(position, routes); @@ -86,9 +85,9 @@ private Map> convertToPositions(Position position, Piec private Map> convertToFixedRoutes(Position position, List routes) { Map> result = new HashMap<>(); - for(Route route:routes) { + for (Route route : routes) { List positionRoute = route.applyDirections(position); - if(positionRoute.isEmpty()) { + if (positionRoute.isEmpty()) { continue; } result.put(positionRoute.getLast(), positionRoute); @@ -98,7 +97,7 @@ private Map> convertToFixedRoutes(Position position, Li private Map> convertToContinuousRoutes(Position position, List routes) { Map> result = new HashMap<>(); - for(Route route: routes) { + for (Route route : routes) { route.applyContinuousDirections(position, result); } return result; @@ -106,7 +105,7 @@ private Map> convertToContinuousRoutes(Position positio private boolean isDestinationIsPo(Position destination) { Piece destinationPiece = board.get(destination); - if(board.containsKey(destination)) { + if (board.containsKey(destination)) { return destinationPiece.isPo(); } return false; @@ -115,9 +114,9 @@ private boolean isDestinationIsPo(Position destination) { 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))); } } @@ -130,7 +129,7 @@ private List calculateAvailablePositions(Piece piece, Map route = entry.getValue(); - if(canMove(piece, route, destination)){ + if (canMove(piece, route, destination)) { result.add(destination); } } @@ -138,7 +137,7 @@ private List calculateAvailablePositions(Piece piece, Map route, Position destination) { - if(movePiece.isPo()) { + if (movePiece.isPo()) { return hasOneObstacleAndNotPo(route) && !isDestinationIsMyTeam(destination, movePiece) && !isDestinationIsPo(destination); diff --git a/src/main/java/janggi/domain/BoardFormation.java b/src/main/java/janggi/domain/BoardFormation.java new file mode 100644 index 0000000000..8ff7375e3f --- /dev/null +++ b/src/main/java/janggi/domain/BoardFormation.java @@ -0,0 +1,54 @@ +package janggi.domain; + +import java.util.List; + +public enum BoardFormation { + MA_SANG_MA_SANG(1, "마상마상", List.of(2, 7), List.of(3, 8)), + MA_SANG_SANG_MA(2, "마상상마", List.of(2, 8), List.of(3, 7)), + SANG_MA_SANG_MA(3, "상마상마", List.of(3, 8), List.of(2, 7)), + SANG_MA_MA_SANG(4, "상마마상", List.of(3, 7), List.of(2, 8)); + + private final int choice; + private final String name; + private final List maXPositions; + private final List sangXPositions; + + BoardFormation(int choice, String name, List maXPositions, List sangXPositions) { + this.choice = choice; + this.name = name; + this.maXPositions = maXPositions; + this.sangXPositions = sangXPositions; + } + + public static BoardFormation selectByChoice(int choice) { + if (choice == 1) { + return MA_SANG_MA_SANG; + } + if (choice == 2) { + return MA_SANG_SANG_MA; + } + if (choice == 3) { + return SANG_MA_SANG_MA; + } + if (choice == 4) { + return SANG_MA_MA_SANG; + } + throw new IllegalArgumentException("[ERROR] 잘못된 번호를 입력하셨습니다."); + } + + public int getChoice() { + return choice; + } + + public String getName() { + return name; + } + + public List getMaXPositions() { + return maXPositions; + } + + public List getSangXPositions() { + return sangXPositions; + } +} diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index cd29c6011f..e4885dc242 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -19,9 +19,9 @@ public enum PieceType { 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; + private List xPositions; PieceType(String name, List xPositions, int yPosition, MoveRule moveRule) { this.name = name; @@ -52,4 +52,14 @@ private int calculateYPositionByTeam(Team team) { } return yPosition; } + + public void changeXPositionsByFormation(BoardFormation boardFormation) { + if (this == MA) { + xPositions = boardFormation.getMaXPositions(); + } + + if (this == SANG) { + xPositions = boardFormation.getSangXPositions(); + } + } } diff --git a/src/main/java/janggi/view/InputView.java b/src/main/java/janggi/view/InputView.java index 52f67e5ef6..cff7f4865f 100644 --- a/src/main/java/janggi/view/InputView.java +++ b/src/main/java/janggi/view/InputView.java @@ -13,4 +13,9 @@ public Position readPosition() { String[] position = input.split(" "); return new Position(Integer.parseInt(position[0]), Integer.parseInt(position[1])); } + + public int readBoardFormationChoice() { + System.out.println("상차림 번호를 입력하세요"); + return Integer.parseInt(scanner.nextLine()); + } } diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index c522921111..1e3b9b1412 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -1,5 +1,6 @@ package janggi.view; +import janggi.domain.BoardFormation; import janggi.domain.Piece; import janggi.domain.Position; import janggi.domain.Team; @@ -99,4 +100,11 @@ private String getColorByTeam(Piece piece) { } return HAN_COLOR; } + + public void printBoardFormation(Team team) { + System.out.printf("%s 상차림을 선택하세요.%n", team.getName()); + for (BoardFormation boardFormation : BoardFormation.values()) { + System.out.printf("%d. %s%n", boardFormation.getChoice(), boardFormation.getName()); + } + } } diff --git a/src/test/java/janggi/domain/BoardTest.java b/src/test/java/janggi/domain/BoardTest.java index 07677c4520..cb021deabe 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/BoardTest.java @@ -18,35 +18,76 @@ 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){ + @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); + BoardFormation hanFormation = BoardFormation.MA_SANG_MA_SANG; + BoardFormation choFormation = BoardFormation.MA_SANG_MA_SANG; + Position position = new Position(x, y); + Piece piece = new Piece(team, pieceType); //when - Map checkZol = board.getBoard(); + board.initializeByFormation(hanFormation, Team.HAN); + board.initializeByFormation(choFormation, Team.CHO); + Map checkPiece = board.getBoard(); //then - assertThat(checkZol.get(position)).isEqualTo(zol); + assertThat(checkPiece.get(position)).isEqualTo(piece); + } + + @ParameterizedTest + @CsvSource({ + + "CHO,KING,5,9", + "CHO,SA,4,10", "CHO,SA,6,10", + "CHO,SANG,2,10", "CHO,SANG,7,10", + "CHO,MA,3,10", "CHO,MA,8,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(); + BoardFormation hanFormation = BoardFormation.MA_SANG_MA_SANG; + BoardFormation choFormation = BoardFormation.SANG_MA_SANG_MA; + Position position = new Position(x, y); + Piece piece = new Piece(team, pieceType); + + // when + board.initializeByFormation(hanFormation, Team.HAN); + board.initializeByFormation(choFormation, Team.CHO); + Map checkPiece = board.getBoard(); + + // then + assertThat(checkPiece.get(position)).isEqualTo(piece); } @Test @@ -54,7 +95,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); @@ -73,7 +114,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)); @@ -93,7 +134,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); @@ -101,8 +142,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 @@ -118,15 +159,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 @@ -142,16 +183,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 @@ -167,7 +208,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); @@ -175,8 +216,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 @@ -192,16 +233,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 @@ -217,15 +258,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 @@ -241,16 +282,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 @@ -266,7 +307,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); @@ -288,7 +329,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); @@ -310,7 +351,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); @@ -329,11 +370,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); @@ -358,7 +399,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)); @@ -383,7 +424,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)); @@ -410,7 +451,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), @@ -440,11 +481,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( @@ -469,9 +510,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) ); @@ -498,9 +539,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,10 +561,10 @@ public class BoardTest { @DisplayName("포는 넘어가려는 목적지에 또 다른 포가 있으면, 포는 포를 포획할 수 없으므로 이동할 수 없다") void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { 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)); + 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); @@ -538,10 +579,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 063b6a7b68ed234eb1ff4a83d4c005e0a509f7fd Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Thu, 2 Apr 2026 15:11:31 +0900 Subject: [PATCH 32/37] =?UTF-8?q?refactor:=20BoardInitiator=EC=97=90?= =?UTF-8?q?=EA=B2=8C=20=EB=B3=B4=EB=93=9C=20=EC=B4=88=EA=B8=B0=ED=99=94=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=20=EB=84=98=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존에 PieceType에서 가지고 있던 초기 좌표를 BoardInitiator가 가지고 있도록 변경 --- .../janggi/controller/JanggiController.java | 10 +- src/main/java/janggi/domain/PieceType.java | 45 ++------- .../java/janggi/domain/{ => board}/Board.java | 12 +-- .../domain/{ => board}/BoardFormation.java | 2 +- .../janggi/domain/board/BoardInitiator.java | 73 +++++++++++++++ src/main/java/janggi/view/OutputView.java | 2 +- .../domain/board/BoardInitiatorTest.java | 92 +++++++++++++++++++ .../janggi/domain/{ => board}/BoardTest.java | 85 +---------------- 8 files changed, 190 insertions(+), 131 deletions(-) rename src/main/java/janggi/domain/{ => board}/Board.java (94%) rename src/main/java/janggi/domain/{ => board}/BoardFormation.java (98%) create mode 100644 src/main/java/janggi/domain/board/BoardInitiator.java create mode 100644 src/test/java/janggi/domain/board/BoardInitiatorTest.java rename src/test/java/janggi/domain/{ => board}/BoardTest.java (87%) diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index 19c1f0c8dd..1150c646a6 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -1,9 +1,10 @@ package janggi.controller; -import janggi.domain.Board; -import janggi.domain.BoardFormation; import janggi.domain.Position; import janggi.domain.Team; +import janggi.domain.board.Board; +import janggi.domain.board.BoardFormation; +import janggi.domain.board.BoardInitiator; import janggi.view.InputView; import janggi.view.OutputView; import java.util.List; @@ -13,6 +14,7 @@ public class JanggiController { private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); + private final BoardInitiator boardInitiator = new BoardInitiator(); public void run() { Board board = new Board(); @@ -38,8 +40,8 @@ private void choiceBoardFormation(Board board) { private void askBoardFormation(Board board, Team team) { outputView.printBoardFormation(team); int boardFormationChoice = inputView.readBoardFormationChoice(); - BoardFormation hanFormation = BoardFormation.selectByChoice(boardFormationChoice); - board.initializeByFormation(hanFormation, team); + BoardFormation formation = BoardFormation.selectByChoice(boardFormationChoice); + boardInitiator.initializeByFormation(board, formation, team); } private void playGame(boolean isChoTurn, Board board) { diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/PieceType.java index e4885dc242..dc9e3d9c79 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/PieceType.java @@ -10,23 +10,19 @@ 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, 8), 10, new SangMoveRule()), - MA("마", List.of(2, 7), 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 int yPosition; private final MoveRule moveRule; - private List xPositions; - 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,32 +30,7 @@ public String getName() { return name; } - public void placeOnBoard(Board board, Team team) { - for (int xPosition : xPositions) { - Position position = new Position(xPosition, calculateYPositionByTeam(team)); - Piece piece = new Piece(team, this); - board.place(position, piece); - } - } - public List findRoutes(Team team) { return moveRule.findRoutes(team); } - - private int calculateYPositionByTeam(Team team) { - if (team == Team.HAN) { - return 11 - yPosition; - } - return yPosition; - } - - public void changeXPositionsByFormation(BoardFormation boardFormation) { - if (this == MA) { - xPositions = boardFormation.getMaXPositions(); - } - - if (this == SANG) { - xPositions = boardFormation.getSangXPositions(); - } - } } diff --git a/src/main/java/janggi/domain/Board.java b/src/main/java/janggi/domain/board/Board.java similarity index 94% rename from src/main/java/janggi/domain/Board.java rename to src/main/java/janggi/domain/board/Board.java index 7990715e87..d4f375c8e9 100644 --- a/src/main/java/janggi/domain/Board.java +++ b/src/main/java/janggi/domain/board/Board.java @@ -1,5 +1,8 @@ -package janggi.domain; +package janggi.domain.board; +import janggi.domain.Piece; +import janggi.domain.Position; +import janggi.domain.Route; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -9,13 +12,6 @@ public class Board { private final Map board = new HashMap<>(); - public void initializeByFormation(BoardFormation boardFormation, Team team) { - for (PieceType pieceType : PieceType.values()) { - pieceType.changeXPositionsByFormation(boardFormation); - pieceType.placeOnBoard(this, team); - } - } - public void place(Position position, Piece piece) { board.put(position, piece); } diff --git a/src/main/java/janggi/domain/BoardFormation.java b/src/main/java/janggi/domain/board/BoardFormation.java similarity index 98% rename from src/main/java/janggi/domain/BoardFormation.java rename to src/main/java/janggi/domain/board/BoardFormation.java index 8ff7375e3f..92f2d0ee46 100644 --- a/src/main/java/janggi/domain/BoardFormation.java +++ b/src/main/java/janggi/domain/board/BoardFormation.java @@ -1,4 +1,4 @@ -package janggi.domain; +package janggi.domain.board; import java.util.List; diff --git a/src/main/java/janggi/domain/board/BoardInitiator.java b/src/main/java/janggi/domain/board/BoardInitiator.java new file mode 100644 index 0000000000..c6b7b46c9e --- /dev/null +++ b/src/main/java/janggi/domain/board/BoardInitiator.java @@ -0,0 +1,73 @@ +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; + +public class BoardInitiator { + + private static final int MAX_Y = 11; + + private final Map> defaultXPositions = Map.of( + PieceType.KING, List.of(5), + PieceType.SA, List.of(4, 6), + PieceType.CHA, List.of(1, 9), + PieceType.PO, List.of(2, 8), + PieceType.ZOL, List.of(1, 3, 5, 7, 9) + ); + + private final Map defaultYPosition = Map.of( + PieceType.KING, 9, + PieceType.SA, 10, + PieceType.SANG, 10, + PieceType.MA, 10, + PieceType.CHA, 10, + PieceType.PO, 8, + PieceType.ZOL, 7 + ); + + public void initializeByFormation(Board board, BoardFormation formation, Team team) { + Map> xPositions = initXPositionsByFormation(formation); + placeByPieceType(board, xPositions, team); + } + + private Map> initXPositionsByFormation(BoardFormation formation) { + Map> result = new HashMap<>(); + for (PieceType pieceType : PieceType.values()) { + if (pieceType == PieceType.MA) { + result.put(pieceType, formation.getMaXPositions()); + continue; + } + if (pieceType == PieceType.SANG) { + result.put(pieceType, formation.getSangXPositions()); + continue; + } + result.put(pieceType, defaultXPositions.get(pieceType)); + } + return result; + } + + private void placeByPieceType(Board board, Map> hanXPositions, Team team) { + for (PieceType pieceType : PieceType.values()) { + placeByPieceType(board, hanXPositions, team, pieceType); + } + } + + private void placeByPieceType(Board board, Map> hanXPositions, Team team, + PieceType pieceType) { + for (Integer x : hanXPositions.get(pieceType)) { + if (team == Team.CHO) { + Position position = new Position(x, defaultYPosition.get(pieceType)); + board.place(position, new Piece(team, pieceType)); + } + if (team == Team.HAN) { + Position position = new Position(x, MAX_Y - defaultYPosition.get(pieceType)); + board.place(position, new Piece(team, pieceType)); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index 1e3b9b1412..495a3855f7 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -1,9 +1,9 @@ package janggi.view; -import janggi.domain.BoardFormation; import janggi.domain.Piece; import janggi.domain.Position; import janggi.domain.Team; +import janggi.domain.board.BoardFormation; import java.util.List; import java.util.Map; diff --git a/src/test/java/janggi/domain/board/BoardInitiatorTest.java b/src/test/java/janggi/domain/board/BoardInitiatorTest.java new file mode 100644 index 0000000000..625afd10ff --- /dev/null +++ b/src/test/java/janggi/domain/board/BoardInitiatorTest.java @@ -0,0 +1,92 @@ +package janggi.domain.board; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.Piece; +import janggi.domain.PieceType; +import janggi.domain.Position; +import janggi.domain.Team; +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 BoardInitiatorTest { + @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 + BoardInitiator boardInitiator = new BoardInitiator(); + Board board = new Board(); + BoardFormation hanFormation = BoardFormation.MA_SANG_MA_SANG; + BoardFormation choFormation = BoardFormation.MA_SANG_MA_SANG; + Position position = new Position(x, y); + Piece piece = new Piece(team, pieceType); + + //when + boardInitiator.initializeByFormation(board, hanFormation, Team.HAN); + boardInitiator.initializeByFormation(board, choFormation, Team.CHO); + Map checkPiece = board.getBoard(); + + //then + assertThat(checkPiece.get(position)).isEqualTo(piece); + } + + @ParameterizedTest + @CsvSource({ + + "CHO,KING,5,9", + "CHO,SA,4,10", "CHO,SA,6,10", + "CHO,SANG,2,10", "CHO,SANG,7,10", + "CHO,MA,3,10", "CHO,MA,8,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 + BoardInitiator boardInitiator = new BoardInitiator(); + Board board = new Board(); + BoardFormation hanFormation = BoardFormation.MA_SANG_MA_SANG; + BoardFormation choFormation = BoardFormation.SANG_MA_SANG_MA; + Position position = new Position(x, y); + Piece piece = new Piece(team, pieceType); + + // when + boardInitiator.initializeByFormation(board, hanFormation, Team.HAN); + boardInitiator.initializeByFormation(board, choFormation, Team.CHO); + 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/board/BoardTest.java similarity index 87% rename from src/test/java/janggi/domain/BoardTest.java rename to src/test/java/janggi/domain/board/BoardTest.java index cb021deabe..5be1c6aac9 100644 --- a/src/test/java/janggi/domain/BoardTest.java +++ b/src/test/java/janggi/domain/board/BoardTest.java @@ -1,95 +1,20 @@ -package janggi.domain; +package janggi.domain.board; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; +import janggi.domain.Piece; +import janggi.domain.PieceType; +import janggi.domain.Position; +import janggi.domain.Team; import java.util.ArrayList; 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(); - BoardFormation hanFormation = BoardFormation.MA_SANG_MA_SANG; - BoardFormation choFormation = BoardFormation.MA_SANG_MA_SANG; - Position position = new Position(x, y); - Piece piece = new Piece(team, pieceType); - - //when - board.initializeByFormation(hanFormation, Team.HAN); - board.initializeByFormation(choFormation, Team.CHO); - Map checkPiece = board.getBoard(); - - //then - assertThat(checkPiece.get(position)).isEqualTo(piece); - } - - @ParameterizedTest - @CsvSource({ - - "CHO,KING,5,9", - "CHO,SA,4,10", "CHO,SA,6,10", - "CHO,SANG,2,10", "CHO,SANG,7,10", - "CHO,MA,3,10", "CHO,MA,8,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(); - BoardFormation hanFormation = BoardFormation.MA_SANG_MA_SANG; - BoardFormation choFormation = BoardFormation.SANG_MA_SANG_MA; - Position position = new Position(x, y); - Piece piece = new Piece(team, pieceType); - - // when - board.initializeByFormation(hanFormation, Team.HAN); - board.initializeByFormation(choFormation, Team.CHO); - Map checkPiece = board.getBoard(); - - // then - assertThat(checkPiece.get(position)).isEqualTo(piece); - } - @Test @DisplayName("초나라 졸은 경로에 장애물이 없으면 위쪽, 왼쪽, 오른쪽으로 이동할 수 있다") void 초나라_졸_장애물_없을때_이동_성공() { From 0648bd30c0c16e0117397ae16fad5b4649648c99 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Thu, 2 Apr 2026 16:16:58 +0900 Subject: [PATCH 33/37] =?UTF-8?q?refactor:=20RouteConverter=EC=97=90?= =?UTF-8?q?=EA=B2=8C=20=EA=B2=BD=EB=A1=9C=EB=A5=BC=20=EC=A2=8C=ED=91=9C=20?= =?UTF-8?q?=ED=98=95=ED=83=9C=EB=A1=9C=20=EB=B0=94=EA=BE=B8=EB=8A=94=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=20=EB=84=98=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존에 Board에 있던 로직을 RouteConverter에게 위임 --- .../java/janggi/domain/RouteConverter.java | 37 ++++++++++++++++++ src/main/java/janggi/domain/board/Board.java | 38 ++++--------------- 2 files changed, 44 insertions(+), 31 deletions(-) create mode 100644 src/main/java/janggi/domain/RouteConverter.java diff --git a/src/main/java/janggi/domain/RouteConverter.java b/src/main/java/janggi/domain/RouteConverter.java new file mode 100644 index 0000000000..adba9c260d --- /dev/null +++ b/src/main/java/janggi/domain/RouteConverter.java @@ -0,0 +1,37 @@ +package janggi.domain; + +import janggi.domain.board.Board; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RouteConverter { + + public Map> convertToPosition(Board board, Position position) { + Piece piece = board.placeAt(position); + if (piece.isCha() || piece.isPo()) { + return convertToContinuousRoutes(position, piece.findRoutes()); + } + return convertToFixedRoutes(position, piece.findRoutes()); + } + + private Map> convertToFixedRoutes(Position position, List routes) { + Map> result = new HashMap<>(); + for (Route route : routes) { + List positionRoute = route.applyDirections(position); + if (positionRoute.isEmpty()) { + continue; + } + result.put(positionRoute.getLast(), positionRoute); + } + return result; + } + + private Map> convertToContinuousRoutes(Position position, List routes) { + Map> result = new HashMap<>(); + for (Route route : routes) { + route.applyContinuousDirections(position, result); + } + return result; + } +} diff --git a/src/main/java/janggi/domain/board/Board.java b/src/main/java/janggi/domain/board/Board.java index d4f375c8e9..2614fc023d 100644 --- a/src/main/java/janggi/domain/board/Board.java +++ b/src/main/java/janggi/domain/board/Board.java @@ -2,7 +2,7 @@ import janggi.domain.Piece; import janggi.domain.Position; -import janggi.domain.Route; +import janggi.domain.RouteConverter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -11,6 +11,7 @@ public class Board { private final Map board = new HashMap<>(); + private final RouteConverter routeConverter = new RouteConverter(); public void place(Position position, Piece piece) { board.put(position, piece); @@ -23,9 +24,7 @@ public Map getBoard() { public List findAvailablePositions(Position position) { Piece piece = board.get(position); - List routes = piece.findRoutes(); - - Map> routePositions = convertToPositions(position, piece, routes); + Map> routePositions = routeConverter.convertToPosition(this, position); List availablePositions = calculateAvailablePositions(piece, routePositions); @@ -55,6 +54,10 @@ public void validateDestination(Position movePiecePosition, Position destination } } + public Piece placeAt(Position position) { + return board.get(position); + } + private boolean isDestinationIsMyTeam(Position destination, Piece piece) { Piece destinationPiece = board.get(destination); if (board.containsKey(destination)) { @@ -72,33 +75,6 @@ private boolean hasObstacleOnRoute(List route) { return false; } - private Map> convertToPositions(Position position, Piece piece, List routes) { - if (piece.isCha() || piece.isPo()) { - return convertToContinuousRoutes(position, routes); - } - return convertToFixedRoutes(position, routes); - } - - private Map> convertToFixedRoutes(Position position, List routes) { - Map> result = new HashMap<>(); - for (Route route : routes) { - List positionRoute = route.applyDirections(position); - if (positionRoute.isEmpty()) { - continue; - } - result.put(positionRoute.getLast(), positionRoute); - } - return result; - } - - private Map> convertToContinuousRoutes(Position position, List routes) { - Map> result = new HashMap<>(); - for (Route route : routes) { - route.applyContinuousDirections(position, result); - } - return result; - } - private boolean isDestinationIsPo(Position destination) { Piece destinationPiece = board.get(destination); if (board.containsKey(destination)) { From b57e61a0cbe65e7bd3295347902b6c1c904fb331 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Thu, 2 Apr 2026 16:47:07 +0900 Subject: [PATCH 34/37] =?UTF-8?q?refactor:=20RouteChecker=EC=97=90?= =?UTF-8?q?=EA=B2=8C=20=EC=A7=80=EB=82=98=EA=B0=88=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EA=B2=BD=EB=A1=9C=20=ED=99=95=EC=9D=B8=20=EC=B1=85?= =?UTF-8?q?=EC=9E=84=20=EB=84=98=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Board가 판단하던 것을 RouteChecker에게 위임 --- .../janggi/controller/JanggiController.java | 8 +- src/main/java/janggi/domain/RouteChecker.java | 97 ++++ src/main/java/janggi/domain/board/Board.java | 90 +-- .../java/janggi/domain/RouteCheckerTest.java | 518 ++++++++++++++++++ .../java/janggi/domain/board/BoardTest.java | 517 ----------------- 5 files changed, 622 insertions(+), 608 deletions(-) create mode 100644 src/main/java/janggi/domain/RouteChecker.java create mode 100644 src/test/java/janggi/domain/RouteCheckerTest.java diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index 1150c646a6..ad961cf776 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -1,6 +1,7 @@ package janggi.controller; import janggi.domain.Position; +import janggi.domain.RouteChecker; import janggi.domain.Team; import janggi.domain.board.Board; import janggi.domain.board.BoardFormation; @@ -15,6 +16,7 @@ public class JanggiController { private final InputView inputView = new InputView(); private final OutputView outputView = new OutputView(); private final BoardInitiator boardInitiator = new BoardInitiator(); + private final RouteChecker routeChecker = new RouteChecker(); public void run() { Board board = new Board(); @@ -49,7 +51,7 @@ private void playGame(boolean isChoTurn, Board board) { Position movePiecePosition = doLoop(() -> askMovePiecePosition(board)); - List availablePositions = board.findAvailablePositions(movePiecePosition); + List availablePositions = routeChecker.findAvailablePositions(board, movePiecePosition); outputView.printAvailablePositions(board.getBoard(), availablePositions); @@ -67,14 +69,14 @@ private boolean changeTurn(boolean isChoTurn) { private Position askMovePosition(Board board, Position movePiecePosition) { outputView.printMoveChoiceInfo(); Position position = inputView.readPosition(); - board.validateDestination(movePiecePosition, position); + routeChecker.validateDestination(board, movePiecePosition, position); return position; } private Position askMovePiecePosition(Board board) { outputView.printMoveInfo(); Position position = inputView.readPosition(); - board.findAvailablePositions(position); + routeChecker.findAvailablePositions(board, position); return position; } diff --git a/src/main/java/janggi/domain/RouteChecker.java b/src/main/java/janggi/domain/RouteChecker.java new file mode 100644 index 0000000000..eb8a9b7cd7 --- /dev/null +++ b/src/main/java/janggi/domain/RouteChecker.java @@ -0,0 +1,97 @@ +package janggi.domain; + +import janggi.domain.board.Board; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class RouteChecker { + private final RouteConverter routeConverter = new RouteConverter(); + + public List findAvailablePositions(Board board, Position position) { + Piece piece = board.placeAt(position); + + Map> routePositions = routeConverter.convertToPosition(board, position); + + List availablePositions = calculateAvailablePositions(board, piece, routePositions); + + if (availablePositions.isEmpty()) { + throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); + } + return availablePositions; + } + + public void validateDestination(Board board, Position movePiecePosition, Position destination) { + List availablePositions = findAvailablePositions(board, movePiecePosition); + boolean hasPosition = false; + for (Position position : availablePositions) { + if (position.equals(destination)) { + hasPosition = true; + break; + } + } + if (hasPosition == false) { + throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); + } + } + + private List calculateAvailablePositions(Board board, Piece piece, + Map> routePositions) { + List result = new ArrayList<>(); + for (Map.Entry> entry : routePositions.entrySet()) { + Position destination = entry.getKey(); + List route = entry.getValue(); + + if (canMove(board, piece, route, destination)) { + result.add(destination); + } + } + return result; + } + + private boolean canMove(Board board, Piece movePiece, List route, Position destination) { + if (movePiece.isPo()) { + return hasOneObstacleAndNotPo(board, route) + && !isDestinationIsMyTeam(board, destination, movePiece) + && !isDestinationIsPo(board, destination); + } + return !hasObstacleOnRoute(board, route) && !isDestinationIsMyTeam(board, destination, movePiece); + } + + private boolean isDestinationIsMyTeam(Board board, Position destination, Piece piece) { + Piece destinationPiece = board.placeAt(destination); + if (board.isPiece(destination)) { + return piece.isSameTeam(destinationPiece); + } + return false; + } + + private boolean hasObstacleOnRoute(Board board, List route) { + for (int i = 0; i < route.size() - 1; i++) { + if (board.isPiece(route.get(i))) { + return true; + } + } + return false; + } + + private boolean isDestinationIsPo(Board board, Position destination) { + Piece destinationPiece = board.placeAt(destination); + if (board.isPiece(destination)) { + return destinationPiece.isPo(); + } + return false; + } + + private boolean hasOneObstacleAndNotPo(Board board, List route) { + int count = 0; + List obstacles = new ArrayList<>(); + for (int i = 0; i < route.size() - 1; i++) { + if (board.isPiece(route.get(i))) { + count += 1; + obstacles.add(board.placeAt(route.get(i))); + } + } + return count == 1 && !obstacles.getFirst().isPo(); + } +} diff --git a/src/main/java/janggi/domain/board/Board.java b/src/main/java/janggi/domain/board/Board.java index 2614fc023d..fa1f5b63f3 100644 --- a/src/main/java/janggi/domain/board/Board.java +++ b/src/main/java/janggi/domain/board/Board.java @@ -2,16 +2,12 @@ import janggi.domain.Piece; import janggi.domain.Position; -import janggi.domain.RouteConverter; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; public class Board { private final Map board = new HashMap<>(); - private final RouteConverter routeConverter = new RouteConverter(); public void place(Position position, Piece piece) { board.put(position, piece); @@ -21,99 +17,17 @@ public Map getBoard() { return board; } - public List findAvailablePositions(Position position) { - Piece piece = board.get(position); - - Map> routePositions = routeConverter.convertToPosition(this, position); - - List availablePositions = calculateAvailablePositions(piece, routePositions); - - if (availablePositions.isEmpty()) { - throw new IllegalArgumentException("[ERROR] 이동할 수 없는 좌표입니다."); - } - return availablePositions; - } - public void movePiece(Position movePiecePosition, Position destination) { Piece piece = board.get(movePiecePosition); board.remove(movePiecePosition); board.put(destination, piece); } - public void validateDestination(Position movePiecePosition, Position destination) { - List availablePositions = findAvailablePositions(movePiecePosition); - boolean hasPosition = false; - for (Position position : availablePositions) { - if (position.equals(destination)) { - hasPosition = true; - break; - } - } - if (hasPosition == false) { - throw new IllegalArgumentException("[ERROR] 이동 가능한 좌표 중에서 선택하세요."); - } - } - public Piece placeAt(Position position) { return board.get(position); } - private boolean isDestinationIsMyTeam(Position destination, Piece piece) { - Piece destinationPiece = board.get(destination); - if (board.containsKey(destination)) { - return piece.isSameTeam(destinationPiece); - } - return false; - } - - 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 boolean isDestinationIsPo(Position destination) { - Piece destinationPiece = board.get(destination); - if (board.containsKey(destination)) { - return destinationPiece.isPo(); - } - return false; - } - - 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().isPo(); - } - - private List calculateAvailablePositions(Piece piece, Map> routePositions) { - List result = new ArrayList<>(); - for (Map.Entry> entry : routePositions.entrySet()) { - Position destination = entry.getKey(); - List route = entry.getValue(); - - if (canMove(piece, route, destination)) { - result.add(destination); - } - } - return result; - } - - private boolean canMove(Piece movePiece, List route, Position destination) { - if (movePiece.isPo()) { - return hasOneObstacleAndNotPo(route) - && !isDestinationIsMyTeam(destination, movePiece) - && !isDestinationIsPo(destination); - } - return !hasObstacleOnRoute(route) && !isDestinationIsMyTeam(destination, movePiece); + public boolean isPiece(Position position) { + return board.containsKey(position); } } diff --git a/src/test/java/janggi/domain/RouteCheckerTest.java b/src/test/java/janggi/domain/RouteCheckerTest.java new file mode 100644 index 0000000000..30f464145a --- /dev/null +++ b/src/test/java/janggi/domain/RouteCheckerTest.java @@ -0,0 +1,518 @@ +package janggi.domain; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import janggi.domain.board.Board; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class RouteCheckerTest { + private final RouteChecker routeChecker = new RouteChecker(); + + @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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(rightAnswer).isEqualTo(zolRoutesPositions); + } + + @Test + @DisplayName("마는 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") + void 마_장애물_없을때_8방향_이동_성공() { + //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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(maRoutesPositions).hasSize(7) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("상은 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") + void 상_장애물_없을때_8방향_이동_성공() { + //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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(sangRoutesPositions).hasSize(7) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("사는 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)") + 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(maRoutesPositions).hasSize(5) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("사의 목적지에 아군 기물이 있으면 이동할 수 없다 (사이클1 규칙)") + 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(maRoutesPositions).hasSize(4) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("사의 목적지에 적군 기물이 있으면 이동할 수 있다 (사이클1 규칙)") + 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(maRoutesPositions).hasSize(5) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("왕은 이동경로에 장애물이 없는 곳으로 이동할 수 있다 (사이클1 규칙)") + 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(maRoutesPositions).hasSize(8) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("왕의 이동하려는 목적지에 아군 기물이 있으면 이동할 수 없다(사이클1 규칙)") + 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(maRoutesPositions).hasSize(6) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("왕의 목적지에 적군 기물이 있으면 이동할 수 있다 (사이클1 규칙)") + 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 = routeChecker.findAvailablePositions(board, position); + + //then + 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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(chaRoutesPositions).hasSize(11) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("포는 이동 경로상에 일반 기물(포다리)이 딱 1개 존재하면 그 너머로 이동할 수 있다") + 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)); + 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 = routeChecker.findAvailablePositions(board, position); + + //then + assertThat(chaRoutesPositions).hasSize(5) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } + + @Test + @DisplayName("포는 넘어가려는 목적지에 또 다른 포가 있으면, 포는 포를 포획할 수 없으므로 이동할 수 없다") + void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { + 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); + + assertThrows(IllegalArgumentException.class, () -> { + routeChecker.findAvailablePositions(board, position); + }); + } + + @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)); + 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 = routeChecker.findAvailablePositions(board, position); + //then + assertThat(chaRoutesPositions).hasSize(1) + .containsExactlyInAnyOrderElementsOf(rightAnswer); + } +} diff --git a/src/test/java/janggi/domain/board/BoardTest.java b/src/test/java/janggi/domain/board/BoardTest.java index 5be1c6aac9..ab2ae161a5 100644 --- a/src/test/java/janggi/domain/board/BoardTest.java +++ b/src/test/java/janggi/domain/board/BoardTest.java @@ -1,522 +1,5 @@ package janggi.domain.board; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import janggi.domain.Piece; -import janggi.domain.PieceType; -import janggi.domain.Position; -import janggi.domain.Team; -import java.util.ArrayList; -import java.util.List; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - public class BoardTest { - - @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); - } - - @Test - @DisplayName("마는 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") - void 마_장애물_없을때_8방향_이동_성공() { - //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); - } - - @Test - @DisplayName("상은 이동 경로(멱)에 장애물이 없으면 8방향 모두 이동할 수 있다") - void 상_장애물_없을때_8방향_이동_성공() { - //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 규칙)") - 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 규칙)") - 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 규칙)") - 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 규칙)") - 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 규칙)") - 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 규칙)") - 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); - } - - @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); - } - - @Test - @DisplayName("포는 이동 경로상에 일반 기물(포다리)이 딱 1개 존재하면 그 너머로 이동할 수 있다") - 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)); - 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 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { - 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); - - assertThrows(IllegalArgumentException.class, () -> { - board.findAvailablePositions(position); - }); - } - - @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)); - 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 3059d68162c265163ed3d971db033092f36e9071 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Thu, 2 Apr 2026 17:30:35 +0900 Subject: [PATCH 35/37] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../janggi/controller/JanggiController.java | 6 +- src/main/java/janggi/domain/MoveRule.java | 7 -- src/main/java/janggi/domain/board/Board.java | 8 +- .../janggi/domain/board/BoardInitiator.java | 8 +- .../janggi/domain/{ => common}/Direction.java | 2 +- .../janggi/domain/{ => common}/Position.java | 6 +- .../java/janggi/domain/{ => common}/Team.java | 2 +- .../janggi/domain/moveRules/MaMoveRule.java | 23 ----- .../java/janggi/domain/{ => piece}/Piece.java | 4 +- .../janggi/domain/{ => piece}/PieceType.java | 19 ++-- .../{ => piece}/moveRules/ChaMoveRule.java | 9 +- .../{ => piece}/moveRules/KingMoveRule.java | 9 +- .../domain/piece/moveRules/MaMoveRule.java | 22 +++++ .../domain/piece/moveRules/MoveRule.java | 9 ++ .../{ => piece}/moveRules/PoMoveRule.java | 9 +- .../{ => piece}/moveRules/SaMoveRule.java | 9 +- .../{ => piece}/moveRules/SangMoveRule.java | 17 ++-- .../{ => piece}/moveRules/ZolMoveRule.java | 11 ++- .../java/janggi/domain/{ => route}/Route.java | 10 ++- .../domain/{ => route}/RouteChecker.java | 20 +++-- .../domain/{ => route}/RouteConverter.java | 6 +- src/main/java/janggi/view/InputView.java | 2 +- src/main/java/janggi/view/OutputView.java | 6 +- .../domain/board/BoardInitiatorTest.java | 8 +- .../domain/{ => common}/PositionTest.java | 8 +- .../domain/moveRules/ChaMoveRuleTest.java | 9 +- .../domain/moveRules/KingMoveRuleTest.java | 9 +- .../domain/moveRules/MaMoveRuleTest.java | 9 +- .../domain/moveRules/PoMoveRuleTest.java | 11 +-- .../domain/moveRules/SaMoveRuleTest.java | 9 +- .../domain/moveRules/SangMoveRuleTest.java | 19 ++-- .../domain/moveRules/ZolMoveRuleTest.java | 13 +-- .../janggi/domain/{ => piece}/PieceTest.java | 9 +- .../domain/{ => route}/RouteCheckerTest.java | 86 ++++++++++--------- 34 files changed, 215 insertions(+), 199 deletions(-) delete mode 100644 src/main/java/janggi/domain/MoveRule.java rename src/main/java/janggi/domain/{ => common}/Direction.java (95%) rename src/main/java/janggi/domain/{ => common}/Position.java (93%) rename src/main/java/janggi/domain/{ => common}/Team.java (87%) delete mode 100644 src/main/java/janggi/domain/moveRules/MaMoveRule.java rename src/main/java/janggi/domain/{ => piece}/Piece.java (91%) rename src/main/java/janggi/domain/{ => piece}/PieceType.java (56%) rename src/main/java/janggi/domain/{ => piece}/moveRules/ChaMoveRule.java (74%) rename src/main/java/janggi/domain/{ => piece}/moveRules/KingMoveRule.java (82%) create mode 100644 src/main/java/janggi/domain/piece/moveRules/MaMoveRule.java create mode 100644 src/main/java/janggi/domain/piece/moveRules/MoveRule.java rename src/main/java/janggi/domain/{ => piece}/moveRules/PoMoveRule.java (74%) rename src/main/java/janggi/domain/{ => piece}/moveRules/SaMoveRule.java (82%) rename src/main/java/janggi/domain/{ => piece}/moveRules/SangMoveRule.java (53%) rename src/main/java/janggi/domain/{ => piece}/moveRules/ZolMoveRule.java (77%) rename src/main/java/janggi/domain/{ => route}/Route.java (84%) rename src/main/java/janggi/domain/{ => route}/RouteChecker.java (86%) rename src/main/java/janggi/domain/{ => route}/RouteConverter.java (89%) rename src/test/java/janggi/domain/{ => common}/PositionTest.java (88%) rename src/test/java/janggi/domain/{ => piece}/PieceTest.java (89%) rename src/test/java/janggi/domain/{ => route}/RouteCheckerTest.java (85%) diff --git a/src/main/java/janggi/controller/JanggiController.java b/src/main/java/janggi/controller/JanggiController.java index ad961cf776..1100525e01 100644 --- a/src/main/java/janggi/controller/JanggiController.java +++ b/src/main/java/janggi/controller/JanggiController.java @@ -1,11 +1,11 @@ package janggi.controller; -import janggi.domain.Position; -import janggi.domain.RouteChecker; -import janggi.domain.Team; import janggi.domain.board.Board; import janggi.domain.board.BoardFormation; import janggi.domain.board.BoardInitiator; +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.route.RouteChecker; import janggi.view.InputView; import janggi.view.OutputView; import java.util.List; diff --git a/src/main/java/janggi/domain/MoveRule.java b/src/main/java/janggi/domain/MoveRule.java deleted file mode 100644 index 3337cf6c6e..0000000000 --- a/src/main/java/janggi/domain/MoveRule.java +++ /dev/null @@ -1,7 +0,0 @@ -package janggi.domain; - -import java.util.List; - -public interface MoveRule { - List findRoutes(Team team); -} diff --git a/src/main/java/janggi/domain/board/Board.java b/src/main/java/janggi/domain/board/Board.java index fa1f5b63f3..671b3bb5a5 100644 --- a/src/main/java/janggi/domain/board/Board.java +++ b/src/main/java/janggi/domain/board/Board.java @@ -1,7 +1,7 @@ package janggi.domain.board; -import janggi.domain.Piece; -import janggi.domain.Position; +import janggi.domain.common.Position; +import janggi.domain.piece.Piece; import java.util.HashMap; import java.util.Map; @@ -23,11 +23,11 @@ public void movePiece(Position movePiecePosition, Position destination) { board.put(destination, piece); } - public Piece placeAt(Position position) { + public Piece pieceAt(Position position) { return board.get(position); } - public boolean isPiece(Position position) { + public boolean hasPiece(Position position) { return board.containsKey(position); } } diff --git a/src/main/java/janggi/domain/board/BoardInitiator.java b/src/main/java/janggi/domain/board/BoardInitiator.java index c6b7b46c9e..327b51a58b 100644 --- a/src/main/java/janggi/domain/board/BoardInitiator.java +++ b/src/main/java/janggi/domain/board/BoardInitiator.java @@ -1,9 +1,9 @@ package janggi.domain.board; -import janggi.domain.Piece; -import janggi.domain.PieceType; -import janggi.domain.Position; -import janggi.domain.Team; +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.piece.Piece; +import janggi.domain.piece.PieceType; import java.util.HashMap; import java.util.List; import java.util.Map; diff --git a/src/main/java/janggi/domain/Direction.java b/src/main/java/janggi/domain/common/Direction.java similarity index 95% rename from src/main/java/janggi/domain/Direction.java rename to src/main/java/janggi/domain/common/Direction.java index 01dcfb2929..3b96fd7b66 100644 --- a/src/main/java/janggi/domain/Direction.java +++ b/src/main/java/janggi/domain/common/Direction.java @@ -1,4 +1,4 @@ -package janggi.domain; +package janggi.domain.common; import java.util.List; import java.util.Map; diff --git a/src/main/java/janggi/domain/Position.java b/src/main/java/janggi/domain/common/Position.java similarity index 93% rename from src/main/java/janggi/domain/Position.java rename to src/main/java/janggi/domain/common/Position.java index 00aa36c93a..f02f4b90e5 100644 --- a/src/main/java/janggi/domain/Position.java +++ b/src/main/java/janggi/domain/common/Position.java @@ -1,4 +1,4 @@ -package janggi.domain; +package janggi.domain.common; import java.util.ArrayList; import java.util.List; @@ -22,7 +22,7 @@ public Position(int x, int y) { } public Optional applyDirection(int dx, int dy) { - if(isInsideBoundary(x + dx, y + dy)) { + if (isInsideBoundary(x + dx, y + dy)) { return Optional.of(new Position(x + dx, y + dy)); } return Optional.empty(); @@ -32,7 +32,7 @@ public void applyContinuousDirection(int dx, int dy, Map result = new ArrayList<>(); int nextX = x + dx; int nextY = y + dy; - while(isInsideBoundary(nextX, nextY)) { + while (isInsideBoundary(nextX, nextY)) { result.add(new Position(nextX, nextY)); continuousRoute.put(new Position(nextX, nextY), new ArrayList<>(result)); nextX += dx; diff --git a/src/main/java/janggi/domain/Team.java b/src/main/java/janggi/domain/common/Team.java similarity index 87% rename from src/main/java/janggi/domain/Team.java rename to src/main/java/janggi/domain/common/Team.java index 9d7c221835..14e721811a 100644 --- a/src/main/java/janggi/domain/Team.java +++ b/src/main/java/janggi/domain/common/Team.java @@ -1,4 +1,4 @@ -package janggi.domain; +package janggi.domain.common; public enum Team { CHO("초나라"), diff --git a/src/main/java/janggi/domain/moveRules/MaMoveRule.java b/src/main/java/janggi/domain/moveRules/MaMoveRule.java deleted file mode 100644 index 99379b9dcf..0000000000 --- a/src/main/java/janggi/domain/moveRules/MaMoveRule.java +++ /dev/null @@ -1,23 +0,0 @@ -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/Piece.java b/src/main/java/janggi/domain/piece/Piece.java similarity index 91% rename from src/main/java/janggi/domain/Piece.java rename to src/main/java/janggi/domain/piece/Piece.java index 17c784be9d..0b1c38d0cc 100644 --- a/src/main/java/janggi/domain/Piece.java +++ b/src/main/java/janggi/domain/piece/Piece.java @@ -1,5 +1,7 @@ -package janggi.domain; +package janggi.domain.piece; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; import java.util.Objects; diff --git a/src/main/java/janggi/domain/PieceType.java b/src/main/java/janggi/domain/piece/PieceType.java similarity index 56% rename from src/main/java/janggi/domain/PieceType.java rename to src/main/java/janggi/domain/piece/PieceType.java index dc9e3d9c79..08c28b9aa6 100644 --- a/src/main/java/janggi/domain/PieceType.java +++ b/src/main/java/janggi/domain/piece/PieceType.java @@ -1,12 +1,15 @@ -package janggi.domain; +package janggi.domain.piece; -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 janggi.domain.common.Team; +import janggi.domain.piece.moveRules.ChaMoveRule; +import janggi.domain.piece.moveRules.KingMoveRule; +import janggi.domain.piece.moveRules.MaMoveRule; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.piece.moveRules.PoMoveRule; +import janggi.domain.piece.moveRules.SaMoveRule; +import janggi.domain.piece.moveRules.SangMoveRule; +import janggi.domain.piece.moveRules.ZolMoveRule; +import janggi.domain.route.Route; import java.util.List; public enum PieceType { diff --git a/src/main/java/janggi/domain/moveRules/ChaMoveRule.java b/src/main/java/janggi/domain/piece/moveRules/ChaMoveRule.java similarity index 74% rename from src/main/java/janggi/domain/moveRules/ChaMoveRule.java rename to src/main/java/janggi/domain/piece/moveRules/ChaMoveRule.java index 39993bd48f..922df79a2d 100644 --- a/src/main/java/janggi/domain/moveRules/ChaMoveRule.java +++ b/src/main/java/janggi/domain/piece/moveRules/ChaMoveRule.java @@ -1,9 +1,8 @@ -package janggi.domain.moveRules; +package janggi.domain.piece.moveRules; -import janggi.domain.Direction; -import janggi.domain.MoveRule; -import janggi.domain.Route; -import janggi.domain.Team; +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; public class ChaMoveRule implements MoveRule { diff --git a/src/main/java/janggi/domain/moveRules/KingMoveRule.java b/src/main/java/janggi/domain/piece/moveRules/KingMoveRule.java similarity index 82% rename from src/main/java/janggi/domain/moveRules/KingMoveRule.java rename to src/main/java/janggi/domain/piece/moveRules/KingMoveRule.java index d0174ddb44..b9e9d52c17 100644 --- a/src/main/java/janggi/domain/moveRules/KingMoveRule.java +++ b/src/main/java/janggi/domain/piece/moveRules/KingMoveRule.java @@ -1,9 +1,8 @@ -package janggi.domain.moveRules; +package janggi.domain.piece.moveRules; -import janggi.domain.Direction; -import janggi.domain.MoveRule; -import janggi.domain.Route; -import janggi.domain.Team; +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; public class KingMoveRule implements MoveRule { diff --git a/src/main/java/janggi/domain/piece/moveRules/MaMoveRule.java b/src/main/java/janggi/domain/piece/moveRules/MaMoveRule.java new file mode 100644 index 0000000000..6df28de425 --- /dev/null +++ b/src/main/java/janggi/domain/piece/moveRules/MaMoveRule.java @@ -0,0 +1,22 @@ +package janggi.domain.piece.moveRules; + +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; +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/piece/moveRules/MoveRule.java b/src/main/java/janggi/domain/piece/moveRules/MoveRule.java new file mode 100644 index 0000000000..c85640a392 --- /dev/null +++ b/src/main/java/janggi/domain/piece/moveRules/MoveRule.java @@ -0,0 +1,9 @@ +package janggi.domain.piece.moveRules; + +import janggi.domain.common.Team; +import janggi.domain.route.Route; +import java.util.List; + +public interface MoveRule { + List findRoutes(Team team); +} diff --git a/src/main/java/janggi/domain/moveRules/PoMoveRule.java b/src/main/java/janggi/domain/piece/moveRules/PoMoveRule.java similarity index 74% rename from src/main/java/janggi/domain/moveRules/PoMoveRule.java rename to src/main/java/janggi/domain/piece/moveRules/PoMoveRule.java index ba61b20f85..7f68209dbe 100644 --- a/src/main/java/janggi/domain/moveRules/PoMoveRule.java +++ b/src/main/java/janggi/domain/piece/moveRules/PoMoveRule.java @@ -1,9 +1,8 @@ -package janggi.domain.moveRules; +package janggi.domain.piece.moveRules; -import janggi.domain.Direction; -import janggi.domain.MoveRule; -import janggi.domain.Route; -import janggi.domain.Team; +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; public class PoMoveRule implements MoveRule { diff --git a/src/main/java/janggi/domain/moveRules/SaMoveRule.java b/src/main/java/janggi/domain/piece/moveRules/SaMoveRule.java similarity index 82% rename from src/main/java/janggi/domain/moveRules/SaMoveRule.java rename to src/main/java/janggi/domain/piece/moveRules/SaMoveRule.java index 75a1892952..c373bba292 100644 --- a/src/main/java/janggi/domain/moveRules/SaMoveRule.java +++ b/src/main/java/janggi/domain/piece/moveRules/SaMoveRule.java @@ -1,9 +1,8 @@ -package janggi.domain.moveRules; +package janggi.domain.piece.moveRules; -import janggi.domain.Direction; -import janggi.domain.MoveRule; -import janggi.domain.Route; -import janggi.domain.Team; +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; public class SaMoveRule implements MoveRule { diff --git a/src/main/java/janggi/domain/moveRules/SangMoveRule.java b/src/main/java/janggi/domain/piece/moveRules/SangMoveRule.java similarity index 53% rename from src/main/java/janggi/domain/moveRules/SangMoveRule.java rename to src/main/java/janggi/domain/piece/moveRules/SangMoveRule.java index fbc492bcf9..2a2976e3b7 100644 --- a/src/main/java/janggi/domain/moveRules/SangMoveRule.java +++ b/src/main/java/janggi/domain/piece/moveRules/SangMoveRule.java @@ -1,9 +1,8 @@ -package janggi.domain.moveRules; +package janggi.domain.piece.moveRules; -import janggi.domain.Direction; -import janggi.domain.MoveRule; -import janggi.domain.Route; -import janggi.domain.Team; +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; public class SangMoveRule implements MoveRule { @@ -11,13 +10,13 @@ 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 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)); + 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/piece/moveRules/ZolMoveRule.java similarity index 77% rename from src/main/java/janggi/domain/moveRules/ZolMoveRule.java rename to src/main/java/janggi/domain/piece/moveRules/ZolMoveRule.java index d74cb9011c..0fafb7d6d9 100644 --- a/src/main/java/janggi/domain/moveRules/ZolMoveRule.java +++ b/src/main/java/janggi/domain/piece/moveRules/ZolMoveRule.java @@ -1,16 +1,15 @@ -package janggi.domain.moveRules; +package janggi.domain.piece.moveRules; -import janggi.domain.Direction; -import janggi.domain.MoveRule; -import janggi.domain.Route; -import janggi.domain.Team; +import janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.route.Route; import java.util.List; 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)); diff --git a/src/main/java/janggi/domain/Route.java b/src/main/java/janggi/domain/route/Route.java similarity index 84% rename from src/main/java/janggi/domain/Route.java rename to src/main/java/janggi/domain/route/Route.java index d4ed719679..f01a53e776 100644 --- a/src/main/java/janggi/domain/Route.java +++ b/src/main/java/janggi/domain/route/Route.java @@ -1,5 +1,7 @@ -package janggi.domain; +package janggi.domain.route; +import janggi.domain.common.Direction; +import janggi.domain.common.Position; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -17,9 +19,9 @@ public Route(List routes) { public List applyDirections(Position position) { List routePositions = new ArrayList<>(); Position startPosition = position; - for(Direction direction:routes) { + for (Direction direction : routes) { Optional nextPosition = direction.nextPosition(startPosition); - if(nextPosition.isEmpty()) { + if (nextPosition.isEmpty()) { return new ArrayList<>(); } startPosition = nextPosition.get(); @@ -30,7 +32,7 @@ public List applyDirections(Position position) { public void applyContinuousDirections(Position position, Map> continuousRoutes) { Position startPosition = position; - for(Direction direction:routes) { + for (Direction direction : routes) { direction.nextContinuousPosition(startPosition, continuousRoutes); } } diff --git a/src/main/java/janggi/domain/RouteChecker.java b/src/main/java/janggi/domain/route/RouteChecker.java similarity index 86% rename from src/main/java/janggi/domain/RouteChecker.java rename to src/main/java/janggi/domain/route/RouteChecker.java index eb8a9b7cd7..81f473b0a5 100644 --- a/src/main/java/janggi/domain/RouteChecker.java +++ b/src/main/java/janggi/domain/route/RouteChecker.java @@ -1,6 +1,8 @@ -package janggi.domain; +package janggi.domain.route; import janggi.domain.board.Board; +import janggi.domain.common.Position; +import janggi.domain.piece.Piece; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -9,7 +11,7 @@ public class RouteChecker { private final RouteConverter routeConverter = new RouteConverter(); public List findAvailablePositions(Board board, Position position) { - Piece piece = board.placeAt(position); + Piece piece = board.pieceAt(position); Map> routePositions = routeConverter.convertToPosition(board, position); @@ -59,8 +61,8 @@ private boolean canMove(Board board, Piece movePiece, List route, Posi } private boolean isDestinationIsMyTeam(Board board, Position destination, Piece piece) { - Piece destinationPiece = board.placeAt(destination); - if (board.isPiece(destination)) { + Piece destinationPiece = board.pieceAt(destination); + if (board.hasPiece(destination)) { return piece.isSameTeam(destinationPiece); } return false; @@ -68,7 +70,7 @@ private boolean isDestinationIsMyTeam(Board board, Position destination, Piece p private boolean hasObstacleOnRoute(Board board, List route) { for (int i = 0; i < route.size() - 1; i++) { - if (board.isPiece(route.get(i))) { + if (board.hasPiece(route.get(i))) { return true; } } @@ -76,8 +78,8 @@ private boolean hasObstacleOnRoute(Board board, List route) { } private boolean isDestinationIsPo(Board board, Position destination) { - Piece destinationPiece = board.placeAt(destination); - if (board.isPiece(destination)) { + Piece destinationPiece = board.pieceAt(destination); + if (board.hasPiece(destination)) { return destinationPiece.isPo(); } return false; @@ -87,9 +89,9 @@ private boolean hasOneObstacleAndNotPo(Board board, List route) { int count = 0; List obstacles = new ArrayList<>(); for (int i = 0; i < route.size() - 1; i++) { - if (board.isPiece(route.get(i))) { + if (board.hasPiece(route.get(i))) { count += 1; - obstacles.add(board.placeAt(route.get(i))); + obstacles.add(board.pieceAt(route.get(i))); } } return count == 1 && !obstacles.getFirst().isPo(); diff --git a/src/main/java/janggi/domain/RouteConverter.java b/src/main/java/janggi/domain/route/RouteConverter.java similarity index 89% rename from src/main/java/janggi/domain/RouteConverter.java rename to src/main/java/janggi/domain/route/RouteConverter.java index adba9c260d..aef4bcb5ca 100644 --- a/src/main/java/janggi/domain/RouteConverter.java +++ b/src/main/java/janggi/domain/route/RouteConverter.java @@ -1,6 +1,8 @@ -package janggi.domain; +package janggi.domain.route; import janggi.domain.board.Board; +import janggi.domain.common.Position; +import janggi.domain.piece.Piece; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -8,7 +10,7 @@ public class RouteConverter { public Map> convertToPosition(Board board, Position position) { - Piece piece = board.placeAt(position); + Piece piece = board.pieceAt(position); if (piece.isCha() || piece.isPo()) { return convertToContinuousRoutes(position, piece.findRoutes()); } diff --git a/src/main/java/janggi/view/InputView.java b/src/main/java/janggi/view/InputView.java index cff7f4865f..1413a04d06 100644 --- a/src/main/java/janggi/view/InputView.java +++ b/src/main/java/janggi/view/InputView.java @@ -1,6 +1,6 @@ package janggi.view; -import janggi.domain.Position; +import janggi.domain.common.Position; import java.util.Scanner; public class InputView { diff --git a/src/main/java/janggi/view/OutputView.java b/src/main/java/janggi/view/OutputView.java index 495a3855f7..bd9b4fef57 100644 --- a/src/main/java/janggi/view/OutputView.java +++ b/src/main/java/janggi/view/OutputView.java @@ -1,9 +1,9 @@ package janggi.view; -import janggi.domain.Piece; -import janggi.domain.Position; -import janggi.domain.Team; import janggi.domain.board.BoardFormation; +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.piece.Piece; import java.util.List; import java.util.Map; diff --git a/src/test/java/janggi/domain/board/BoardInitiatorTest.java b/src/test/java/janggi/domain/board/BoardInitiatorTest.java index 625afd10ff..073c217e57 100644 --- a/src/test/java/janggi/domain/board/BoardInitiatorTest.java +++ b/src/test/java/janggi/domain/board/BoardInitiatorTest.java @@ -2,10 +2,10 @@ import static org.assertj.core.api.Assertions.assertThat; -import janggi.domain.Piece; -import janggi.domain.PieceType; -import janggi.domain.Position; -import janggi.domain.Team; +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.piece.Piece; +import janggi.domain.piece.PieceType; import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/janggi/domain/PositionTest.java b/src/test/java/janggi/domain/common/PositionTest.java similarity index 88% rename from src/test/java/janggi/domain/PositionTest.java rename to src/test/java/janggi/domain/common/PositionTest.java index 77b0f4a731..701c3441c4 100644 --- a/src/test/java/janggi/domain/PositionTest.java +++ b/src/test/java/janggi/domain/common/PositionTest.java @@ -1,4 +1,4 @@ -package janggi.domain; +package janggi.domain.common; import static org.assertj.core.api.Assertions.assertThat; @@ -21,7 +21,7 @@ public class PositionTest { Optional result = position.applyDirection(0, 1); // then - assertThat(result).isPresent().contains(new Position(1,10)); + assertThat(result).isPresent().contains(new Position(1, 10)); } @Test @@ -55,13 +55,13 @@ public class PositionTest { void 보드_범위_내에_연속_좌표() { // given Position position = new Position(1, 5); - Map> continuousRoute = new HashMap<>(); + Map> continuousRoute = new HashMap<>(); // when position.applyContinuousDirection(0, 1, continuousRoute); // then assertThat(continuousRoute).hasSize(5) - .containsKey(new Position(1,10)); + .containsKey(new Position(1, 10)); } } diff --git a/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java index 5c52f61be0..9b7b1d9aff 100644 --- a/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/ChaMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.ChaMoveRule; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java index eac266c091..0ae0c9c8c5 100644 --- a/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/KingMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.KingMoveRule; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java index 4564af4dd4..0c0cfff117 100644 --- a/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/MaMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.MaMoveRule; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java index 15b35a0794..1128033a18 100644 --- a/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/PoMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.piece.moveRules.PoMoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -14,7 +15,7 @@ public class PoMoveRuleTest { @Test @DisplayName("포는 직선으로 갈 수 있다") - void 포의_이동규칙(){ + void 포의_이동규칙() { //given MoveRule moveRule = new PoMoveRule(); Team team = Team.CHO; diff --git a/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java index 8250d074eb..5d5fb493c0 100644 --- a/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/SaMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.piece.moveRules.SaMoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java index ab54840159..af74bc5e0d 100644 --- a/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/SangMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.piece.moveRules.SangMoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -19,14 +20,14 @@ public class SangMoveRuleTest { 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 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); + 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); diff --git a/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java b/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java index fc1dc9e7ff..f2593b34ba 100644 --- a/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java +++ b/src/test/java/janggi/domain/moveRules/ZolMoveRuleTest.java @@ -2,10 +2,11 @@ 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 janggi.domain.common.Direction; +import janggi.domain.common.Team; +import janggi.domain.piece.moveRules.MoveRule; +import janggi.domain.piece.moveRules.ZolMoveRule; +import janggi.domain.route.Route; import java.util.List; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -22,7 +23,7 @@ public class ZolMoveRuleTest { Route route2 = new Route(List.of(Direction.LEFT)); Route route3 = new Route(List.of(Direction.RIGHT)); - List routes = List.of(route1,route2,route3); + List routes = List.of(route1, route2, route3); //when List zolPaths = moveRule.findRoutes(cho); @@ -41,7 +42,7 @@ public class ZolMoveRuleTest { Route route2 = new Route(List.of(Direction.LEFT)); Route route3 = new Route(List.of(Direction.RIGHT)); - List routes = List.of(route1,route2,route3); + List routes = List.of(route1, route2, route3); //when List zolPaths = moveRule.findRoutes(han); diff --git a/src/test/java/janggi/domain/PieceTest.java b/src/test/java/janggi/domain/piece/PieceTest.java similarity index 89% rename from src/test/java/janggi/domain/PieceTest.java rename to src/test/java/janggi/domain/piece/PieceTest.java index 7e1ef483db..d528220afd 100644 --- a/src/test/java/janggi/domain/PieceTest.java +++ b/src/test/java/janggi/domain/piece/PieceTest.java @@ -1,9 +1,8 @@ -package janggi.domain; +package janggi.domain.piece; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import janggi.domain.common.Team; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -11,11 +10,11 @@ public class PieceTest { @Test @DisplayName("기물에는 초나라 졸이 있다.") - void 기물은_초나라_졸이_있음(){ + void 기물은_초나라_졸이_있음() { //given Team cho = Team.CHO; PieceType zol = PieceType.ZOL; - Piece piece = new Piece(cho,zol); + Piece piece = new Piece(cho, zol); //when & then assertThat(piece.getTeamName()).isEqualTo("초나라"); diff --git a/src/test/java/janggi/domain/RouteCheckerTest.java b/src/test/java/janggi/domain/route/RouteCheckerTest.java similarity index 85% rename from src/test/java/janggi/domain/RouteCheckerTest.java rename to src/test/java/janggi/domain/route/RouteCheckerTest.java index 30f464145a..3ea6537035 100644 --- a/src/test/java/janggi/domain/RouteCheckerTest.java +++ b/src/test/java/janggi/domain/route/RouteCheckerTest.java @@ -1,9 +1,13 @@ -package janggi.domain; +package janggi.domain.route; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; import janggi.domain.board.Board; +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.piece.Piece; +import janggi.domain.piece.PieceType; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.DisplayName; @@ -18,7 +22,7 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(5, 7); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); + board.place(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); @@ -37,9 +41,9 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(5, 7); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.ZOL)); + board.place(position, new Piece(Team.CHO, PieceType.ZOL)); Position zolUp = new Position(5, 6); - board.getBoard().put(zolUp, new Piece(Team.CHO, PieceType.ZOL)); + board.place(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); @@ -57,7 +61,7 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(4, 6); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.MA)); + board.place(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); @@ -82,8 +86,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.MA)); + board.place(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); @@ -106,8 +110,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.MA)); + board.place(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); @@ -131,7 +135,7 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(5, 7); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.SANG)); + board.place(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); @@ -156,8 +160,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.SANG)); + board.place(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); @@ -181,8 +185,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.SANG)); + board.place(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); @@ -205,8 +209,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.SANG)); + board.place(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); @@ -230,7 +234,7 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(4, 10); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.SA)); + board.place(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); @@ -252,8 +256,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.SA)); + board.place(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); @@ -274,8 +278,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.SA)); + board.place(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); @@ -297,7 +301,7 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(5, 9); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.KING)); + board.place(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); @@ -322,9 +326,9 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.KING)); + board.place(new Position(4, 9), new Piece(Team.CHO, PieceType.SA)); + board.place(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); @@ -347,9 +351,9 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.KING)); + board.place(new Position(4, 9), new Piece(Team.HAN, PieceType.ZOL)); + board.place(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); @@ -374,7 +378,7 @@ public class RouteCheckerTest { //given Board board = new Board(); Position position = new Position(1, 10); - board.getBoard().put(position, new Piece(Team.CHO, PieceType.CHA)); + board.place(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), @@ -404,8 +408,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.CHA)); + board.place(new Position(1, 7), new Piece(Team.CHO, PieceType.ZOL)); List upRoutes = List.of( new Position(1, 9), new Position(1, 8) ); @@ -433,8 +437,8 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.CHA)); + board.place(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) ); @@ -462,8 +466,8 @@ public class RouteCheckerTest { //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.place(position, new Piece(Team.CHO, PieceType.PO)); + board.place(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) @@ -484,9 +488,9 @@ public class RouteCheckerTest { void 포_목적지에_다른_포가_있으면_포획_및_이동_불가() { 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)); + board.place(position, new Piece(Team.CHO, PieceType.PO)); + board.place(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); + board.place(new Position(5, 5), new Piece(Team.HAN, PieceType.PO)); List upRoutes = List.of(); List rightAnswer = new ArrayList<>(upRoutes); @@ -502,9 +506,9 @@ public class RouteCheckerTest { //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)); + board.place(position, new Piece(Team.CHO, PieceType.PO)); + board.place(new Position(5, 6), new Piece(Team.HAN, PieceType.CHA)); + board.place(new Position(5, 5), new Piece(Team.HAN, PieceType.ZOL)); List upRoutes = List.of(new Position(5, 5)); List rightAnswer = new ArrayList<>(upRoutes); From 3c800f69e5cc6b1d2aa5f253d9eb68acb0724d26 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Thu, 2 Apr 2026 17:56:44 +0900 Subject: [PATCH 36/37] =?UTF-8?q?test(Board):=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 보드에 기물 두기 - 목적지 좌표로 기물 이동 - 좌표를 통해 기물 확인 - 좌표에 기물이 있는지 판단 --- .../java/janggi/domain/board/BoardTest.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/test/java/janggi/domain/board/BoardTest.java b/src/test/java/janggi/domain/board/BoardTest.java index ab2ae161a5..86a3fdcb14 100644 --- a/src/test/java/janggi/domain/board/BoardTest.java +++ b/src/test/java/janggi/domain/board/BoardTest.java @@ -1,5 +1,80 @@ package janggi.domain.board; +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.piece.Piece; +import janggi.domain.piece.PieceType; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + public class BoardTest { + + @Test + @DisplayName("보드에 기물을 놓을 수 있다") + void 보드에_기물_두기() { + // given + Board board = new Board(); + Position position = new Position(1, 3); + Piece piece = new Piece(Team.CHO, PieceType.PO); + + // when + board.place(position, piece); + + // then + assertThat(board.hasPiece(position)).isTrue(); + assertThat(board.pieceAt(position)).isEqualTo(piece); + } + + @Test + @DisplayName("이동할 기물의 현재 좌표를 통해 목적지로 기물을 이동할 수 있다") + void 목적지_좌표로_기물_이동() { + // given + Board board = new Board(); + Position movePiecePosition = new Position(1, 5); + Position destinationPosition = new Position(1, 3); + + // when + board.movePiece(movePiecePosition, destinationPosition); + + // then + assertThat(board.hasPiece(movePiecePosition)).isFalse(); + assertThat(board.hasPiece(destinationPosition)).isTrue(); + } + + @Test + @DisplayName("좌표를 통해 기물을 알아낼 수 있다") + void 좌표를_통해_기물_확인() { + // given + Board board = new Board(); + Position position = new Position(2, 5); + Piece piece = new Piece(Team.HAN, PieceType.CHA); + board.place(position, piece); + + // when + Piece result = board.pieceAt(position); + + // then + assertThat(result).isEqualTo(piece); + } + + @Test + @DisplayName("해당 좌표에 기물이 있는지 확인할 수 있다") + void 좌표에_기물_있는지_판단() { + // given + Board board = new Board(); + Position position = new Position(1, 5); + Position emptyPosition = new Position(2, 7); + board.place(position, new Piece(Team.CHO, PieceType.PO)); + + // when + boolean result = board.hasPiece(position); + boolean result2 = board.hasPiece(emptyPosition); + + // then + assertThat(result).isTrue(); + assertThat(result2).isFalse(); + } } From eff4d105e2c63fb0013ee4e9b037818259806aa5 Mon Sep 17 00:00:00 2001 From: Chaerin Lee Date: Thu, 2 Apr 2026 18:51:57 +0900 Subject: [PATCH 37/37] =?UTF-8?q?test(RouteConverter):=20=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EB=B2=94=EC=9C=84=20=EB=82=B4=EC=97=90=20=EC=9E=88?= =?UTF-8?q?=EC=9D=84=20=EB=95=8C=20=EA=B0=80=EB=8A=A5=ED=95=9C=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=EB=A5=BC=20=EC=A2=8C=ED=91=9C=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 졸, 마, 상, 사, 왕은 고정된 경로를 좌표로 변환 - 차, 포는 연속적인 경로를 좌표로 변환(장애물 검사는 RouteConverter에서 진행하지 않음) --- .../domain/route/RouteConverterTest.java | 195 ++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 src/test/java/janggi/domain/route/RouteConverterTest.java diff --git a/src/test/java/janggi/domain/route/RouteConverterTest.java b/src/test/java/janggi/domain/route/RouteConverterTest.java new file mode 100644 index 0000000000..baa05b4272 --- /dev/null +++ b/src/test/java/janggi/domain/route/RouteConverterTest.java @@ -0,0 +1,195 @@ +package janggi.domain.route; + +import static org.assertj.core.api.Assertions.assertThat; + +import janggi.domain.board.Board; +import janggi.domain.common.Position; +import janggi.domain.common.Team; +import janggi.domain.piece.Piece; +import janggi.domain.piece.PieceType; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class RouteConverterTest { + RouteConverter routeConverter = new RouteConverter(); + + @Test + @DisplayName("초나라 졸의 왼쪽 방향이 보드 범위를 넘어서 불가능한 좌표이다") + void 초나라_졸_보드_범위_내_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(1, 5); + Piece piece = new Piece(Team.CHO, PieceType.ZOL); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(1, 4), new Position(2, 5) + ); + } + + @Test + @DisplayName("초나라 졸의 세 방향 모두 보드 범위 내에 있다") + void 초나라_졸_모든_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(2, 5); + Piece piece = new Piece(Team.CHO, PieceType.ZOL); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(1, 5), new Position(2, 4), new Position(3, 5) + ); + } + + @Test + @DisplayName("한나라 졸의 세 방향 모두 보드 범위 내에 있다") + void 한나라_졸_모든_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(3, 4); + Piece piece = new Piece(Team.HAN, PieceType.ZOL); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(3, 5), new Position(2, 4), new Position(4, 4) + ); + } + + @Test + @DisplayName("마의 8방향 모두 보드 범위 내에 있다") + void 마_모든_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(4, 6); + Piece piece = new Piece(Team.CHO, PieceType.MA); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(3, 4), new Position(5, 4), new Position(6, 5), new Position(6, 7), + new Position(3, 8), new Position(5, 8), new Position(2, 5), new Position(2, 7) + ); + } + + @Test + @DisplayName("상의 8방향 모두 보드 범위 내에 있다") + void 상_모든_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(5, 7); + Piece piece = new Piece(Team.CHO, PieceType.SANG); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(3, 4), new Position(7, 4), new Position(8, 5), new Position(8, 9), + new Position(3, 10), new Position(7, 10), new Position(2, 5), new Position(2, 9) + ); + } + + @Test + @DisplayName("사의 8방향 모두 보드 범위 내에 있다") + void 사_모든_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(5, 9); + Piece piece = new Piece(Team.CHO, PieceType.SA); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(5, 8), new Position(6, 9), new Position(5, 10), new Position(4, 9), + new Position(4, 8), new Position(6, 8), new Position(6, 10), new Position(4, 10) + ); + } + + @Test + @DisplayName("왕의 8방향 모두 보드 범위 내에 있다") + void 왕_모든_경로_가능() { + // given + Board board = new Board(); + Position position = new Position(5, 9); + Piece piece = new Piece(Team.CHO, PieceType.KING); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(5, 8), new Position(6, 9), new Position(5, 10), new Position(4, 9), + new Position(4, 8), new Position(6, 8), new Position(6, 10), new Position(4, 10) + ); + } + + @Test + @DisplayName("차는 현재 위치에서 보드 범위 내에서 상하좌우로 계속 갈 수 있다") + void 차_보드_범위_내_상하좌우_계속_가능() { + // given + Board board = new Board(); + Position position = new Position(2, 8); + Piece piece = new Piece(Team.HAN, PieceType.CHA); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(2, 1), new Position(2, 2), new Position(2, 3), new Position(2, 4), + new Position(2, 5), new Position(2, 6), new Position(2, 7), + new Position(2, 9), new Position(2, 10), + + new Position(1, 8), + new Position(3, 8), new Position(4, 8), new Position(5, 8), new Position(6, 8), + new Position(7, 8), new Position(8, 8), new Position(9, 8) + ); + } + + @Test + @DisplayName("포는 현재 위치에서 보드 범위 내에서 상하좌우로 계속 갈 수 있다") + void 포_보드_범위_내_상하좌우_계속_가능() { + // given + Board board = new Board(); + Position position = new Position(2, 8); + Piece piece = new Piece(Team.HAN, PieceType.PO); + board.place(position, piece); + + // when + Map> result = routeConverter.convertToPosition(board, position); + + // then + assertThat(result.keySet()).containsExactlyInAnyOrder( + new Position(2, 1), new Position(2, 2), new Position(2, 3), new Position(2, 4), + new Position(2, 5), new Position(2, 6), new Position(2, 7), + new Position(2, 9), new Position(2, 10), + + new Position(1, 8), + new Position(3, 8), new Position(4, 8), new Position(5, 8), new Position(6, 8), + new Position(7, 8), new Position(8, 8), new Position(9, 8) + ); + } +}