From 2c15f8e06224bd75366c2e6acf2365f3080de54a Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Wed, 25 Mar 2026 13:54:03 +0900 Subject: [PATCH 01/40] =?UTF-8?q?docs:=20README=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EB=AA=85=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/README.md b/README.md index 9775dda0ae..e7fe63ec4d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,85 @@ # java-janggi 장기 미션 저장소 + + +**주요 기능** + +- [ ] 플레이어는 ‘상 차림’을 결정할 수 있다. +- [ ] 기물은 자동으로 배치된다. +- [ ] 현재 장기판의 현황을 볼 수 있다. +- [ ] 초나라(선)/한나라(후) 번갈아가며 플레이한다. +- [ ] 플레이어는 기물의 이동 규칙에 따라 이동시킬 수 있다. +- [ ] 상대 플레이어의 기물을 잡을 수 있다. +- [ ] 상대 플레이어의 왕을 잡으면 승리하고, 게임은 종료된다. + +### **실행 예시** + +``` +초나라 상 차림을 결정해주세요. +1. [마 상 마 상] +2. [마 상 상 마] +3. [상 마 상 마] +4. [상 마 마 상] + +2 + +한나라 상 차림을 결정해주세요. +1. [마 상 마 상] +2. [마 상 상 마] +3. [상 마 상 마] +4. [상 마 마 상] + +3 + +기물이 배치 되었습니다. + A B C D E F G H I + 1 車 象 馬 士 · 士 象 馬 車 + 2 · · · · 漢 · · · · + 3 · 砲 · · · · · 砲 · + 4 兵 · 兵 · 兵 · 兵 · 兵 + 5 · · · · · · · · · + 6 · · · · · · · · · + 7 卒 · 卒 · 卒 · 卒 · 卒 + 8 · 炮 · · · · · 炮 · + 9 · · · · 楚 · · · · + 0 車 馬 相 士 · 士 相 馬 車 + +초나라 플레이어는 말을 선택해주세요.(입력예시 좌표: A, 1) +좌표: A, 0 + +초나라 플레이어는 선택한 말을 움직일 위치를 입력해 주세요.(입력예시 좌표: A, 3) +좌표: A, 8 + +이동되었습니다. + A B C D E F G H I + 1 車 象 馬 士 · 士 象 馬 車 + 2 · · · · 漢 · · · · + 3 · 砲 · · · · · 砲 · + 4 兵 · 兵 · 兵 · 兵 · 兵 + 5 · · · · · · · · · + 6 · · · · · · · · · + 7 卒 · 卒 · 卒 · 卒 · 卒 + 8 車 炮 · · · · · 炮 · + 9 · · · · 楚 · · · · + 0 · 馬 相 士 · 士 相 馬 車 +``` + +**입력** + +- [ ] ‘상 차림’ 배치 타입 입력받는다. +- [ ] 선택할 기물의 좌표를 입력받는다. + - [ ] `[ERROR]` 해당 좌표에 기물이 없을 때 + - [ ] `[ERROR]` 선택한 기물이 플레이어의 기물이 아닐 때 +- [ ] 이동할 좌표를 입력받는다. + - [ ] `[ERROR]` 이동할 좌표가 보드 크기 내에 유효하지 않을 때 + - [ ] `[ERROR]` 해당 좌표에 플레이어의 팀 기물이 있을 때 + - [ ] `[ERROR]` 이동 규칙에 따라 이동할 수 없을 때 + +**출력** + +- [ ] 4 종류의 ‘상 차림’ 배치를 출력한다. +- [ ] 기물이 배치된 보드를 출력한다. +- [ ] 현재 턴을 출력한다. +- [ ] 턴이 끝나고 기물 이동이 된 보드를 출력한다. +- [ ] 최종 승패를 출력한다. From 38f70918c27c57db3ae2bd81fc14e4f3e5863929 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 17:41:11 +0900 Subject: [PATCH 02/40] =?UTF-8?q?test:=20=EC=9C=84=EC=B9=98=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=20=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=98=88=EC=99=B8?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/PositionTest.java | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/domain/PositionTest.java diff --git a/src/test/java/domain/PositionTest.java b/src/test/java/domain/PositionTest.java new file mode 100644 index 0000000000..5c281f92a9 --- /dev/null +++ b/src/test/java/domain/PositionTest.java @@ -0,0 +1,39 @@ +package domain; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +class PositionTest { + + @ParameterizedTest + @CsvSource({ + "1, 0", + "1, 9", + "9, 0", + "9, 9", + "3, 4" + }) + void 정상_생성_테스트(int x, int y) { + Assertions.assertThat(new Position(x, y)).isInstanceOf(Position.class); + } + + @ParameterizedTest + @ValueSource(ints = {-1, 0, 10, 12}) + void X_예외_값_입력_오류_검증(int x) { + assertThatThrownBy(() -> new Position(x, 4)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]", "x 좌표는"); + } + + @ParameterizedTest + @ValueSource(ints = {-5, -1, 10, 12, 1000}) + void Y_예외_값_입력_오류_검증(int y) { + assertThatThrownBy(() -> new Position(1, y)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("[ERROR]", "y좌표"); + } +} From eec72c2f8a1d41e738561838900ed195f62e3224 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 17:47:29 +0900 Subject: [PATCH 03/40] =?UTF-8?q?feat:=20=EC=9C=84=EC=B9=98=20=EA=B0=9D?= =?UTF-8?q?=EC=B2=B4=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/domain/Position.java | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/java/domain/Position.java diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java new file mode 100644 index 0000000000..b60ed8ce51 --- /dev/null +++ b/src/main/java/domain/Position.java @@ -0,0 +1,45 @@ +package domain; + +import java.util.Objects; + +public class Position { + + private final int x; + private final int y; + + public Position(int x, int y) { + validatePosX(x); + validatePosY(y); + this.x = x; + this.y = y; + } + + private void validatePosX(int x) { + if (x < 1 || x > 9) { + throw new IllegalArgumentException("[ERROR] x 좌표는 1~9 사이어야합니다."); + } + } + + private void validatePosY(int y) { + if (y < 0 || y > 9) { + throw new IllegalArgumentException("[ERROR] y 좌표는 0~9 사이어야합니다."); + } + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Position position = (Position) o; + return x == position.x && y == position.y; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } +} From 4eece5ca27e125afe301fe0879c2415d764594ba Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 18:17:34 +0900 Subject: [PATCH 04/40] =?UTF-8?q?test:=20=EA=B8=B0=EB=AC=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/PieceGeneratorTest.java | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/java/PieceGeneratorTest.java diff --git a/src/test/java/PieceGeneratorTest.java b/src/test/java/PieceGeneratorTest.java new file mode 100644 index 0000000000..8035700c2e --- /dev/null +++ b/src/test/java/PieceGeneratorTest.java @@ -0,0 +1,31 @@ +import domain.Camp; +import domain.ElephantFormation; +import domain.PieceGenerator; +import domain.Position; +import domain.pieces.Piece; +import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PieceGeneratorTest { + + @Test + void 한나라_말_16개_생성() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.HAN, + ElephantFormation.RIGHT); + + Assertions.assertEquals(board.size(), 16); + } + + @Test + void 초나라_말_16개_생성() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.CHO, + ElephantFormation.RIGHT); + + Assertions.assertEquals(board.size(), 16); + } +} From 8d1d684da721754400a537a3ca73d3d51d570134 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 18:18:55 +0900 Subject: [PATCH 05/40] =?UTF-8?q?test:=20=EC=83=81=EC=B0=A8=EB=A6=BC?= =?UTF-8?q?=EB=B3=84=20=EA=B8=B0=EB=AC=BC=20=EB=B0=B0=EC=B9=98=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/PieceGeneratorTest.java | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/src/test/java/PieceGeneratorTest.java b/src/test/java/PieceGeneratorTest.java index 8035700c2e..970bf902dc 100644 --- a/src/test/java/PieceGeneratorTest.java +++ b/src/test/java/PieceGeneratorTest.java @@ -2,6 +2,8 @@ import domain.ElephantFormation; import domain.PieceGenerator; import domain.Position; +import domain.pieces.Elephant; +import domain.pieces.Horse; import domain.pieces.Piece; import java.util.Map; import org.junit.jupiter.api.Assertions; @@ -28,4 +30,109 @@ public class PieceGeneratorTest { Assertions.assertEquals(board.size(), 16); } + + @Test + void 한나라_오른상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.HAN, + ElephantFormation.RIGHT); + + Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Horse.class); + } + + @Test + void 한나라_왼상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.HAN, + ElephantFormation.LEFT); + + Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Elephant.class); + } + + @Test + void 한나라_안상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.HAN, + ElephantFormation.INNER); + + Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Horse.class); + } + + @Test + void 한나라_바깥상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.HAN, + ElephantFormation.OUTER); + + Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Elephant.class); + } + + + @Test + void 초나라_오른상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.CHO, + ElephantFormation.RIGHT); + + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Elephant.class); + } + + @Test + void 초나라_왼상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.CHO, + ElephantFormation.LEFT); + + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Horse.class); + } + + @Test + void 초나라_안상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.CHO, + ElephantFormation.INNER); + + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Horse.class); + } + + @Test + void 초나라_바깥상차림() { + PieceGenerator pieceGenerator = new PieceGenerator(); + + Map board = pieceGenerator.generatePieces(Camp.CHO, + ElephantFormation.OUTER); + + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Elephant.class); + } } From 488805eceb11324b4b27d9db2b4a8853bc9a4687 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:04:27 +0900 Subject: [PATCH 06/40] =?UTF-8?q?feat:=20=EA=B0=81=20=EA=B8=B0=EB=AC=BC=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=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/domain/pieces/Cannon.java | 10 ++++++++++ src/main/java/domain/pieces/Chariot.java | 10 ++++++++++ src/main/java/domain/pieces/Elephant.java | 10 ++++++++++ src/main/java/domain/pieces/General.java | 10 ++++++++++ src/main/java/domain/pieces/Guard.java | 10 ++++++++++ src/main/java/domain/pieces/Horse.java | 10 ++++++++++ src/main/java/domain/pieces/Piece.java | 12 ++++++++++++ src/main/java/domain/pieces/Soldier.java | 10 ++++++++++ 8 files changed, 82 insertions(+) create mode 100644 src/main/java/domain/pieces/Cannon.java create mode 100644 src/main/java/domain/pieces/Chariot.java create mode 100644 src/main/java/domain/pieces/Elephant.java create mode 100644 src/main/java/domain/pieces/General.java create mode 100644 src/main/java/domain/pieces/Guard.java create mode 100644 src/main/java/domain/pieces/Horse.java create mode 100644 src/main/java/domain/pieces/Piece.java create mode 100644 src/main/java/domain/pieces/Soldier.java diff --git a/src/main/java/domain/pieces/Cannon.java b/src/main/java/domain/pieces/Cannon.java new file mode 100644 index 0000000000..90aa03d6fe --- /dev/null +++ b/src/main/java/domain/pieces/Cannon.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class Cannon extends Piece { + + public Cannon(Camp camp) { + super(camp); + } +} diff --git a/src/main/java/domain/pieces/Chariot.java b/src/main/java/domain/pieces/Chariot.java new file mode 100644 index 0000000000..b302d560c8 --- /dev/null +++ b/src/main/java/domain/pieces/Chariot.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class Chariot extends Piece { + + public Chariot(Camp camp) { + super(camp); + } +} diff --git a/src/main/java/domain/pieces/Elephant.java b/src/main/java/domain/pieces/Elephant.java new file mode 100644 index 0000000000..dbd453fbd9 --- /dev/null +++ b/src/main/java/domain/pieces/Elephant.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class Elephant extends Piece { + + public Elephant(Camp camp) { + super(camp); + } +} diff --git a/src/main/java/domain/pieces/General.java b/src/main/java/domain/pieces/General.java new file mode 100644 index 0000000000..52ffb34816 --- /dev/null +++ b/src/main/java/domain/pieces/General.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class General extends Piece { + + public General(Camp camp) { + super(camp); + } +} diff --git a/src/main/java/domain/pieces/Guard.java b/src/main/java/domain/pieces/Guard.java new file mode 100644 index 0000000000..cc2df4b71e --- /dev/null +++ b/src/main/java/domain/pieces/Guard.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class Guard extends Piece { + + public Guard(Camp camp) { + super(camp); + } +} diff --git a/src/main/java/domain/pieces/Horse.java b/src/main/java/domain/pieces/Horse.java new file mode 100644 index 0000000000..309315c553 --- /dev/null +++ b/src/main/java/domain/pieces/Horse.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class Horse extends Piece { + + public Horse(Camp camp) { + super(camp); + } +} diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java new file mode 100644 index 0000000000..740d7db861 --- /dev/null +++ b/src/main/java/domain/pieces/Piece.java @@ -0,0 +1,12 @@ +package domain.pieces; + +import domain.Camp; + +public class Piece { + + private final Camp camp; + + public Piece(Camp camp) { + this.camp = camp; + } +} diff --git a/src/main/java/domain/pieces/Soldier.java b/src/main/java/domain/pieces/Soldier.java new file mode 100644 index 0000000000..18494450a7 --- /dev/null +++ b/src/main/java/domain/pieces/Soldier.java @@ -0,0 +1,10 @@ +package domain.pieces; + +import domain.Camp; + +public class Soldier extends Piece { + + public Soldier(Camp camp) { + super(camp); + } +} From 74217a1a4e321a6d33d34228e77bc4bf56ce23b1 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:13:29 +0900 Subject: [PATCH 07/40] =?UTF-8?q?feat:=20=EC=B4=88=EB=82=98=EB=9D=BC/?= =?UTF-8?q?=ED=95=9C=EB=82=98=EB=9D=BC=20=EA=B5=AC=EB=B6=84=20enum=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Camp.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/java/domain/Camp.java diff --git a/src/main/java/domain/Camp.java b/src/main/java/domain/Camp.java new file mode 100644 index 0000000000..3b42eb64a3 --- /dev/null +++ b/src/main/java/domain/Camp.java @@ -0,0 +1,6 @@ +package domain; + +public enum Camp { + HAN, + CHO +} From 1966e6695b7c04feb9aeba7b878cd9fe6c39b7c5 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:14:18 +0900 Subject: [PATCH 08/40] =?UTF-8?q?feat:=20=EA=B8=B0=EB=AC=BC=EB=B3=84=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=20=EC=9C=84=EC=B9=98=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EB=A5=BC=20=EA=B0=80=EC=A7=84=20enum=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/domain/PieceLocation.java | 139 ++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/main/java/domain/PieceLocation.java diff --git a/src/main/java/domain/PieceLocation.java b/src/main/java/domain/PieceLocation.java new file mode 100644 index 0000000000..8f70678850 --- /dev/null +++ b/src/main/java/domain/PieceLocation.java @@ -0,0 +1,139 @@ +package domain; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum PieceLocation { + GENERAL(initGeneralPosition()), + GUARD(initGuardPosition()), + HORSE(initHorsePosition()), + CANNON(initCannonPosition()), + ELEPHANT(initElephantPosition()), + SOLDIER(initSoldierPosition()), + CHARIOT(initChariotPosition()); + + private final Map> positions; + + PieceLocation(Map> positions) { + this.positions = positions; + } + + private static Map> initGeneralPosition() { + Map> generalPosition = new HashMap<>(); + generalPosition.put(Camp.HAN, List.of( + new Position(5, 2) + )); + + generalPosition.put(Camp.CHO, List.of( + new Position(5, 9) + )); + + return generalPosition; + } + + private static Map> initGuardPosition() { + Map> guardPosition = new HashMap<>(); + guardPosition.put(Camp.HAN, List.of( + new Position(4, 1), + new Position(6, 1) + )); + + guardPosition.put(Camp.CHO, List.of( + new Position(4, 0), + new Position(6, 0) + )); + + return guardPosition; + } + + private static Map> initHorsePosition() { + Map> horsePosition = new HashMap<>(); + + horsePosition.put(Camp.HAN, List.of( + new Position(3, 1), + new Position(8, 1) + )); + + horsePosition.put(Camp.CHO, List.of( + new Position(2, 0), + new Position(8, 0) + )); + + return horsePosition; + } + + private static Map> initCannonPosition() { + Map> cannonPosition = new HashMap<>(); + + cannonPosition.put(Camp.HAN, List.of( + new Position(2, 3), + new Position(8, 3) + )); + cannonPosition.put(Camp.CHO, List.of( + new Position(2, 8), + new Position(8, 8) + )); + + return cannonPosition; + } + + private static Map> initElephantPosition() { + Map> elephantPosition = new HashMap<>(); + + elephantPosition.put(Camp.HAN, List.of( + new Position(2, 1), + new Position(7, 1) + )); + elephantPosition.put(Camp.CHO, List.of( + new Position(3, 0), + new Position(7, 0) + )); + + return elephantPosition; + } + + private static Map> initSoldierPosition() { + Map> soldierPosition = new HashMap<>(); + + soldierPosition.put(Camp.HAN, List.of( + new Position(1, 4), + new Position(3, 4), + new Position(5, 4), + new Position(7, 4), + new Position(9, 4) + )); + soldierPosition.put(Camp.CHO, List.of( + new Position(1, 7), + new Position(3, 7), + new Position(5, 7), + new Position(7, 7), + new Position(9, 7) + )); + + return soldierPosition; + } + + private static Map> initChariotPosition() { + Map> chariotPosition = new HashMap<>(); + + chariotPosition.put(Camp.HAN, List.of( + new Position(1, 1), + new Position(9, 1)) + ); + chariotPosition.put(Camp.CHO, List.of( + new Position(1, 0), + new Position(9, 0)) + ); + + return chariotPosition; + } + + public List getPositions(Camp camp) { + return positions.get(camp); + } + + public List getPositions(Camp camp, ElephantFormation formation) { + return formation.getPositions(this, camp); + } +} From 9775ac19dbfd2c66fce992d9a0485e3949d72995 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:15:52 +0900 Subject: [PATCH 09/40] =?UTF-8?q?feat:=20=EC=83=81=EC=B0=A8=EB=A6=BC?= =?UTF-8?q?=EB=B3=84=20=EC=83=81/=EB=A7=88=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EA=B0=80=EC=A7=84=20enum=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/ElephantFormation.java | 146 ++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/main/java/domain/ElephantFormation.java diff --git a/src/main/java/domain/ElephantFormation.java b/src/main/java/domain/ElephantFormation.java new file mode 100644 index 0000000000..a1d01d3196 --- /dev/null +++ b/src/main/java/domain/ElephantFormation.java @@ -0,0 +1,146 @@ +package domain; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public enum ElephantFormation { + RIGHT(initRight()), + INNER(initInner()), + LEFT(initLeft()), + OUTER(initOuter()); + + private final Map>> positions; + + ElephantFormation(Map>> positions) { + this.positions = positions; + } + + private static Map>> initRight() { + Map>> position = new HashMap<>(); + Map> horseRightPosition = new HashMap<>(); + horseRightPosition.put(Camp.HAN, List.of( + new Position(3, 1), + new Position(8, 1) + )); + + horseRightPosition.put(Camp.CHO, List.of( + new Position(2, 0), + new Position(7, 0) + )); + + position.put(PieceLocation.HORSE, horseRightPosition); + + Map> elephantRightPosition = new HashMap<>(); + elephantRightPosition.put(Camp.HAN, List.of( + new Position(2, 1), + new Position(7, 1) + )); + + elephantRightPosition.put(Camp.CHO, List.of( + new Position(3, 0), + new Position(8, 0) + )); + + position.put(PieceLocation.ELEPHANT, elephantRightPosition); + + return position; + } + + private static Map>> initInner() { + Map>> position = new HashMap<>(); + Map> horseInnerPosition = new HashMap<>(); + horseInnerPosition.put(Camp.HAN, List.of( + new Position(2, 1), + new Position(8, 1) + )); + + horseInnerPosition.put(Camp.CHO, List.of( + new Position(2, 0), + new Position(8, 0) + )); + + position.put(PieceLocation.HORSE, horseInnerPosition); + + Map> elephantInnerPosition = new HashMap<>(); + elephantInnerPosition.put(Camp.HAN, List.of( + new Position(3, 1), + new Position(7, 1) + )); + + elephantInnerPosition.put(Camp.CHO, List.of( + new Position(3, 0), + new Position(7, 0) + )); + + position.put(PieceLocation.ELEPHANT, elephantInnerPosition); + + return position; + } + + private static Map>> initLeft() { + Map>> position = new HashMap<>(); + Map> horseLeftPosition = new HashMap<>(); + horseLeftPosition.put(Camp.HAN, List.of( + new Position(2, 1), + new Position(7, 1) + )); + + horseLeftPosition.put(Camp.CHO, List.of( + new Position(3, 0), + new Position(8, 0) + )); + + position.put(PieceLocation.HORSE, horseLeftPosition); + + Map> elephantLeftPosition = new HashMap<>(); + elephantLeftPosition.put(Camp.HAN, List.of( + new Position(3, 1), + new Position(8, 1) + )); + + elephantLeftPosition.put(Camp.CHO, List.of( + new Position(2, 0), + new Position(7, 0) + )); + + position.put(PieceLocation.ELEPHANT, elephantLeftPosition); + + return position; + } + + private static Map>> initOuter() { + Map>> position = new HashMap<>(); + Map> horseOuterPosition = new HashMap<>(); + horseOuterPosition.put(Camp.HAN, List.of( + new Position(3, 1), + new Position(7, 1) + )); + + horseOuterPosition.put(Camp.CHO, List.of( + new Position(3, 0), + new Position(7, 0) + )); + + position.put(PieceLocation.HORSE, horseOuterPosition); + + Map> elephantOuterPosition = new HashMap<>(); + elephantOuterPosition.put(Camp.HAN, List.of( + new Position(2, 1), + new Position(8, 1) + )); + + elephantOuterPosition.put(Camp.CHO, List.of( + new Position(2, 0), + new Position(8, 0) + )); + + position.put(PieceLocation.ELEPHANT, elephantOuterPosition); + + return position; + } + + public List getPositions(PieceLocation pieceLocation, Camp camp) { + return positions.get(pieceLocation).get(camp); + } +} From 9832ec28a5a2a79de612d4606f39f40774fe6393 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:19:42 +0900 Subject: [PATCH 10/40] =?UTF-8?q?feat:=20=EC=83=81=EC=B0=A8=EB=A6=BC=20?= =?UTF-8?q?=EC=A0=84=EB=9E=B5=EC=97=90=20=EB=94=B0=EB=A5=B8=20=ED=8F=AC?= =?UTF-8?q?=EC=A7=80=EC=85=98=20=EB=B0=8F=20=EA=B8=B0=EB=AC=BC=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/PieceGenerator.java | 86 ++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/main/java/domain/PieceGenerator.java diff --git a/src/main/java/domain/PieceGenerator.java b/src/main/java/domain/PieceGenerator.java new file mode 100644 index 0000000000..8329d1527e --- /dev/null +++ b/src/main/java/domain/PieceGenerator.java @@ -0,0 +1,86 @@ +package domain; + +import domain.pieces.Cannon; +import domain.pieces.Chariot; +import domain.pieces.Elephant; +import domain.pieces.General; +import domain.pieces.Guard; +import domain.pieces.Horse; +import domain.pieces.Piece; +import domain.pieces.Soldier; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PieceGenerator { + + public Map generatePieces(Camp camp, ElephantFormation elephantFormation) { + Map board = new HashMap<>(); + board.putAll(generateGeneral(camp)); + board.putAll(generateSoldier(camp)); + board.putAll(generateGuard(camp)); + board.putAll(generateHorse(camp, elephantFormation)); + board.putAll(generateElephant(camp, elephantFormation)); + board.putAll(generateCannon(camp)); + board.putAll(generateChariot(camp)); + + return board; + } + + private Map generateGeneral(Camp camp) { + Map generalPosition = new HashMap<>(); + + List positions = PieceLocation.GENERAL.getPositions(camp); + positions.forEach(position -> generalPosition.put(position, new General(camp))); + + return generalPosition; + } + + private Map generateSoldier(Camp camp) { + Map soldierPosition = new HashMap<>(); + List positions = PieceLocation.SOLDIER.getPositions(camp); + positions.forEach(position -> soldierPosition.put(position, new Soldier(camp))); + + return soldierPosition; + } + + private Map generateGuard(Camp camp) { + Map guardPosition = new HashMap<>(); + List positions = PieceLocation.GUARD.getPositions(camp); + positions.forEach(position -> guardPosition.put(position, new Guard(camp))); + + return guardPosition; + } + + private Map generateHorse(Camp camp, ElephantFormation elephantFormation) { + Map horsePosition = new HashMap<>(); + List positions = PieceLocation.HORSE.getPositions(camp, elephantFormation); + positions.forEach(position -> horsePosition.put(position, new Horse(camp))); + + return horsePosition; + } + + private Map generateCannon(Camp camp) { + Map cannonPosition = new HashMap<>(); + List positions = PieceLocation.CANNON.getPositions(camp); + positions.forEach(position -> cannonPosition.put(position, new Cannon(camp))); + + return cannonPosition; + } + + private Map generateElephant(Camp camp, ElephantFormation elephantFormation) { + Map elephantPosition = new HashMap<>(); + List positions = PieceLocation.ELEPHANT.getPositions(camp, elephantFormation); + positions.forEach(position -> elephantPosition.put(position, new Elephant(camp))); + + return elephantPosition; + } + + private Map generateChariot(Camp camp) { + Map chariotPosition = new HashMap<>(); + List positions = PieceLocation.CHARIOT.getPositions(camp); + positions.forEach(position -> chariotPosition.put(position, new Chariot(camp))); + + return chariotPosition; + } +} From af8fa6cc5bbf0964b3936a2ba5243dbfb24c6e6b Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:23:13 +0900 Subject: [PATCH 11/40] =?UTF-8?q?docs:=20README=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e7fe63ec4d..1a69369739 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,10 @@ 장기 미션 저장소 - **주요 기능** - [ ] 플레이어는 ‘상 차림’을 결정할 수 있다. -- [ ] 기물은 자동으로 배치된다. +- [x] 기물은 자동으로 배치된다. - [ ] 현재 장기판의 현황을 볼 수 있다. - [ ] 초나라(선)/한나라(후) 번갈아가며 플레이한다. - [ ] 플레이어는 기물의 이동 규칙에 따라 이동시킬 수 있다. @@ -69,12 +68,12 @@ - [ ] ‘상 차림’ 배치 타입 입력받는다. - [ ] 선택할 기물의 좌표를 입력받는다. - - [ ] `[ERROR]` 해당 좌표에 기물이 없을 때 - - [ ] `[ERROR]` 선택한 기물이 플레이어의 기물이 아닐 때 + - [ ] `[ERROR]` 해당 좌표에 기물이 없을 때 + - [ ] `[ERROR]` 선택한 기물이 플레이어의 기물이 아닐 때 - [ ] 이동할 좌표를 입력받는다. - - [ ] `[ERROR]` 이동할 좌표가 보드 크기 내에 유효하지 않을 때 - - [ ] `[ERROR]` 해당 좌표에 플레이어의 팀 기물이 있을 때 - - [ ] `[ERROR]` 이동 규칙에 따라 이동할 수 없을 때 + - [ ] `[ERROR]` 이동할 좌표가 보드 크기 내에 유효하지 않을 때 + - [ ] `[ERROR]` 해당 좌표에 플레이어의 팀 기물이 있을 때 + - [ ] `[ERROR]` 이동 규칙에 따라 이동할 수 없을 때 **출력** From e7d1eafed13b3aaff9d5caca0d7b77a03da913e5 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Thu, 26 Mar 2026 20:24:20 +0900 Subject: [PATCH 12/40] =?UTF-8?q?docs:=20README=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1a69369739..b1b170c4fa 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ 3 기물이 배치 되었습니다. - A B C D E F G H I - 1 車 象 馬 士 · 士 象 馬 車 + 1 2 3 4 5 6 7 8 9 + 1 車 馬 象 士 · 士 馬 象 車 2 · · · · 漢 · · · · 3 · 砲 · · · · · 砲 · 4 兵 · 兵 · 兵 · 兵 · 兵 @@ -44,15 +44,15 @@ 9 · · · · 楚 · · · · 0 車 馬 相 士 · 士 相 馬 車 -초나라 플레이어는 말을 선택해주세요.(입력예시 좌표: A, 1) -좌표: A, 0 +초나라 플레이어는 말을 선택해주세요.(입력예시 좌표: 1, 1) +좌표: 1, 0 -초나라 플레이어는 선택한 말을 움직일 위치를 입력해 주세요.(입력예시 좌표: A, 3) -좌표: A, 8 +초나라 플레이어는 선택한 말을 움직일 위치를 입력해 주세요.(입력예시 좌표: 1, 3) +좌표: 1, 8 이동되었습니다. - A B C D E F G H I - 1 車 象 馬 士 · 士 象 馬 車 + 1 2 3 4 5 6 7 8 9 + 1 車 馬 象 士 · 士 馬 象 車 2 · · · · 漢 · · · · 3 · 砲 · · · · · 砲 · 4 兵 · 兵 · 兵 · 兵 · 兵 From f3b5bea805df486b5c5e8e866ed0b7fd259bf9e8 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Fri, 27 Mar 2026 19:12:33 +0900 Subject: [PATCH 13/40] =?UTF-8?q?test(Board):=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EB=82=B4=20=EA=B8=B0=EB=AC=BC=20=EC=9D=B4=EB=8F=99=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/BoardTest.java | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/test/java/BoardTest.java diff --git a/src/test/java/BoardTest.java b/src/test/java/BoardTest.java new file mode 100644 index 0000000000..d67d802159 --- /dev/null +++ b/src/test/java/BoardTest.java @@ -0,0 +1,48 @@ +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import domain.Board; +import domain.Camp; +import domain.Position; +import domain.pieces.Piece; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class BoardTest { + + @Test + void 특정_위치에_기물을_놓을_수_있다() { + Board board = new Board(); + Position position = new Position(2, 3); + Piece piece = new Piece(Camp.HAN); + board.locatePiece(position, piece); + + Assertions.assertEquals(board.getPieceFrom(position), piece); + } + + @Test + void 같은_팀_기물은_잡을_수_없다() { + Board board = new Board(); + Position position = new Position(2, 3); + Piece locatedPiece = new Piece(Camp.HAN); + Piece anotherPiece = new Piece(Camp.HAN); + board.locatePiece(position, locatedPiece); + + assertThatThrownBy(() -> board.locatePiece(position, anotherPiece)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("[ERROR]", "같은 팀"); + } + + @Test + void 기물을_이동시킬_수_있다() { + Board board = new Board(); + Position fromPosition = new Position(2,3); + Position toPosition = new Position(2,4); + + Piece piece = new Piece(Camp.HAN); + board.locatePiece(fromPosition, piece); //초기 배치 + + board.move(fromPosition, toPosition); // A위치의 기물을 B로 옮긴다. + + Assertions.assertFalse(board.isExist(fromPosition)); + Assertions.assertEquals(board.getPieceFrom(toPosition).getClass(), piece.getClass()); + } +} From 4677afada54bc8d1bb6c6be330341a1a3d8c5fdf Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Fri, 27 Mar 2026 19:13:43 +0900 Subject: [PATCH 14/40] =?UTF-8?q?feat:=20=EB=B3=B4=EB=93=9C=20=EB=82=B4=20?= =?UTF-8?q?=EA=B8=B0=EB=AC=BC=20=EC=9D=B4=EB=8F=99=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/domain/Board.java | 37 ++++++++++++++++++++++++++ src/main/java/domain/pieces/Piece.java | 4 +++ 2 files changed, 41 insertions(+) create mode 100644 src/main/java/domain/Board.java diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java new file mode 100644 index 0000000000..9c915c5634 --- /dev/null +++ b/src/main/java/domain/Board.java @@ -0,0 +1,37 @@ +package domain; + +import domain.pieces.Piece; +import java.util.HashMap; +import java.util.Map; + +public class Board { + + private final Map board = new HashMap<>(); + + public void locatePiece(Position position, Piece piece) { + if (!isExist(position)) { + board.put(position, piece); + return; + } + + if (getPieceFrom(position).isSameCamp(piece)) { + throw new IllegalArgumentException("[ERROR] 같은 팀은 잡을 수 없습니다!"); + } + + board.put(position, piece); + } + + public Piece getPieceFrom(Position position) { + return board.get(position); + } + + public boolean isExist(Position position) { + return board.containsKey(position); + } + + public void move(Position fromPosition, Position toPosition) { + Piece piece = board.get(fromPosition); + board.remove(fromPosition); + locatePiece(toPosition, piece); + } +} diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 740d7db861..fe7eb6181d 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -9,4 +9,8 @@ public class Piece { public Piece(Camp camp) { this.camp = camp; } + + public boolean isSameCamp(Piece comparedPiece) { + return this.camp == comparedPiece.camp; + } } From 0de8449b2992fe77c8934f849a2306f865f54366 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Sun, 29 Mar 2026 19:45:45 +0900 Subject: [PATCH 15/40] =?UTF-8?q?refactor:=20=EC=A2=8C=ED=91=9C=20?= =?UTF-8?q?=EA=B8=B0=EC=A4=80=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/domain/ElephantFormation.java | 64 ++++++++++----------- src/main/java/domain/PieceLocation.java | 64 ++++++++++----------- src/main/java/domain/Position.java | 12 +++- src/test/java/PieceGeneratorTest.java | 64 ++++++++++----------- src/test/java/domain/PositionTest.java | 12 ++-- 5 files changed, 112 insertions(+), 104 deletions(-) diff --git a/src/main/java/domain/ElephantFormation.java b/src/main/java/domain/ElephantFormation.java index a1d01d3196..8f32b22c53 100644 --- a/src/main/java/domain/ElephantFormation.java +++ b/src/main/java/domain/ElephantFormation.java @@ -20,26 +20,26 @@ private static Map>> initRight() { Map>> position = new HashMap<>(); Map> horseRightPosition = new HashMap<>(); horseRightPosition.put(Camp.HAN, List.of( - new Position(3, 1), - new Position(8, 1) + new Position(2, 0), + new Position(7, 0) )); horseRightPosition.put(Camp.CHO, List.of( - new Position(2, 0), - new Position(7, 0) + new Position(1, 9), + new Position(6, 9) )); position.put(PieceLocation.HORSE, horseRightPosition); Map> elephantRightPosition = new HashMap<>(); elephantRightPosition.put(Camp.HAN, List.of( - new Position(2, 1), - new Position(7, 1) + new Position(1, 0), + new Position(6, 0) )); elephantRightPosition.put(Camp.CHO, List.of( - new Position(3, 0), - new Position(8, 0) + new Position(2, 9), + new Position(7, 9) )); position.put(PieceLocation.ELEPHANT, elephantRightPosition); @@ -51,26 +51,26 @@ private static Map>> initInner() { Map>> position = new HashMap<>(); Map> horseInnerPosition = new HashMap<>(); horseInnerPosition.put(Camp.HAN, List.of( - new Position(2, 1), - new Position(8, 1) + new Position(1, 0), + new Position(7, 0) )); horseInnerPosition.put(Camp.CHO, List.of( - new Position(2, 0), - new Position(8, 0) + new Position(1, 9), + new Position(7, 9) )); position.put(PieceLocation.HORSE, horseInnerPosition); Map> elephantInnerPosition = new HashMap<>(); elephantInnerPosition.put(Camp.HAN, List.of( - new Position(3, 1), - new Position(7, 1) + new Position(2, 0), + new Position(6, 0) )); elephantInnerPosition.put(Camp.CHO, List.of( - new Position(3, 0), - new Position(7, 0) + new Position(2, 9), + new Position(6, 9) )); position.put(PieceLocation.ELEPHANT, elephantInnerPosition); @@ -82,26 +82,26 @@ private static Map>> initLeft() { Map>> position = new HashMap<>(); Map> horseLeftPosition = new HashMap<>(); horseLeftPosition.put(Camp.HAN, List.of( - new Position(2, 1), - new Position(7, 1) + new Position(1, 0), + new Position(6, 0) )); horseLeftPosition.put(Camp.CHO, List.of( - new Position(3, 0), - new Position(8, 0) + new Position(2, 9), + new Position(7, 9) )); position.put(PieceLocation.HORSE, horseLeftPosition); Map> elephantLeftPosition = new HashMap<>(); elephantLeftPosition.put(Camp.HAN, List.of( - new Position(3, 1), - new Position(8, 1) + new Position(2, 0), + new Position(7, 0) )); elephantLeftPosition.put(Camp.CHO, List.of( - new Position(2, 0), - new Position(7, 0) + new Position(1, 9), + new Position(6, 9) )); position.put(PieceLocation.ELEPHANT, elephantLeftPosition); @@ -113,26 +113,26 @@ private static Map>> initOuter() { Map>> position = new HashMap<>(); Map> horseOuterPosition = new HashMap<>(); horseOuterPosition.put(Camp.HAN, List.of( - new Position(3, 1), - new Position(7, 1) + new Position(2, 0), + new Position(6, 0) )); horseOuterPosition.put(Camp.CHO, List.of( - new Position(3, 0), - new Position(7, 0) + new Position(2, 9), + new Position(6, 9) )); position.put(PieceLocation.HORSE, horseOuterPosition); Map> elephantOuterPosition = new HashMap<>(); elephantOuterPosition.put(Camp.HAN, List.of( - new Position(2, 1), - new Position(8, 1) + new Position(1, 0), + new Position(7, 0) )); elephantOuterPosition.put(Camp.CHO, List.of( - new Position(2, 0), - new Position(8, 0) + new Position(1, 9), + new Position(7, 9) )); position.put(PieceLocation.ELEPHANT, elephantOuterPosition); diff --git a/src/main/java/domain/PieceLocation.java b/src/main/java/domain/PieceLocation.java index 8f70678850..4defdfcb92 100644 --- a/src/main/java/domain/PieceLocation.java +++ b/src/main/java/domain/PieceLocation.java @@ -22,11 +22,11 @@ public enum PieceLocation { private static Map> initGeneralPosition() { Map> generalPosition = new HashMap<>(); generalPosition.put(Camp.HAN, List.of( - new Position(5, 2) + new Position(4, 1) )); generalPosition.put(Camp.CHO, List.of( - new Position(5, 9) + new Position(4, 8) )); return generalPosition; @@ -35,13 +35,13 @@ private static Map> initGeneralPosition() { private static Map> initGuardPosition() { Map> guardPosition = new HashMap<>(); guardPosition.put(Camp.HAN, List.of( - new Position(4, 1), - new Position(6, 1) + new Position(3, 0), + new Position(5, 0) )); guardPosition.put(Camp.CHO, List.of( - new Position(4, 0), - new Position(6, 0) + new Position(3, 9), + new Position(5, 9) )); return guardPosition; @@ -51,13 +51,13 @@ private static Map> initHorsePosition() { Map> horsePosition = new HashMap<>(); horsePosition.put(Camp.HAN, List.of( - new Position(3, 1), - new Position(8, 1) + new Position(2, 0), + new Position(7, 0) )); horsePosition.put(Camp.CHO, List.of( - new Position(2, 0), - new Position(8, 0) + new Position(1, 9), + new Position(7, 9) )); return horsePosition; @@ -67,12 +67,12 @@ private static Map> initCannonPosition() { Map> cannonPosition = new HashMap<>(); cannonPosition.put(Camp.HAN, List.of( - new Position(2, 3), - new Position(8, 3) + new Position(1, 2), + new Position(7, 2) )); cannonPosition.put(Camp.CHO, List.of( - new Position(2, 8), - new Position(8, 8) + new Position(1, 7), + new Position(7, 7) )); return cannonPosition; @@ -82,12 +82,12 @@ private static Map> initElephantPosition() { Map> elephantPosition = new HashMap<>(); elephantPosition.put(Camp.HAN, List.of( - new Position(2, 1), - new Position(7, 1) + new Position(1, 0), + new Position(6, 0) )); elephantPosition.put(Camp.CHO, List.of( - new Position(3, 0), - new Position(7, 0) + new Position(2, 9), + new Position(6, 9) )); return elephantPosition; @@ -97,18 +97,18 @@ private static Map> initSoldierPosition() { Map> soldierPosition = new HashMap<>(); soldierPosition.put(Camp.HAN, List.of( - new Position(1, 4), - new Position(3, 4), - new Position(5, 4), - new Position(7, 4), - new Position(9, 4) + new Position(0, 3), + new Position(2, 3), + new Position(4, 3), + new Position(6, 3), + new Position(8, 3) )); soldierPosition.put(Camp.CHO, List.of( - new Position(1, 7), - new Position(3, 7), - new Position(5, 7), - new Position(7, 7), - new Position(9, 7) + new Position(0, 6), + new Position(2, 6), + new Position(4, 6), + new Position(6, 6), + new Position(8, 6) )); return soldierPosition; @@ -118,12 +118,12 @@ private static Map> initChariotPosition() { Map> chariotPosition = new HashMap<>(); chariotPosition.put(Camp.HAN, List.of( - new Position(1, 1), - new Position(9, 1)) + new Position(0, 0), + new Position(8, 0)) ); chariotPosition.put(Camp.CHO, List.of( - new Position(1, 0), - new Position(9, 0)) + new Position(0, 9), + new Position(8, 9)) ); return chariotPosition; diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index b60ed8ce51..57159e03b6 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -14,9 +14,17 @@ public Position(int x, int y) { this.y = y; } + public int getX() { + return x; + } + + public int getY() { + return y; + } + private void validatePosX(int x) { - if (x < 1 || x > 9) { - throw new IllegalArgumentException("[ERROR] x 좌표는 1~9 사이어야합니다."); + if (x < 0 || x > 8) { + throw new IllegalArgumentException("[ERROR] x 좌표는 0~8 사이어야합니다."); } } diff --git a/src/test/java/PieceGeneratorTest.java b/src/test/java/PieceGeneratorTest.java index 970bf902dc..4719dda3c6 100644 --- a/src/test/java/PieceGeneratorTest.java +++ b/src/test/java/PieceGeneratorTest.java @@ -38,10 +38,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.HAN, ElephantFormation.RIGHT); - Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(6, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Horse.class); } @Test @@ -51,10 +51,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.HAN, ElephantFormation.LEFT); - Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(6, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Elephant.class); } @Test @@ -64,10 +64,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.HAN, ElephantFormation.INNER); - Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(6, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Horse.class); } @Test @@ -77,10 +77,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.HAN, ElephantFormation.OUTER); - Assertions.assertEquals(board.get(new Position(2, 1)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(3, 1)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(7, 1)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(8, 1)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(6, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Elephant.class); } @@ -91,10 +91,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.CHO, ElephantFormation.RIGHT); - Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(6, 9)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 9)).getClass(), Elephant.class); } @Test @@ -104,10 +104,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.CHO, ElephantFormation.LEFT); - Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(6, 9)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 9)).getClass(), Horse.class); } @Test @@ -117,10 +117,10 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.CHO, ElephantFormation.INNER); - Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(6, 9)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(7, 9)).getClass(), Horse.class); } @Test @@ -130,9 +130,9 @@ public class PieceGeneratorTest { Map board = pieceGenerator.generatePieces(Camp.CHO, ElephantFormation.OUTER); - Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); - Assertions.assertEquals(board.get(new Position(3, 0)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(7, 0)).getClass(), Horse.class); - Assertions.assertEquals(board.get(new Position(8, 0)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Elephant.class); + Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(6, 9)).getClass(), Horse.class); + Assertions.assertEquals(board.get(new Position(7, 9)).getClass(), Elephant.class); } } diff --git a/src/test/java/domain/PositionTest.java b/src/test/java/domain/PositionTest.java index 5c281f92a9..6fa1492629 100644 --- a/src/test/java/domain/PositionTest.java +++ b/src/test/java/domain/PositionTest.java @@ -11,18 +11,18 @@ class PositionTest { @ParameterizedTest @CsvSource({ - "1, 0", - "1, 9", - "9, 0", - "9, 9", - "3, 4" + "0, 9", + "0, 8", + "8, 9", + "8, 8", + "2, 3" }) void 정상_생성_테스트(int x, int y) { Assertions.assertThat(new Position(x, y)).isInstanceOf(Position.class); } @ParameterizedTest - @ValueSource(ints = {-1, 0, 10, 12}) + @ValueSource(ints = {-1, 9, 12}) void X_예외_값_입력_오류_검증(int x) { assertThatThrownBy(() -> new Position(x, 4)) .isInstanceOf(IllegalArgumentException.class) From 627b90615b66335a214d155ea1e478a65a31bf6f Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Sun, 29 Mar 2026 19:49:13 +0900 Subject: [PATCH 16/40] =?UTF-8?q?test:=20=EA=B8=B0=EB=AC=BC=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/domain/pieces/CannonTest.java | 96 ++++++++++++++++ src/test/java/domain/pieces/ChariotTest.java | 30 +++++ src/test/java/domain/pieces/ElephantTest.java | 61 ++++++++++ src/test/java/domain/pieces/GeneralTest.java | 61 ++++++++++ src/test/java/domain/pieces/GuardTest.java | 61 ++++++++++ src/test/java/domain/pieces/HorseTest.java | 61 ++++++++++ src/test/java/domain/pieces/SoldierTest.java | 105 ++++++++++++++++++ 7 files changed, 475 insertions(+) create mode 100644 src/test/java/domain/pieces/CannonTest.java create mode 100644 src/test/java/domain/pieces/ChariotTest.java create mode 100644 src/test/java/domain/pieces/ElephantTest.java create mode 100644 src/test/java/domain/pieces/GeneralTest.java create mode 100644 src/test/java/domain/pieces/GuardTest.java create mode 100644 src/test/java/domain/pieces/HorseTest.java create mode 100644 src/test/java/domain/pieces/SoldierTest.java diff --git a/src/test/java/domain/pieces/CannonTest.java b/src/test/java/domain/pieces/CannonTest.java new file mode 100644 index 0000000000..2b7b753ee1 --- /dev/null +++ b/src/test/java/domain/pieces/CannonTest.java @@ -0,0 +1,96 @@ +package domain.pieces; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class CannonTest { + + @Test + void 다른_기물을_넘고_이동_가능() { + Board board = new Board(); + Cannon cannon = new Cannon(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + + Position fromPosition = new Position(3, 5); + Position anotherPiecePosition = new Position(5, 5); + + board.locatePiece(fromPosition, cannon); + board.locatePiece(anotherPiecePosition, piece); + + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(3, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(4, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(5, 5), board)); + Assertions.assertTrue(cannon.canMove(fromPosition, new Position(6, 5), board)); + Assertions.assertTrue(cannon.canMove(fromPosition, new Position(7, 5), board)); + Assertions.assertTrue(cannon.canMove(fromPosition, new Position(8, 5), board)); + } + + @Test + void 포에_막혀_이동_불가() { + Board board = new Board(); + Cannon cannon = new Cannon(Camp.HAN); + Cannon cannonForBlock = new Cannon(Camp.HAN); + + Position fromPosition = new Position(3, 5); + Position anotherPiecePosition = new Position(5, 5); + + board.locatePiece(fromPosition, cannon); + board.locatePiece(anotherPiecePosition, cannonForBlock); + + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(3, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(4, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(5, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(6, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(7, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(8, 5), board)); + } + + @Test + void 기물을_넘고_다른_기물을_만나기_전까지_이동_가능() { + Board board = new Board(); + Cannon cannon = new Cannon(Camp.HAN); + Piece pieceA = new Piece(Camp.HAN); + Piece pieceB = new Piece(Camp.HAN); + + Position fromPosition = new Position(3, 5); + Position anotherPieceAPosition = new Position(5, 5); + Position anotherPieceBPosition = new Position(7, 5); + + board.locatePiece(fromPosition, cannon); + board.locatePiece(anotherPieceAPosition, pieceA); + board.locatePiece(anotherPieceBPosition, pieceB); + + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(3, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(4, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(5, 5), board)); + Assertions.assertTrue(cannon.canMove(fromPosition, new Position(6, 5), board)); + Assertions.assertTrue(cannon.canMove(fromPosition, new Position(7, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(8, 5), board)); + } + + @Test + void 기물을_넘고_다른_기물을_만나기_전까지_이동_가능_포는_못잡음() { + Board board = new Board(); + Cannon cannon = new Cannon(Camp.HAN); + Piece pieceA = new Piece(Camp.CHO); + Cannon pieceB = new Cannon(Camp.CHO); + + Position fromPosition = new Position(3, 5); + Position anotherPieceAPosition = new Position(5, 5); + Position anotherPieceBPosition = new Position(7, 5); + + board.locatePiece(fromPosition, cannon); + board.locatePiece(anotherPieceAPosition, pieceA); + board.locatePiece(anotherPieceBPosition, pieceB); + + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(3, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(4, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(5, 5), board)); + Assertions.assertTrue(cannon.canMove(fromPosition, new Position(6, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(7, 5), board)); + Assertions.assertFalse(cannon.canMove(fromPosition, new Position(8, 5), board)); + } +} diff --git a/src/test/java/domain/pieces/ChariotTest.java b/src/test/java/domain/pieces/ChariotTest.java new file mode 100644 index 0000000000..4f08b0ed8d --- /dev/null +++ b/src/test/java/domain/pieces/ChariotTest.java @@ -0,0 +1,30 @@ +package domain.pieces; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ChariotTest { + + @Test + void 다른_기물_뒤로는_이동할_수_없다() { + Board board = new Board(); + Chariot chariot = new Chariot(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + + Position fromPosition = new Position(3, 5); + Position anotherPiecePosition = new Position(6, 5); + + board.locatePiece(fromPosition, chariot); + board.locatePiece(anotherPiecePosition, piece); + + Assertions.assertFalse(chariot.canMove(fromPosition, new Position(3, 5), board)); + Assertions.assertTrue(chariot.canMove(fromPosition, new Position(4, 5), board)); + Assertions.assertTrue(chariot.canMove(fromPosition, new Position(5, 5), board)); + Assertions.assertTrue(chariot.canMove(fromPosition, new Position(6, 5), board)); + Assertions.assertFalse(chariot.canMove(fromPosition, new Position(7, 5), board)); + Assertions.assertFalse(chariot.canMove(fromPosition, new Position(8, 5), board)); + } +} diff --git a/src/test/java/domain/pieces/ElephantTest.java b/src/test/java/domain/pieces/ElephantTest.java new file mode 100644 index 0000000000..5351afb2de --- /dev/null +++ b/src/test/java/domain/pieces/ElephantTest.java @@ -0,0 +1,61 @@ +package domain.pieces; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ElephantTest { + + @Test + void 위로_오른대각선_이동_가능() { + Board board = new Board(); + Elephant elephant = new Elephant(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(4, 6); + + Assertions.assertTrue(elephant.canMove(fromPosition, toPosition, board)); + } + + @Test + void 위로_오른대각선_이동() { + Board board = new Board(); + Elephant elephant = new Elephant(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(4, 6); + + board.locatePiece(fromPosition, elephant); + board.move(fromPosition, toPosition); + + Assertions.assertFalse(board.isExist(fromPosition)); + Assertions.assertEquals(board.getPieceFrom(toPosition), elephant); + } + + @Test + void 위로_오른대각선_경로_막힘() { + Board board = new Board(); + Elephant elephant = new Elephant(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(4, 6); + + board.locatePiece(fromPosition, elephant); + board.locatePiece(new Position(2, 8), piece); + + assertThatThrownBy(() -> board.move(fromPosition, toPosition)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("[ERROR]", "이동할"); + } + + @Test + void 이동_불가_좌표_이동_불가() { + Board board = new Board(); + Elephant elephant = new Elephant(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(0, 0); + + Assertions.assertFalse(elephant.canMove(fromPosition, toPosition, board)); + } +} diff --git a/src/test/java/domain/pieces/GeneralTest.java b/src/test/java/domain/pieces/GeneralTest.java new file mode 100644 index 0000000000..916b733cf4 --- /dev/null +++ b/src/test/java/domain/pieces/GeneralTest.java @@ -0,0 +1,61 @@ +package domain.pieces; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class GeneralTest { + + @Test + void 아래로_오른대각선_이동_가능() { + Board board = new Board(); + General general = new General(Camp.HAN); + Position fromPosition = new Position(4, 1); + Position toPosition = new Position(5, 2); + + Assertions.assertTrue(general.canMove(fromPosition, toPosition, board)); + } + + @Test + void 아래로_오른대각선_이동() { + Board board = new Board(); + General general = new General(Camp.HAN); + Position fromPosition = new Position(4, 1); + Position toPosition = new Position(5, 2); + + board.locatePiece(fromPosition, general); + board.move(fromPosition, toPosition); + + Assertions.assertFalse(board.isExist(fromPosition)); + Assertions.assertEquals(board.getPieceFrom(toPosition), general); + } + + @Test + void 아래로_오른대각선_경로_막힘() { + Board board = new Board(); + General general = new General(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + Position fromPosition = new Position(4, 1); + Position toPosition = new Position(5, 2); + + board.locatePiece(fromPosition, general); + board.locatePiece(toPosition, piece); + + assertThatThrownBy(() -> board.move(fromPosition, toPosition)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("[ERROR]", "이동할"); + } + + @Test + void 이동_불가_좌표_이동_불가() { + Board board = new Board(); + General general = new General(Camp.HAN); + Position fromPosition = new Position(3, 0); + Position toPosition = new Position(0, 0); + + Assertions.assertFalse(general.canMove(fromPosition, toPosition, board)); + } +} diff --git a/src/test/java/domain/pieces/GuardTest.java b/src/test/java/domain/pieces/GuardTest.java new file mode 100644 index 0000000000..e3f1a499d9 --- /dev/null +++ b/src/test/java/domain/pieces/GuardTest.java @@ -0,0 +1,61 @@ +package domain.pieces; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class GuardTest { + + @Test + void 아래로_오른대각선_이동_가능() { + Board board = new Board(); + Guard guard = new Guard(Camp.HAN); + Position fromPosition = new Position(3, 0); + Position toPosition = new Position(4, 1); + + Assertions.assertTrue(guard.canMove(fromPosition, toPosition, board)); + } + + @Test + void 아래로_오른대각선_이동() { + Board board = new Board(); + Guard guard = new Guard(Camp.HAN); + Position fromPosition = new Position(3, 0); + Position toPosition = new Position(4, 1); + + board.locatePiece(fromPosition, guard); + board.move(fromPosition, toPosition); + + Assertions.assertFalse(board.isExist(fromPosition)); + Assertions.assertEquals(board.getPieceFrom(toPosition), guard); + } + + @Test + void 아래로_오른대각선_경로_막힘() { + Board board = new Board(); + Guard guard = new Guard(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + Position fromPosition = new Position(3, 0); + Position toPosition = new Position(4, 1); + + board.locatePiece(fromPosition, guard); + board.locatePiece(toPosition, piece); + + assertThatThrownBy(() -> board.move(fromPosition, toPosition)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("[ERROR]", "이동할"); + } + + @Test + void 이동_불가_좌표_이동_불가() { + Board board = new Board(); + Guard guard = new Guard(Camp.HAN); + Position fromPosition = new Position(3, 0); + Position toPosition = new Position(0, 0); + + Assertions.assertFalse(guard.canMove(fromPosition, toPosition, board)); + } +} diff --git a/src/test/java/domain/pieces/HorseTest.java b/src/test/java/domain/pieces/HorseTest.java new file mode 100644 index 0000000000..e253c223f3 --- /dev/null +++ b/src/test/java/domain/pieces/HorseTest.java @@ -0,0 +1,61 @@ +package domain.pieces; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class HorseTest { + + @Test + void 위로_오른대각선_이동_가능() { + Board board = new Board(); + Horse horse = new Horse(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(3, 7); + + Assertions.assertTrue(horse.canMove(fromPosition, toPosition, board)); + } + + @Test + void 위로_오른대각선_이동() { + Board board = new Board(); + Horse horse = new Horse(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(3, 7); + + board.locatePiece(fromPosition, horse); + board.move(fromPosition, toPosition); + + Assertions.assertFalse(board.isExist(fromPosition)); + Assertions.assertEquals(board.getPieceFrom(toPosition), horse); + } + + @Test + void 위로_오른대각선_경로_막힘() { + Board board = new Board(); + Horse horse = new Horse(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(3, 7); + + board.locatePiece(fromPosition, horse); + board.locatePiece(new Position(2, 8), piece); + + assertThatThrownBy(() -> board.move(fromPosition, toPosition)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("[ERROR]", "이동할"); + } + + @Test + void 이동_불가_좌표_이동_불가() { + Board board = new Board(); + Horse horse = new Horse(Camp.HAN); + Position fromPosition = new Position(2, 9); + Position toPosition = new Position(0, 0); + + Assertions.assertFalse(horse.canMove(fromPosition, toPosition, board)); + } +} diff --git a/src/test/java/domain/pieces/SoldierTest.java b/src/test/java/domain/pieces/SoldierTest.java new file mode 100644 index 0000000000..af4724b874 --- /dev/null +++ b/src/test/java/domain/pieces/SoldierTest.java @@ -0,0 +1,105 @@ +package domain.pieces; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import domain.Board; +import domain.Camp; +import domain.Position; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SoldierTest { + + @Test + void 한나라_기준_앞으로_한_칸_전진_가능() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.HAN); + Position fromPosition = new Position(0, 3); + Position toPosition = new Position(0, 4); + + Assertions.assertTrue(soldier.canMove(fromPosition, toPosition, board)); + } + + @Test + void 한나라_기준_왼쪽으로_한_칸_전진_가능() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.HAN); + Position fromPosition = new Position(0, 3); + Position toPosition = new Position(1, 3); + + Assertions.assertTrue(soldier.canMove(fromPosition, toPosition, board)); + } + + @Test + void 한나라_기준_뒤로_한_칸_후진_불가() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.HAN); + Position fromPosition = new Position(0, 3); + Position toPosition = new Position(0, 2); + + Assertions.assertFalse(soldier.canMove(fromPosition, toPosition, board)); + } + + @Test + void 같은_팀_기물_막힘으로_앞으로_한_칸_전진_불가() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.HAN); + Piece piece = new Piece(Camp.HAN); + + Position fromPosition = new Position(0, 3); + Position toPosition = new Position(0, 4); + + board.locatePiece(fromPosition, soldier); + board.locatePiece(toPosition, piece); + + assertThatThrownBy(() -> board.move(fromPosition, toPosition)).isInstanceOf( + IllegalArgumentException.class).hasMessageContaining("[ERROR]", "같은 팀"); + } + + @Test + void 상대_팀_기물_잡고_앞으로_한_칸_전진_가능() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.HAN); + Piece piece = new Piece(Camp.CHO); + + Position fromPosition = new Position(0, 3); + Position toPosition = new Position(0, 4); + + board.locatePiece(fromPosition, soldier); + board.locatePiece(toPosition, piece); + + board.move(fromPosition, toPosition); + + Assertions.assertEquals(board.getPieceFrom(toPosition), soldier); + } + + @Test + void 초나라_기준_앞으로_한_칸_전진_가능() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.CHO); + Position fromPosition = new Position(0, 6); + Position toPosition = new Position(0, 5); + + Assertions.assertTrue(soldier.canMove(fromPosition, toPosition, board)); + } + + @Test + void 초나라_기준_오른쪽으로_한_칸_전진_가능() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.CHO); + Position fromPosition = new Position(0, 6); + Position toPosition = new Position(1, 6); + + Assertions.assertTrue(soldier.canMove(fromPosition, toPosition, board)); + } + + @Test + void 초나라_기준_뒤로_한_칸_후진_불가() { + Board board = new Board(); + Soldier soldier = new Soldier(Camp.CHO); + Position fromPosition = new Position(0, 6); + Position toPosition = new Position(0, 7); + + Assertions.assertFalse(soldier.canMove(fromPosition, toPosition, board)); + } +} From 79e6716b649c6a9b24dbf8d0287119ee1fb82f4a Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Sun, 29 Mar 2026 19:50:26 +0900 Subject: [PATCH 17/40] =?UTF-8?q?feat:=20=EA=B8=B0=EB=AC=BC=EB=B3=84=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=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/domain/Board.java | 26 ++- src/main/java/domain/ExistBoard.java | 10 ++ src/main/java/domain/pieces/Cannon.java | 128 +++++++++++++++ src/main/java/domain/pieces/Chariot.java | 70 ++++++++ src/main/java/domain/pieces/Elephant.java | 191 ++++++++++++++++++++++ src/main/java/domain/pieces/General.java | 85 ++++++++++ src/main/java/domain/pieces/Guard.java | 85 ++++++++++ src/main/java/domain/pieces/Horse.java | 162 ++++++++++++++++++ src/main/java/domain/pieces/Piece.java | 62 +++++++ src/main/java/domain/pieces/Soldier.java | 55 +++++++ src/test/java/BoardTest.java | 8 +- 11 files changed, 875 insertions(+), 7 deletions(-) create mode 100644 src/main/java/domain/ExistBoard.java diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java index 9c915c5634..57317addc7 100644 --- a/src/main/java/domain/Board.java +++ b/src/main/java/domain/Board.java @@ -4,7 +4,7 @@ import java.util.HashMap; import java.util.Map; -public class Board { +public class Board implements ExistBoard { private final Map board = new HashMap<>(); @@ -25,13 +25,33 @@ public Piece getPieceFrom(Position position) { return board.get(position); } + @Override public boolean isExist(Position position) { return board.containsKey(position); } public void move(Position fromPosition, Position toPosition) { + if (fromPosition.equals(toPosition)) { + throw new IllegalArgumentException("[ERROR] 제자리 이동은 불가능합니다."); + } + Piece piece = board.get(fromPosition); - board.remove(fromPosition); - locatePiece(toPosition, piece); + boolean canMove = piece.canMove(fromPosition, toPosition, this); + if (canMove) { + locatePiece(toPosition, piece); + board.remove(fromPosition); + return; + } + + throw new IllegalArgumentException("[ERROR] 이동할 수 없습니다"); + } + + @Override + public boolean isDifferentPieceType(Position position, Piece piece) { + if (!board.containsKey(position)) { + return true; + } + + return board.get(position).isDifferentPieceType(piece); } } diff --git a/src/main/java/domain/ExistBoard.java b/src/main/java/domain/ExistBoard.java new file mode 100644 index 0000000000..b2bb3f8d01 --- /dev/null +++ b/src/main/java/domain/ExistBoard.java @@ -0,0 +1,10 @@ +package domain; + +import domain.pieces.Piece; + +public interface ExistBoard { + + boolean isExist(Position position); + + boolean isDifferentPieceType(Position position, Piece piece); +} diff --git a/src/main/java/domain/pieces/Cannon.java b/src/main/java/domain/pieces/Cannon.java index 90aa03d6fe..f8de0282d5 100644 --- a/src/main/java/domain/pieces/Cannon.java +++ b/src/main/java/domain/pieces/Cannon.java @@ -1,10 +1,138 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.HashSet; +import java.util.Set; public class Cannon extends Piece { public Cannon(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + + movablePositions.addAll(moveUp(from, existBoard)); + movablePositions.addAll(moveLeft(from, existBoard)); + movablePositions.addAll(moveRight(from, existBoard)); + movablePositions.addAll(moveDown(from, existBoard)); + + return movablePositions.contains(to); + } + + private Set moveRight(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + boolean jumping = false; + + try { + while (!jumping) { + position = right(position); + jumping = checkCannonJumping(position, existBoard); + } + } catch (IllegalArgumentException e) { + + } + + try { + do { + position = right(position); + if (existBoard.isDifferentPieceType(position, this)) { + movablePositions.add(position); + } + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + + return movablePositions; + } + + private Set moveLeft(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + boolean jumping = false; + + try { + while (!jumping) { + position = left(position); + jumping = checkCannonJumping(position, existBoard); + } + } catch (IllegalArgumentException e) { + + } + + try { + do { + position = left(position); + if (existBoard.isDifferentPieceType(position, this)) { + movablePositions.add(position); + } + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + + return movablePositions; + } + + private Set moveUp(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + boolean jumping = false; + + try { + while (!jumping) { + position = up(position); + jumping = checkCannonJumping(position, existBoard); + } + } catch (IllegalArgumentException e) { + + } + + try { + do { + position = up(position); + if (existBoard.isDifferentPieceType(position, this)) { + movablePositions.add(position); + } + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + + return movablePositions; + } + + private Set moveDown(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + boolean jumping = false; + + try { + while (!jumping) { + position = down(position); + jumping = checkCannonJumping(position, existBoard); + } + } catch (IllegalArgumentException e) { + + } + + try { + do { + position = down(position); + if (existBoard.isDifferentPieceType(position, this)) { + movablePositions.add(position); + } + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + + return movablePositions; + } + + private boolean checkCannonJumping(Position position, ExistBoard existBoard) { + return existBoard.isExist(position) && existBoard.isDifferentPieceType(position, this); + } } diff --git a/src/main/java/domain/pieces/Chariot.java b/src/main/java/domain/pieces/Chariot.java index b302d560c8..e0a7c20db6 100644 --- a/src/main/java/domain/pieces/Chariot.java +++ b/src/main/java/domain/pieces/Chariot.java @@ -1,10 +1,80 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.HashSet; +import java.util.Set; public class Chariot extends Piece { public Chariot(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + + movablePositions.addAll(moveUp(from, existBoard)); + movablePositions.addAll(moveDown(from, existBoard)); + movablePositions.addAll(moveLeft(from, existBoard)); + movablePositions.addAll(moveRight(from, existBoard)); + + return movablePositions.contains(to); + } + + private Set moveUp(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + try { + do { + position = up(position); + movablePositions.add(position); + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + return movablePositions; + } + + private Set moveLeft(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + try { + do { + position = left(position); + movablePositions.add(position); + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + return movablePositions; + } + + private Set moveRight(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + try { + do { + position = right(position); + movablePositions.add(position); + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + return movablePositions; + } + + private Set moveDown(Position position, ExistBoard existBoard) { + Set movablePositions = new HashSet<>(); + try { + do { + position = down(position); + movablePositions.add(position); + } while (!existBoard.isExist(position)); + } catch (IllegalArgumentException e) { + + } + return movablePositions; + } + + } diff --git a/src/main/java/domain/pieces/Elephant.java b/src/main/java/domain/pieces/Elephant.java index dbd453fbd9..f534b53b7d 100644 --- a/src/main/java/domain/pieces/Elephant.java +++ b/src/main/java/domain/pieces/Elephant.java @@ -1,10 +1,201 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class Elephant extends Piece { public Elephant(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + Map> routeOfDestination = new HashMap<>(); + + routeOfDestination.putAll(move_U_RU(from)); + routeOfDestination.putAll(move_U_LU(from)); + routeOfDestination.putAll(move_D_RD(from)); + routeOfDestination.putAll(move_D_LD(from)); + routeOfDestination.putAll(move_R_RU(from)); + routeOfDestination.putAll(move_R_RD(from)); + routeOfDestination.putAll(move_L_LU(from)); + routeOfDestination.putAll(move_L_LD(from)); + + if (!routeOfDestination.containsKey(to)) { + return false; + } + + List route = routeOfDestination.get(to); + for (Position position : route) { + if (existBoard.isExist(position)) { + return false; + } + } + + return true; + } + + private Map> move_U_RU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = up(position); + route.add(position); + + position = rightUpDiagonal(position); + route.add(position); + + position = rightUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_U_LU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = up(position); + route.add(position); + + position = leftUpDiagonal(position); + route.add(position); + + position = leftUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } + + private Map> move_D_RD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = down(position); + route.add(position); + + position = rightDownDiagonal(position); + route.add(position); + + position = rightDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_D_LD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = down(position); + route.add(position); + + position = leftDownDiagonal(position); + route.add(position); + + position = leftDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } + + private Map> move_R_RU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = right(position); + route.add(position); + + position = rightUpDiagonal(position); + route.add(position); + + position = rightUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } + + private Map> move_R_RD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = right(position); + route.add(position); + + position = rightDownDiagonal(position); + route.add(position); + + position = rightDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } + + private Map> move_L_LU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = left(position); + route.add(position); + + position = leftUpDiagonal(position); + route.add(position); + + position = leftUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } + + private Map> move_L_LD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = left(position); + route.add(position); + + position = leftDownDiagonal(position); + route.add(position); + + position = leftDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } } diff --git a/src/main/java/domain/pieces/General.java b/src/main/java/domain/pieces/General.java index 52ffb34816..d73e935647 100644 --- a/src/main/java/domain/pieces/General.java +++ b/src/main/java/domain/pieces/General.java @@ -1,10 +1,95 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.HashSet; +import java.util.Set; public class General extends Piece { public General(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + + Set destination = new HashSet<>(); + + destination.add(move_L(from)); + destination.add(move_R(from)); + destination.add(move_D(from)); + destination.add(move_U(from)); + destination.add(move_RU(from)); + destination.add(move_RD(from)); + destination.add(move_LU(from)); + destination.add(move_LD(from)); + + return destination.contains(to); + } + + private Position move_U(Position position) { + try { + return up(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_L(Position position) { + try { + return left(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_R(Position position) { + try { + return right(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_D(Position position) { + try { + return down(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_RU(Position position) { + try { + return rightUpDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_RD(Position position) { + try { + return rightDownDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_LU(Position position) { + try { + return leftUpDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_LD(Position position) { + try { + return leftDownDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } } diff --git a/src/main/java/domain/pieces/Guard.java b/src/main/java/domain/pieces/Guard.java index cc2df4b71e..c7305060f1 100644 --- a/src/main/java/domain/pieces/Guard.java +++ b/src/main/java/domain/pieces/Guard.java @@ -1,10 +1,95 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.HashSet; +import java.util.Set; public class Guard extends Piece { public Guard(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + + Set destination = new HashSet<>(); + + destination.add(move_L(from)); + destination.add(move_R(from)); + destination.add(move_D(from)); + destination.add(move_U(from)); + destination.add(move_RU(from)); + destination.add(move_RD(from)); + destination.add(move_LU(from)); + destination.add(move_LD(from)); + + return destination.contains(to); + } + + private Position move_U(Position position) { + try { + return up(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_L(Position position) { + try { + return left(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_R(Position position) { + try { + return right(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_D(Position position) { + try { + return down(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_RU(Position position) { + try { + return rightUpDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_RD(Position position) { + try { + return rightDownDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_LU(Position position) { + try { + return leftUpDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_LD(Position position) { + try { + return leftDownDiagonal(position); + } catch (IllegalArgumentException e) { + return position; + } + } } diff --git a/src/main/java/domain/pieces/Horse.java b/src/main/java/domain/pieces/Horse.java index 309315c553..43ad78b729 100644 --- a/src/main/java/domain/pieces/Horse.java +++ b/src/main/java/domain/pieces/Horse.java @@ -1,10 +1,172 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public class Horse extends Piece { public Horse(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + Map> routeOfDestination = new HashMap<>(); + + routeOfDestination.putAll(move_U_RU(from)); + routeOfDestination.putAll(move_U_LU(from)); + routeOfDestination.putAll(move_R_RU(from)); + routeOfDestination.putAll(move_R_RD(from)); + routeOfDestination.putAll(move_L_LU(from)); + routeOfDestination.putAll(move_L_LD(from)); + routeOfDestination.putAll(move_D_RD(from)); + routeOfDestination.putAll(move_D_LD(from)); + + if (!routeOfDestination.containsKey(to)) { + return false; + } + + List route = routeOfDestination.get(to); + for (Position position : route) { + if (existBoard.isExist(position)) { + return false; + } + } + + return true; + } + + private Map> move_U_RU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = up(position); + route.add(position); + + position = rightUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + + return routeOfDestination; + } + + private Map> move_U_LU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = up(position); + route.add(position); + + position = leftUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_R_RU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = right(position); + route.add(position); + + position = rightUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_R_RD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = right(position); + route.add(position); + + position = rightDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_L_LU(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = left(position); + route.add(position); + + position = leftUpDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_L_LD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = left(position); + route.add(position); + + position = leftDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_D_RD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = down(position); + route.add(position); + + position = rightDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } + + private Map> move_D_LD(Position position) { + Map> routeOfDestination = new HashMap<>(); + List route = new ArrayList<>(); + try { + position = down(position); + route.add(position); + + position = leftDownDiagonal(position); + + routeOfDestination.put(position, route); + } catch (IllegalArgumentException e) { + // 생성할 수 없는 Position이면 무시 + } + return routeOfDestination; + } } diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index fe7eb6181d..8a9c66258a 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -1,6 +1,8 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; public class Piece { @@ -13,4 +15,64 @@ public Piece(Camp camp) { public boolean isSameCamp(Piece comparedPiece) { return this.camp == comparedPiece.camp; } + + public boolean isSameCamp(Camp camp) { + return this.camp == camp; + } + + public boolean isDifferentPieceType(Piece piece) { + return this.getClass() != piece.getClass(); + } + + Position up(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(x, --y); + } + + Position down(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(x, ++y); + } + + Position left(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(--x, y); + } + + Position right(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(++x, y); + } + + Position leftUpDiagonal(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(--x, --y); + } + + Position rightUpDiagonal(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(++x, --y); + } + + Position leftDownDiagonal(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(--x, ++y); + } + + Position rightDownDiagonal(Position position) { + int x = position.getX(); + int y = position.getY(); + return new Position(++x, ++y); + } + + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + return true; + } } diff --git a/src/main/java/domain/pieces/Soldier.java b/src/main/java/domain/pieces/Soldier.java index 18494450a7..2c9120b34b 100644 --- a/src/main/java/domain/pieces/Soldier.java +++ b/src/main/java/domain/pieces/Soldier.java @@ -1,10 +1,65 @@ package domain.pieces; import domain.Camp; +import domain.ExistBoard; +import domain.Position; +import java.util.HashSet; +import java.util.Set; public class Soldier extends Piece { public Soldier(Camp camp) { super(camp); } + + @Override + public boolean canMove(Position from, Position to, ExistBoard existBoard) { + + Set destination = new HashSet<>(); + + destination.add(move_L(from)); + destination.add(move_R(from)); + + if (this.isSameCamp(Camp.HAN)) { + destination.add(move_D(from)); + } + + if (this.isSameCamp(Camp.CHO)) { + destination.add(move_U(from)); + } + + return destination.contains(to); + } + + private Position move_U(Position position) { + try { + return up(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_L(Position position) { + try { + return left(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_R(Position position) { + try { + return right(position); + } catch (IllegalArgumentException e) { + return position; + } + } + + private Position move_D(Position position) { + try { + return down(position); + } catch (IllegalArgumentException e) { + return position; + } + } } diff --git a/src/test/java/BoardTest.java b/src/test/java/BoardTest.java index d67d802159..62c4aba964 100644 --- a/src/test/java/BoardTest.java +++ b/src/test/java/BoardTest.java @@ -12,7 +12,7 @@ public class BoardTest { @Test void 특정_위치에_기물을_놓을_수_있다() { Board board = new Board(); - Position position = new Position(2, 3); + Position position = new Position(1, 2); Piece piece = new Piece(Camp.HAN); board.locatePiece(position, piece); @@ -22,7 +22,7 @@ public class BoardTest { @Test void 같은_팀_기물은_잡을_수_없다() { Board board = new Board(); - Position position = new Position(2, 3); + Position position = new Position(1, 2); Piece locatedPiece = new Piece(Camp.HAN); Piece anotherPiece = new Piece(Camp.HAN); board.locatePiece(position, locatedPiece); @@ -34,8 +34,8 @@ public class BoardTest { @Test void 기물을_이동시킬_수_있다() { Board board = new Board(); - Position fromPosition = new Position(2,3); - Position toPosition = new Position(2,4); + Position fromPosition = new Position(1, 2); + Position toPosition = new Position(1, 3); Piece piece = new Piece(Camp.HAN); board.locatePiece(fromPosition, piece); //초기 배치 From e3b8c0515ead6b718dea8b614b46c697cdf32b2d Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Sun, 29 Mar 2026 19:53:13 +0900 Subject: [PATCH 18/40] =?UTF-8?q?docs:=20README=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index b1b170c4fa..4dfe02c3f2 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ - [x] 기물은 자동으로 배치된다. - [ ] 현재 장기판의 현황을 볼 수 있다. - [ ] 초나라(선)/한나라(후) 번갈아가며 플레이한다. -- [ ] 플레이어는 기물의 이동 규칙에 따라 이동시킬 수 있다. -- [ ] 상대 플레이어의 기물을 잡을 수 있다. +- [x] 플레이어는 기물의 이동 규칙에 따라 이동시킬 수 있다. +- [x] 상대 플레이어의 기물을 잡을 수 있다. - [ ] 상대 플레이어의 왕을 잡으면 승리하고, 게임은 종료된다. ### **실행 예시** @@ -51,17 +51,17 @@ 좌표: 1, 8 이동되었습니다. - 1 2 3 4 5 6 7 8 9 - 1 車 馬 象 士 · 士 馬 象 車 - 2 · · · · 漢 · · · · - 3 · 砲 · · · · · 砲 · - 4 兵 · 兵 · 兵 · 兵 · 兵 + 0 1 2 3 4 5 6 7 8 + 0 車 馬 象 士 · 士 馬 象 車 + 1 · · · · 漢 · · · · + 2 · 砲 · · · · · 砲 · + 3 兵 · 兵 · 兵 · 兵 · 兵 + 4 · · · · · · · · · 5 · · · · · · · · · - 6 · · · · · · · · · - 7 卒 · 卒 · 卒 · 卒 · 卒 - 8 車 炮 · · · · · 炮 · - 9 · · · · 楚 · · · · - 0 · 馬 相 士 · 士 相 馬 車 + 6 卒 · 卒 · 卒 · 卒 · 卒 + 7 車 炮 · · · · · 炮 · + 8 · · · · 楚 · · · · + 9 · 馬 相 士 · 士 相 馬 車 ``` **입력** From abe756a6d8ec8f9c1792fe0a27922fbdcb560773 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:04:34 +0900 Subject: [PATCH 19/40] =?UTF-8?q?feat:=20=EA=B0=81=20=EA=B8=B0=EB=AC=BC=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EC=97=90=20=EA=B8=B0=EB=AC=BC=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EA=B5=AC=EB=B6=84=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20PieceType=20=EC=9D=B8=EC=8A=A4=ED=84=B4=EC=8A=A4=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/PieceType.java | 12 ++++++++++++ src/main/java/domain/pieces/Cannon.java | 8 ++++++++ src/main/java/domain/pieces/Chariot.java | 8 +++++++- src/main/java/domain/pieces/Elephant.java | 8 ++++++++ src/main/java/domain/pieces/General.java | 8 ++++++++ src/main/java/domain/pieces/Guard.java | 8 ++++++++ src/main/java/domain/pieces/Horse.java | 8 ++++++++ src/main/java/domain/pieces/Piece.java | 10 ++++++++++ 8 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/main/java/domain/PieceType.java diff --git a/src/main/java/domain/PieceType.java b/src/main/java/domain/PieceType.java new file mode 100644 index 0000000000..ac82b86860 --- /dev/null +++ b/src/main/java/domain/PieceType.java @@ -0,0 +1,12 @@ +package domain; + +public enum PieceType { + GENERAL, + GUARD, + HORSE, + CANNON, + ELEPHANT, + SOLDIER, + CHARIOT, + NONE +} diff --git a/src/main/java/domain/pieces/Cannon.java b/src/main/java/domain/pieces/Cannon.java index f8de0282d5..626638d5f7 100644 --- a/src/main/java/domain/pieces/Cannon.java +++ b/src/main/java/domain/pieces/Cannon.java @@ -2,12 +2,15 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.HashSet; import java.util.Set; public class Cannon extends Piece { + private final PieceType pieceType = PieceType.CANNON; + public Cannon(Camp camp) { super(camp); } @@ -135,4 +138,9 @@ private Set moveDown(Position position, ExistBoard existBoard) { private boolean checkCannonJumping(Position position, ExistBoard existBoard) { return existBoard.isExist(position) && existBoard.isDifferentPieceType(position, this); } + + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/domain/pieces/Chariot.java b/src/main/java/domain/pieces/Chariot.java index e0a7c20db6..79d92ef633 100644 --- a/src/main/java/domain/pieces/Chariot.java +++ b/src/main/java/domain/pieces/Chariot.java @@ -2,12 +2,15 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.HashSet; import java.util.Set; public class Chariot extends Piece { + private final PieceType pieceType = PieceType.CHARIOT; + public Chariot(Camp camp) { super(camp); } @@ -76,5 +79,8 @@ private Set moveDown(Position position, ExistBoard existBoard) { return movablePositions; } - + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/domain/pieces/Elephant.java b/src/main/java/domain/pieces/Elephant.java index f534b53b7d..030cd2777f 100644 --- a/src/main/java/domain/pieces/Elephant.java +++ b/src/main/java/domain/pieces/Elephant.java @@ -2,6 +2,7 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.ArrayList; import java.util.HashMap; @@ -10,6 +11,8 @@ public class Elephant extends Piece { + private final PieceType pieceType = PieceType.ELEPHANT; + public Elephant(Camp camp) { super(camp); } @@ -198,4 +201,9 @@ private Map> move_L_LD(Position position) { return routeOfDestination; } + + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/domain/pieces/General.java b/src/main/java/domain/pieces/General.java index d73e935647..e7281fa6e6 100644 --- a/src/main/java/domain/pieces/General.java +++ b/src/main/java/domain/pieces/General.java @@ -2,12 +2,15 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.HashSet; import java.util.Set; public class General extends Piece { + private final PieceType pieceType = PieceType.GENERAL; + public General(Camp camp) { super(camp); } @@ -92,4 +95,9 @@ private Position move_LD(Position position) { return position; } } + + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/domain/pieces/Guard.java b/src/main/java/domain/pieces/Guard.java index c7305060f1..5e26149a6f 100644 --- a/src/main/java/domain/pieces/Guard.java +++ b/src/main/java/domain/pieces/Guard.java @@ -2,12 +2,15 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.HashSet; import java.util.Set; public class Guard extends Piece { + private final PieceType pieceType = PieceType.GUARD; + public Guard(Camp camp) { super(camp); } @@ -92,4 +95,9 @@ private Position move_LD(Position position) { return position; } } + + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/domain/pieces/Horse.java b/src/main/java/domain/pieces/Horse.java index 43ad78b729..c10fce8065 100644 --- a/src/main/java/domain/pieces/Horse.java +++ b/src/main/java/domain/pieces/Horse.java @@ -2,6 +2,7 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.ArrayList; import java.util.HashMap; @@ -10,6 +11,8 @@ public class Horse extends Piece { + private final PieceType pieceType = PieceType.HORSE; + public Horse(Camp camp) { super(camp); } @@ -169,4 +172,9 @@ private Map> move_D_LD(Position position) { } return routeOfDestination; } + + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 8a9c66258a..1f1fbb32df 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -2,10 +2,12 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; public class Piece { + private final PieceType pieceType = PieceType.NONE; private final Camp camp; public Piece(Camp camp) { @@ -75,4 +77,12 @@ Position rightDownDiagonal(Position position) { public boolean canMove(Position from, Position to, ExistBoard existBoard) { return true; } + + public PieceType getPieceType() { + return this.pieceType; + } + + public Camp getCamp() { + return this.camp; + } } From b08d536ab9f8571acc55196c1f102fb1e6a2f01d Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:06:03 +0900 Subject: [PATCH 20/40] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=EA=B0=92=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EC=A0=84=EB=8B=AC=20Dto=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/dto/BoardStatusDto.java | 9 +++++++++ src/main/java/dto/PositionStatusDto.java | 13 +++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/main/java/dto/BoardStatusDto.java create mode 100644 src/main/java/dto/PositionStatusDto.java diff --git a/src/main/java/dto/BoardStatusDto.java b/src/main/java/dto/BoardStatusDto.java new file mode 100644 index 0000000000..b99a1c8916 --- /dev/null +++ b/src/main/java/dto/BoardStatusDto.java @@ -0,0 +1,9 @@ +package dto; + +import java.util.List; + +public record BoardStatusDto( + List> positionStatusDtos +) { + +} diff --git a/src/main/java/dto/PositionStatusDto.java b/src/main/java/dto/PositionStatusDto.java new file mode 100644 index 0000000000..bbe48d746e --- /dev/null +++ b/src/main/java/dto/PositionStatusDto.java @@ -0,0 +1,13 @@ +package dto; + +import domain.Camp; +import domain.PieceType; +import domain.Position; + +public record PositionStatusDto( + Position position, + PieceType pieceType, + Camp camp +) { + +} From c7c986c0827117a56bdf331209b9e4462ad99526 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:08:15 +0900 Subject: [PATCH 21/40] =?UTF-8?q?feat:=20=EC=83=81=EC=B0=A8=EB=A6=BC=20?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EB=B2=88=ED=98=B8=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/domain/ElephantFormation.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/domain/ElephantFormation.java b/src/main/java/domain/ElephantFormation.java index 8f32b22c53..94af1c4ddc 100644 --- a/src/main/java/domain/ElephantFormation.java +++ b/src/main/java/domain/ElephantFormation.java @@ -1,18 +1,21 @@ package domain; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public enum ElephantFormation { - RIGHT(initRight()), - INNER(initInner()), - LEFT(initLeft()), - OUTER(initOuter()); + RIGHT(1, initRight()), + INNER(2, initInner()), + LEFT(3, initLeft()), + OUTER(4, initOuter()); + private final int formationNumber; private final Map>> positions; - ElephantFormation(Map>> positions) { + ElephantFormation(int formationNumber, Map>> positions) { + this.formationNumber = formationNumber; this.positions = positions; } @@ -140,6 +143,13 @@ private static Map>> initOuter() { return position; } + public static ElephantFormation getFormationType(int formationNumber) { + return Arrays.stream(ElephantFormation.values()) + .filter(n -> n.formationNumber == formationNumber) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("잘못된 타입 번호입니다." + formationNumber)); + } + public List getPositions(PieceLocation pieceLocation, Camp camp) { return positions.get(pieceLocation).get(camp); } From 8d5d4e885fe88c521a6cbfd2e856408cc037b9c5 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:09:12 +0900 Subject: [PATCH 22/40] =?UTF-8?q?feat:=20Camp=20enum=20=ED=95=9C=EA=B8=80?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=A7=A4=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Camp.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/Camp.java b/src/main/java/domain/Camp.java index 3b42eb64a3..dd11b2e3cf 100644 --- a/src/main/java/domain/Camp.java +++ b/src/main/java/domain/Camp.java @@ -1,6 +1,17 @@ package domain; public enum Camp { - HAN, - CHO + HAN("한"), + CHO("초"); + + private final String campName; + + Camp(String campName) { + this.campName = campName; + } + + public String getCampName() { + return campName; + } } + From 976e2f46673e5c1ccf6c347ee0461fdd9e260e5a Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:11:23 +0900 Subject: [PATCH 23/40] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9E=85=EC=B6=9C=EB=A0=A5=20=EB=B0=8F=20=ED=94=8C=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=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/Application.java | 13 ++++ src/main/java/JanggiController.java | 75 ++++++++++++++++++++++ src/main/java/domain/Board.java | 45 +++++++++++++ src/main/java/domain/Position.java | 5 ++ src/main/java/domain/pieces/Soldier.java | 8 +++ src/main/java/view/InputView.java | 80 ++++++++++++++++++++++++ src/main/java/view/OutputView.java | 80 ++++++++++++++++++++++++ 7 files changed, 306 insertions(+) create mode 100644 src/main/java/Application.java create mode 100644 src/main/java/JanggiController.java create mode 100644 src/main/java/view/InputView.java create mode 100644 src/main/java/view/OutputView.java diff --git a/src/main/java/Application.java b/src/main/java/Application.java new file mode 100644 index 0000000000..d4c180750a --- /dev/null +++ b/src/main/java/Application.java @@ -0,0 +1,13 @@ +import view.InputView; +import view.OutputView; + +public class Application { + + public static void main(String[] args) { + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + + JanggiController janggiController = new JanggiController(inputView, outputView); + janggiController.run(); + } +} diff --git a/src/main/java/JanggiController.java b/src/main/java/JanggiController.java new file mode 100644 index 0000000000..8c44c896ff --- /dev/null +++ b/src/main/java/JanggiController.java @@ -0,0 +1,75 @@ +import domain.Board; +import domain.Camp; +import domain.ElephantFormation; +import domain.Position; +import dto.BoardStatusDto; +import view.InputView; +import view.OutputView; + +public class JanggiController { + + InputView inputView; + OutputView outputView; + + + JanggiController(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void run() { + Board board = generateBoard(); + printBoard(board); + + playJanggi(board); + } + + private Board generateBoard() { + Board board = new Board(); + int choElephantFormation = inputView.askElephantFormation(Camp.CHO); + int hanElephantFormation = inputView.askElephantFormation(Camp.HAN); + board.generatePiecesBy(Camp.CHO, mappingElephantFormation(choElephantFormation)); + board.generatePiecesBy(Camp.HAN, mappingElephantFormation(hanElephantFormation)); + return board; + } + + private void playJanggi(Board board) { + Camp camp = Camp.CHO; + while (true) { + Position fromPosition = askFromPosition(camp, board); + Position toPosition = inputView.askToPosition(camp); + board.move(fromPosition, toPosition); + printBoard(board); + camp = turnCamp(camp); + + //Todo: 사이클2 왕이 잡히면, 게임이 종료 + } + } + + private Camp turnCamp(Camp camp) { + if (camp.equals(Camp.CHO)) { + return Camp.HAN; + } + return Camp.CHO; + } + + private Position askFromPosition(Camp camp, Board board) { + while (true) { + Position fromPosition = inputView.askFromPosition(camp); + if (!board.isPieceOfCamp(fromPosition, camp)) { + outputView.printWrongChoice(); + continue; + } + return fromPosition; + } + } + + private void printBoard(Board board) { + BoardStatusDto boardStatus = board.getBoardStatus(); + outputView.printBoardStatus(boardStatus); + } + + private ElephantFormation mappingElephantFormation(int userInput) { + return ElephantFormation.getFormationType(userInput); + } +} diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java index 57317addc7..8d011b2c60 100644 --- a/src/main/java/domain/Board.java +++ b/src/main/java/domain/Board.java @@ -1,13 +1,24 @@ package domain; import domain.pieces.Piece; +import dto.BoardStatusDto; +import dto.PositionStatusDto; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; public class Board implements ExistBoard { private final Map board = new HashMap<>(); + public void generatePiecesBy(Camp camp, ElephantFormation elephantFormation) { + PieceGenerator pieceGenerator = new PieceGenerator(); + Map pieces = pieceGenerator.generatePieces(camp, elephantFormation); + + board.putAll(pieces); + } + public void locatePiece(Position position, Piece piece) { if (!isExist(position)) { board.put(position, piece); @@ -54,4 +65,38 @@ public boolean isDifferentPieceType(Position position, Piece piece) { return board.get(position).isDifferentPieceType(piece); } + + public BoardStatusDto getBoardStatus() { + List> boardStatusDto = new ArrayList<>(); + for (int y = Position.MIN_Y_VALUE; y <= Position.MAX_Y_VALUE; y++) { + List xPositionStatus = new ArrayList<>(); + for (int x = Position.MIN_X_VALUE; x <= Position.MAX_X_VALUE; x++) { + Position position = new Position(x, y); + + PositionStatusDto positionStatusDto = getPositionStatusDto(position); + xPositionStatus.add(positionStatusDto); + } + boardStatusDto.add(xPositionStatus); + } + return new BoardStatusDto(boardStatusDto); + } + + private PositionStatusDto getPositionStatusDto(Position position) { + if (!board.containsKey(position)) { + return new PositionStatusDto(position, PieceType.NONE, Camp.CHO); + } + + Piece piece = board.get(position); + PieceType pieceType = piece.getPieceType(); + Camp camp = piece.getCamp(); + return new PositionStatusDto(position, pieceType, camp); + } + + public boolean isPieceOfCamp(Position position, Camp camp) { + if (!board.containsKey(position)) { + return false; + } + + return board.get(position).isSameCamp(camp); + } } diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index 57159e03b6..cee27273d3 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -4,6 +4,11 @@ public class Position { + public static int MAX_X_VALUE = 8; + public static int MIN_X_VALUE = 0; + public static int MAX_Y_VALUE = 9; + public static int MIN_Y_VALUE = 0; + private final int x; private final int y; diff --git a/src/main/java/domain/pieces/Soldier.java b/src/main/java/domain/pieces/Soldier.java index 2c9120b34b..6fc0c8da5c 100644 --- a/src/main/java/domain/pieces/Soldier.java +++ b/src/main/java/domain/pieces/Soldier.java @@ -2,12 +2,15 @@ import domain.Camp; import domain.ExistBoard; +import domain.PieceType; import domain.Position; import java.util.HashSet; import java.util.Set; public class Soldier extends Piece { + private final PieceType pieceType = PieceType.SOLDIER; + public Soldier(Camp camp) { super(camp); } @@ -62,4 +65,9 @@ private Position move_D(Position position) { return position; } } + + @Override + public PieceType getPieceType() { + return this.pieceType; + } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java new file mode 100644 index 0000000000..7af3f32a67 --- /dev/null +++ b/src/main/java/view/InputView.java @@ -0,0 +1,80 @@ +package view; + +import domain.Camp; +import domain.Position; +import java.util.Arrays; +import java.util.Scanner; + +public class InputView { + + private final Scanner sc = new Scanner(System.in); + + public int askElephantFormation(Camp camp) { + return readElephantFormation(camp); + } + + public Position askFromPosition(Camp camp) { + while (true) { + try { + System.out.println(camp.getCampName() + " 플레이어는 말을 선택해주세요. (입력좌표 예시: 2, 1)"); + return readPosition(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } + + public Position askToPosition(Camp camp) { + while (true) { + try { + System.out.println( + camp.getCampName() + " 플레이어는 선택한 말을 움직일 위치를 입력해 주세요.(입력좌표 예시: 2, 3)"); + return readPosition(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } + + private int readElephantFormation(Camp camp) { + while (true) { + try { + System.out.println(camp.getCampName() + "상 차림을 결정해주세요."); + System.out.println("1. [마 상 마 상]"); + System.out.println("2. [마 상 상 마]"); + System.out.println("3. [상 마 상 마]"); + System.out.println("4. [상 마 마 상]"); + return Integer.parseInt(sc.nextLine()); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + } + } + } + + private Position readPosition() { + System.out.print("좌표: "); + String[] input = Arrays.stream(sc.nextLine().split(",")) + .map(String::trim) + .toArray(String[]::new); + + validateInputSize(input); + int x = parseInt(input[0]); + int y = parseInt(input[1]); + System.out.println(); + return new Position(x, y); + } + + private int parseInt(String input) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("[ERROR] 숫자를 입력해 주세요"); + } + } + + private void validateInputSize(String[] input) { + if (input.length != 2) { + throw new IllegalArgumentException("[ERROR] 좌표는 숫자 2개 입니다."); + } + } +} diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java new file mode 100644 index 0000000000..6bce88fcf2 --- /dev/null +++ b/src/main/java/view/OutputView.java @@ -0,0 +1,80 @@ +package view; + +import domain.Camp; +import domain.PieceType; +import dto.BoardStatusDto; +import dto.PositionStatusDto; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +public class OutputView { + + private static final String ANSI_RESET = "\u001B[0m"; + private static final String ANSI_GREEN = "\u001B[32m"; + private static final String ANSI_RED = "\u001B[31m"; + + // 전각 문자 통일을 위한 설정 + private static final String EMPTY_SPACE = "."; // 전각 마침표 (U+FF0E) + private static final String[] FULL_WIDTH_NUMBERS = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + }; + + private static final Map CHO_SYMBOLS = new EnumMap<>(PieceType.class); + private static final Map HAN_SYMBOLS = new EnumMap<>(PieceType.class); + + static { + CHO_SYMBOLS.put(PieceType.GENERAL, "楚"); + CHO_SYMBOLS.put(PieceType.CHARIOT, "車"); + CHO_SYMBOLS.put(PieceType.CANNON, "包"); + CHO_SYMBOLS.put(PieceType.HORSE, "馬"); + CHO_SYMBOLS.put(PieceType.ELEPHANT, "象"); + CHO_SYMBOLS.put(PieceType.GUARD, "士"); + CHO_SYMBOLS.put(PieceType.SOLDIER, "卒"); + + HAN_SYMBOLS.put(PieceType.GENERAL, "漢"); + HAN_SYMBOLS.put(PieceType.CHARIOT, "車"); + HAN_SYMBOLS.put(PieceType.CANNON, "砲"); + HAN_SYMBOLS.put(PieceType.HORSE, "馬"); + HAN_SYMBOLS.put(PieceType.ELEPHANT, "相"); + HAN_SYMBOLS.put(PieceType.GUARD, "士"); + HAN_SYMBOLS.put(PieceType.SOLDIER, "兵"); + } + + public void printBoardStatus(BoardStatusDto boardStatusDto) { + List> rows = boardStatusDto.positionStatusDtos(); + + // 1. 상단 열 인덱스 출력 (전각 숫자 사용, 앞부분 공백 2칸으로 시작점 정렬) + System.out.println("\n 0 1 2 3 4 5 6 7 8"); + + for (int i = 0; i < rows.size(); i++) { + // 2. 좌측 행 인덱스 출력 (전각 숫자 사용) + System.out.print(FULL_WIDTH_NUMBERS[i] + " "); + + List row = rows.get(i); + for (PositionStatusDto cell : row) { + // 3. 기물 출력 및 띄어쓰기 1칸 + System.out.print(formatPiece(cell) + " "); + } + System.out.println(); + } + } + + public void printWrongChoice() { + System.out.println("잘못된 말 선택입니다."); + } + + private String formatPiece(PositionStatusDto cell) { + if (cell.pieceType() == PieceType.NONE) { + return EMPTY_SPACE; // 전각 마침표 반환 + } + + String symbol = (cell.camp() == Camp.CHO) + ? CHO_SYMBOLS.get(cell.pieceType()) + : HAN_SYMBOLS.get(cell.pieceType()); + + String color = (cell.camp() == Camp.CHO) ? ANSI_GREEN : ANSI_RED; + + return color + symbol + ANSI_RESET; + } +} From 0b635777f61f4d9fe096eca577a0c75b9987ace1 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:14:52 +0900 Subject: [PATCH 24/40] =?UTF-8?q?docs:=20README=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 4dfe02c3f2..dd4afb1d39 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ **주요 기능** -- [ ] 플레이어는 ‘상 차림’을 결정할 수 있다. +- [x] 플레이어는 ‘상 차림’을 결정할 수 있다. - [x] 기물은 자동으로 배치된다. -- [ ] 현재 장기판의 현황을 볼 수 있다. -- [ ] 초나라(선)/한나라(후) 번갈아가며 플레이한다. +- [x] 현재 장기판의 현황을 볼 수 있다. +- [x] 초나라(선)/한나라(후) 번갈아가며 플레이한다. - [x] 플레이어는 기물의 이동 규칙에 따라 이동시킬 수 있다. - [x] 상대 플레이어의 기물을 잡을 수 있다. - [ ] 상대 플레이어의 왕을 잡으면 승리하고, 게임은 종료된다. @@ -32,23 +32,23 @@ 3 기물이 배치 되었습니다. - 1 2 3 4 5 6 7 8 9 - 1 車 馬 象 士 · 士 馬 象 車 - 2 · · · · 漢 · · · · - 3 · 砲 · · · · · 砲 · - 4 兵 · 兵 · 兵 · 兵 · 兵 + 0 1 2 3 4 5 6 7 8 + 0 車 馬 象 士 · 士 馬 象 車 + 1 · · · · 漢 · · · · + 2 · 砲 · · · · · 砲 · + 3 兵 · 兵 · 兵 · 兵 · 兵 + 4 · · · · · · · · · 5 · · · · · · · · · - 6 · · · · · · · · · - 7 卒 · 卒 · 卒 · 卒 · 卒 - 8 · 炮 · · · · · 炮 · - 9 · · · · 楚 · · · · - 0 車 馬 相 士 · 士 相 馬 車 + 6 卒 · 卒 · 卒 · 卒 · 卒 + 7 · 炮 · · · · · 炮 · + 8 · · · · 楚 · · · · + 9 車 馬 相 士 · 士 相 馬 車 -초나라 플레이어는 말을 선택해주세요.(입력예시 좌표: 1, 1) -좌표: 1, 0 +초나라 플레이어는 말을 선택해주세요.(입력예시 좌표: 0, 9) +좌표: 0, 9 -초나라 플레이어는 선택한 말을 움직일 위치를 입력해 주세요.(입력예시 좌표: 1, 3) -좌표: 1, 8 +초나라 플레이어는 선택한 말을 움직일 위치를 입력해 주세요.(입력예시 좌표: 0, 7) +좌표: 0, 7 이동되었습니다. 0 1 2 3 4 5 6 7 8 @@ -66,19 +66,19 @@ **입력** -- [ ] ‘상 차림’ 배치 타입 입력받는다. -- [ ] 선택할 기물의 좌표를 입력받는다. - - [ ] `[ERROR]` 해당 좌표에 기물이 없을 때 - - [ ] `[ERROR]` 선택한 기물이 플레이어의 기물이 아닐 때 -- [ ] 이동할 좌표를 입력받는다. - - [ ] `[ERROR]` 이동할 좌표가 보드 크기 내에 유효하지 않을 때 +- [x] ‘상 차림’ 배치 타입 입력받는다. +- [x] 선택할 기물의 좌표를 입력받는다. + - [x] `[ERROR]` 해당 좌표에 기물이 없을 때 + - [x] `[ERROR]` 선택한 기물이 플레이어의 기물이 아닐 때 +- [x] 이동할 좌표를 입력받는다. + - [x] `[ERROR]` 이동할 좌표가 보드 크기 내에 유효하지 않을 때 - [ ] `[ERROR]` 해당 좌표에 플레이어의 팀 기물이 있을 때 - [ ] `[ERROR]` 이동 규칙에 따라 이동할 수 없을 때 **출력** -- [ ] 4 종류의 ‘상 차림’ 배치를 출력한다. -- [ ] 기물이 배치된 보드를 출력한다. -- [ ] 현재 턴을 출력한다. -- [ ] 턴이 끝나고 기물 이동이 된 보드를 출력한다. +- [x] 4 종류의 ‘상 차림’ 배치를 출력한다. +- [x] 기물이 배치된 보드를 출력한다. +- [x] 현재 턴을 출력한다. +- [x] 턴이 끝나고 기물 이동이 된 보드를 출력한다. - [ ] 최종 승패를 출력한다. From 259264187db58ab6d459d6558bf85d4b4dccb770 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 11:26:31 +0900 Subject: [PATCH 25/40] =?UTF-8?q?feat:=20=EA=B8=B0=EB=AC=BC=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EB=B6=88=EA=B0=80=EB=8A=A5=20=EC=8B=9C=20=EC=9E=AC?= =?UTF-8?q?=EC=9E=85=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/main/java/JanggiController.java | 11 ++++++++--- src/main/java/view/OutputView.java | 4 ++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index dd4afb1d39..12c30d96a5 100644 --- a/README.md +++ b/README.md @@ -72,8 +72,8 @@ - [x] `[ERROR]` 선택한 기물이 플레이어의 기물이 아닐 때 - [x] 이동할 좌표를 입력받는다. - [x] `[ERROR]` 이동할 좌표가 보드 크기 내에 유효하지 않을 때 - - [ ] `[ERROR]` 해당 좌표에 플레이어의 팀 기물이 있을 때 - - [ ] `[ERROR]` 이동 규칙에 따라 이동할 수 없을 때 + - [x] `[ERROR]` 해당 좌표에 플레이어의 팀 기물이 있을 때 + - [x] `[ERROR]` 이동 규칙에 따라 이동할 수 없을 때 **출력** diff --git a/src/main/java/JanggiController.java b/src/main/java/JanggiController.java index 8c44c896ff..3e4ab1d37f 100644 --- a/src/main/java/JanggiController.java +++ b/src/main/java/JanggiController.java @@ -36,9 +36,14 @@ private Board generateBoard() { private void playJanggi(Board board) { Camp camp = Camp.CHO; while (true) { - Position fromPosition = askFromPosition(camp, board); - Position toPosition = inputView.askToPosition(camp); - board.move(fromPosition, toPosition); + try{ + Position fromPosition = askFromPosition(camp, board); + Position toPosition = inputView.askToPosition(camp); + board.move(fromPosition, toPosition); + } catch (IllegalArgumentException e) { + outputView.printErrorMessage(e); + continue; + } printBoard(board); camp = turnCamp(camp); diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 6bce88fcf2..a48d4dce9e 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -64,6 +64,10 @@ public void printWrongChoice() { System.out.println("잘못된 말 선택입니다."); } + public void printErrorMessage(Exception e) { + System.out.println(e.getMessage()); + } + private String formatPiece(PositionStatusDto cell) { if (cell.pieceType() == PieceType.NONE) { return EMPTY_SPACE; // 전각 마침표 반환 From 2351f6466833ae3c821f7e480f726811d0e70e90 Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 12:53:13 +0900 Subject: [PATCH 26/40] =?UTF-8?q?refactor:=20=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EB=A7=A4=EC=A7=81=EB=84=98=EB=B2=84=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Position.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index cee27273d3..9d56c102a3 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -28,14 +28,14 @@ public int getY() { } private void validatePosX(int x) { - if (x < 0 || x > 8) { - throw new IllegalArgumentException("[ERROR] x 좌표는 0~8 사이어야합니다."); + if (x < MIN_X_VALUE || x > MAX_X_VALUE) { + throw new IllegalArgumentException("[ERROR] x 좌표는 " + MIN_X_VALUE + "~" + MAX_X_VALUE + "사이어야합니다."); } } private void validatePosY(int y) { - if (y < 0 || y > 9) { - throw new IllegalArgumentException("[ERROR] y 좌표는 0~9 사이어야합니다."); + if (y < MIN_Y_VALUE || y > MAX_Y_VALUE) { + throw new IllegalArgumentException("[ERROR] y 좌표는" + MIN_Y_VALUE + "~" + MAX_Y_VALUE + "사이어야합니다."); } } From a629d796651030391e79eb5566660f35626ffd8e Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Mon, 30 Mar 2026 14:44:30 +0900 Subject: [PATCH 27/40] =?UTF-8?q?refactor:=20Camp=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A2=8C=ED=91=9C=20=EC=97=90=EB=9F=AC=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Camp.java | 4 ++-- src/main/java/domain/Position.java | 2 +- src/main/java/view/InputView.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/Camp.java b/src/main/java/domain/Camp.java index dd11b2e3cf..33abb85b49 100644 --- a/src/main/java/domain/Camp.java +++ b/src/main/java/domain/Camp.java @@ -1,8 +1,8 @@ package domain; public enum Camp { - HAN("한"), - CHO("초"); + HAN("한나라"), + CHO("초나라"); private final String campName; diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index 9d56c102a3..c52ac1225b 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -35,7 +35,7 @@ private void validatePosX(int x) { private void validatePosY(int y) { if (y < MIN_Y_VALUE || y > MAX_Y_VALUE) { - throw new IllegalArgumentException("[ERROR] y 좌표는" + MIN_Y_VALUE + "~" + MAX_Y_VALUE + "사이어야합니다."); + throw new IllegalArgumentException("[ERROR] y 좌표는 " + MIN_Y_VALUE + "~" + MAX_Y_VALUE + "사이어야합니다."); } } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 7af3f32a67..46d80fd834 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -39,7 +39,7 @@ public Position askToPosition(Camp camp) { private int readElephantFormation(Camp camp) { while (true) { try { - System.out.println(camp.getCampName() + "상 차림을 결정해주세요."); + System.out.println(camp.getCampName() + " 상 차림을 결정해주세요."); System.out.println("1. [마 상 마 상]"); System.out.println("2. [마 상 상 마]"); System.out.println("3. [상 마 상 마]"); From b75174284796dc28d1843eca84ae98bada431765 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 14:02:28 +0900 Subject: [PATCH 28/40] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=20?= =?UTF-8?q?=EC=A0=9C=EC=96=B4=EC=9E=90=20=EB=B0=8F=20final=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/main/java/JanggiController.java | 4 ++-- src/main/java/domain/Position.java | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/JanggiController.java b/src/main/java/JanggiController.java index 3e4ab1d37f..387ec30993 100644 --- a/src/main/java/JanggiController.java +++ b/src/main/java/JanggiController.java @@ -8,8 +8,8 @@ public class JanggiController { - InputView inputView; - OutputView outputView; + private final InputView inputView; + private final OutputView outputView; JanggiController(InputView inputView, OutputView outputView) { diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index c52ac1225b..3f1e282488 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -4,10 +4,10 @@ public class Position { - public static int MAX_X_VALUE = 8; - public static int MIN_X_VALUE = 0; - public static int MAX_Y_VALUE = 9; - public static int MIN_Y_VALUE = 0; + public final static int MAX_X_VALUE = 8; + public final static int MIN_X_VALUE = 0; + public final static int MAX_Y_VALUE = 9; + public final static int MIN_Y_VALUE = 0; private final int x; private final int y; From e025d9c430076e6ca09e1b0a45e3af0df7188a27 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 16:57:43 +0900 Subject: [PATCH 29/40] =?UTF-8?q?refactor:=20Camp=20Enum=20NONE=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/main/java/domain/Board.java | 2 +- src/main/java/domain/Camp.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java index 8d011b2c60..bbedace96e 100644 --- a/src/main/java/domain/Board.java +++ b/src/main/java/domain/Board.java @@ -83,7 +83,7 @@ public BoardStatusDto getBoardStatus() { private PositionStatusDto getPositionStatusDto(Position position) { if (!board.containsKey(position)) { - return new PositionStatusDto(position, PieceType.NONE, Camp.CHO); + return new PositionStatusDto(position, PieceType.NONE, Camp.NONE); } Piece piece = board.get(position); diff --git a/src/main/java/domain/Camp.java b/src/main/java/domain/Camp.java index 33abb85b49..94058f85d4 100644 --- a/src/main/java/domain/Camp.java +++ b/src/main/java/domain/Camp.java @@ -2,7 +2,8 @@ public enum Camp { HAN("한나라"), - CHO("초나라"); + CHO("초나라"), + NONE("중립"); private final String campName; From 3a57a25c42ed31f682bcc44201a4b79267977926 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 17:04:01 +0900 Subject: [PATCH 30/40] =?UTF-8?q?refactor:=20Piece=20=EC=B6=94=EC=83=81=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/pieces/Piece.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 1f1fbb32df..6f3a830ec7 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -5,7 +5,7 @@ import domain.PieceType; import domain.Position; -public class Piece { +public abstract class Piece { private final PieceType pieceType = PieceType.NONE; private final Camp camp; @@ -74,9 +74,7 @@ Position rightDownDiagonal(Position position) { return new Position(++x, ++y); } - public boolean canMove(Position from, Position to, ExistBoard existBoard) { - return true; - } + public abstract boolean canMove(Position from, Position to, ExistBoard existBoard); public PieceType getPieceType() { return this.pieceType; From ab2a4e51d15f58576b973412e58c72cfcbfc07ab Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 17:10:27 +0900 Subject: [PATCH 31/40] =?UTF-8?q?refactor:=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EB=B9=84=EA=B5=90.=20getClass=EA=B0=80=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?PieceType=EC=9D=84=20=EB=B9=84=EA=B5=90=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=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/domain/pieces/Piece.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 6f3a830ec7..166031c14e 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -23,7 +23,7 @@ public boolean isSameCamp(Camp camp) { } public boolean isDifferentPieceType(Piece piece) { - return this.getClass() != piece.getClass(); + return this.getPieceType()!= piece.getPieceType(); } Position up(Position position) { From f1674ee587fa13cf2698b23e3f16fc12319c98a9 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 21:54:48 +0900 Subject: [PATCH 32/40] =?UTF-8?q?refactor:=20Piece=20=EC=B6=94=EC=83=81?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EB=B3=80=EA=B2=BD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20test=20=EA=B8=B0=EB=AC=BC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/test/java/BoardTest.java | 10 +++++----- src/test/java/domain/pieces/CannonTest.java | 8 ++++---- src/test/java/domain/pieces/ChariotTest.java | 2 +- src/test/java/domain/pieces/ElephantTest.java | 2 +- src/test/java/domain/pieces/GeneralTest.java | 2 +- src/test/java/domain/pieces/GuardTest.java | 2 +- src/test/java/domain/pieces/HorseTest.java | 2 +- src/test/java/domain/pieces/SoldierTest.java | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/test/java/BoardTest.java b/src/test/java/BoardTest.java index 62c4aba964..c3b8090a6a 100644 --- a/src/test/java/BoardTest.java +++ b/src/test/java/BoardTest.java @@ -3,7 +3,7 @@ import domain.Board; import domain.Camp; import domain.Position; -import domain.pieces.Piece; +import domain.pieces.Soldier; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -13,7 +13,7 @@ public class BoardTest { void 특정_위치에_기물을_놓을_수_있다() { Board board = new Board(); Position position = new Position(1, 2); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); board.locatePiece(position, piece); Assertions.assertEquals(board.getPieceFrom(position), piece); @@ -23,8 +23,8 @@ public class BoardTest { void 같은_팀_기물은_잡을_수_없다() { Board board = new Board(); Position position = new Position(1, 2); - Piece locatedPiece = new Piece(Camp.HAN); - Piece anotherPiece = new Piece(Camp.HAN); + Soldier locatedPiece = new Soldier(Camp.HAN); + Soldier anotherPiece = new Soldier(Camp.HAN); board.locatePiece(position, locatedPiece); assertThatThrownBy(() -> board.locatePiece(position, anotherPiece)).isInstanceOf( @@ -37,7 +37,7 @@ public class BoardTest { Position fromPosition = new Position(1, 2); Position toPosition = new Position(1, 3); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); board.locatePiece(fromPosition, piece); //초기 배치 board.move(fromPosition, toPosition); // A위치의 기물을 B로 옮긴다. diff --git a/src/test/java/domain/pieces/CannonTest.java b/src/test/java/domain/pieces/CannonTest.java index 2b7b753ee1..2ce2c04733 100644 --- a/src/test/java/domain/pieces/CannonTest.java +++ b/src/test/java/domain/pieces/CannonTest.java @@ -12,7 +12,7 @@ public class CannonTest { void 다른_기물을_넘고_이동_가능() { Board board = new Board(); Cannon cannon = new Cannon(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); Position fromPosition = new Position(3, 5); Position anotherPiecePosition = new Position(5, 5); @@ -52,8 +52,8 @@ public class CannonTest { void 기물을_넘고_다른_기물을_만나기_전까지_이동_가능() { Board board = new Board(); Cannon cannon = new Cannon(Camp.HAN); - Piece pieceA = new Piece(Camp.HAN); - Piece pieceB = new Piece(Camp.HAN); + Soldier pieceA = new Soldier(Camp.HAN); + Soldier pieceB = new Soldier(Camp.HAN); Position fromPosition = new Position(3, 5); Position anotherPieceAPosition = new Position(5, 5); @@ -75,7 +75,7 @@ public class CannonTest { void 기물을_넘고_다른_기물을_만나기_전까지_이동_가능_포는_못잡음() { Board board = new Board(); Cannon cannon = new Cannon(Camp.HAN); - Piece pieceA = new Piece(Camp.CHO); + Soldier pieceA = new Soldier(Camp.CHO); Cannon pieceB = new Cannon(Camp.CHO); Position fromPosition = new Position(3, 5); diff --git a/src/test/java/domain/pieces/ChariotTest.java b/src/test/java/domain/pieces/ChariotTest.java index 4f08b0ed8d..3ee6dea438 100644 --- a/src/test/java/domain/pieces/ChariotTest.java +++ b/src/test/java/domain/pieces/ChariotTest.java @@ -12,7 +12,7 @@ public class ChariotTest { void 다른_기물_뒤로는_이동할_수_없다() { Board board = new Board(); Chariot chariot = new Chariot(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); Position fromPosition = new Position(3, 5); Position anotherPiecePosition = new Position(6, 5); diff --git a/src/test/java/domain/pieces/ElephantTest.java b/src/test/java/domain/pieces/ElephantTest.java index 5351afb2de..a0d55ec4d5 100644 --- a/src/test/java/domain/pieces/ElephantTest.java +++ b/src/test/java/domain/pieces/ElephantTest.java @@ -38,7 +38,7 @@ public class ElephantTest { void 위로_오른대각선_경로_막힘() { Board board = new Board(); Elephant elephant = new Elephant(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); Position fromPosition = new Position(2, 9); Position toPosition = new Position(4, 6); diff --git a/src/test/java/domain/pieces/GeneralTest.java b/src/test/java/domain/pieces/GeneralTest.java index 916b733cf4..66d06bf882 100644 --- a/src/test/java/domain/pieces/GeneralTest.java +++ b/src/test/java/domain/pieces/GeneralTest.java @@ -38,7 +38,7 @@ class GeneralTest { void 아래로_오른대각선_경로_막힘() { Board board = new Board(); General general = new General(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); Position fromPosition = new Position(4, 1); Position toPosition = new Position(5, 2); diff --git a/src/test/java/domain/pieces/GuardTest.java b/src/test/java/domain/pieces/GuardTest.java index e3f1a499d9..0f6ed74ba5 100644 --- a/src/test/java/domain/pieces/GuardTest.java +++ b/src/test/java/domain/pieces/GuardTest.java @@ -38,7 +38,7 @@ public class GuardTest { void 아래로_오른대각선_경로_막힘() { Board board = new Board(); Guard guard = new Guard(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); Position fromPosition = new Position(3, 0); Position toPosition = new Position(4, 1); diff --git a/src/test/java/domain/pieces/HorseTest.java b/src/test/java/domain/pieces/HorseTest.java index e253c223f3..8ea01d35c0 100644 --- a/src/test/java/domain/pieces/HorseTest.java +++ b/src/test/java/domain/pieces/HorseTest.java @@ -38,7 +38,7 @@ public class HorseTest { void 위로_오른대각선_경로_막힘() { Board board = new Board(); Horse horse = new Horse(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Piece piece = new Soldier(Camp.HAN); Position fromPosition = new Position(2, 9); Position toPosition = new Position(3, 7); diff --git a/src/test/java/domain/pieces/SoldierTest.java b/src/test/java/domain/pieces/SoldierTest.java index af4724b874..98389d0778 100644 --- a/src/test/java/domain/pieces/SoldierTest.java +++ b/src/test/java/domain/pieces/SoldierTest.java @@ -44,7 +44,7 @@ public class SoldierTest { void 같은_팀_기물_막힘으로_앞으로_한_칸_전진_불가() { Board board = new Board(); Soldier soldier = new Soldier(Camp.HAN); - Piece piece = new Piece(Camp.HAN); + Soldier piece = new Soldier(Camp.HAN); Position fromPosition = new Position(0, 3); Position toPosition = new Position(0, 4); @@ -60,7 +60,7 @@ public class SoldierTest { void 상대_팀_기물_잡고_앞으로_한_칸_전진_가능() { Board board = new Board(); Soldier soldier = new Soldier(Camp.HAN); - Piece piece = new Piece(Camp.CHO); + Soldier piece = new Soldier(Camp.CHO); Position fromPosition = new Position(0, 3); Position toPosition = new Position(0, 4); From a32db10ff1562d24e40083b2e9d92910913c35b7 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 21:57:16 +0900 Subject: [PATCH 33/40] =?UTF-8?q?refactor:=20=EC=83=9D=EC=84=B1=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=ED=86=B5=ED=95=B4=20PieceType=EC=9D=84=20=EB=B0=9B?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=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/domain/pieces/Cannon.java | 9 +-------- src/main/java/domain/pieces/Chariot.java | 9 +-------- src/main/java/domain/pieces/Elephant.java | 9 +-------- src/main/java/domain/pieces/General.java | 9 +-------- src/main/java/domain/pieces/Guard.java | 9 +-------- src/main/java/domain/pieces/Horse.java | 9 +-------- src/main/java/domain/pieces/Piece.java | 5 +++-- src/main/java/domain/pieces/Soldier.java | 9 +-------- 8 files changed, 10 insertions(+), 58 deletions(-) diff --git a/src/main/java/domain/pieces/Cannon.java b/src/main/java/domain/pieces/Cannon.java index 626638d5f7..0fe0759445 100644 --- a/src/main/java/domain/pieces/Cannon.java +++ b/src/main/java/domain/pieces/Cannon.java @@ -9,10 +9,8 @@ public class Cannon extends Piece { - private final PieceType pieceType = PieceType.CANNON; - public Cannon(Camp camp) { - super(camp); + super(camp, PieceType.CANNON); } @Override @@ -138,9 +136,4 @@ private Set moveDown(Position position, ExistBoard existBoard) { private boolean checkCannonJumping(Position position, ExistBoard existBoard) { return existBoard.isExist(position) && existBoard.isDifferentPieceType(position, this); } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } diff --git a/src/main/java/domain/pieces/Chariot.java b/src/main/java/domain/pieces/Chariot.java index 79d92ef633..111d1a2f4f 100644 --- a/src/main/java/domain/pieces/Chariot.java +++ b/src/main/java/domain/pieces/Chariot.java @@ -9,10 +9,8 @@ public class Chariot extends Piece { - private final PieceType pieceType = PieceType.CHARIOT; - public Chariot(Camp camp) { - super(camp); + super(camp, PieceType.CHARIOT); } @Override @@ -78,9 +76,4 @@ private Set moveDown(Position position, ExistBoard existBoard) { } return movablePositions; } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } diff --git a/src/main/java/domain/pieces/Elephant.java b/src/main/java/domain/pieces/Elephant.java index 030cd2777f..6434305914 100644 --- a/src/main/java/domain/pieces/Elephant.java +++ b/src/main/java/domain/pieces/Elephant.java @@ -11,10 +11,8 @@ public class Elephant extends Piece { - private final PieceType pieceType = PieceType.ELEPHANT; - public Elephant(Camp camp) { - super(camp); + super(camp, PieceType.ELEPHANT); } @Override @@ -201,9 +199,4 @@ private Map> move_L_LD(Position position) { return routeOfDestination; } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } diff --git a/src/main/java/domain/pieces/General.java b/src/main/java/domain/pieces/General.java index e7281fa6e6..963da22782 100644 --- a/src/main/java/domain/pieces/General.java +++ b/src/main/java/domain/pieces/General.java @@ -9,10 +9,8 @@ public class General extends Piece { - private final PieceType pieceType = PieceType.GENERAL; - public General(Camp camp) { - super(camp); + super(camp, PieceType.GENERAL); } @Override @@ -95,9 +93,4 @@ private Position move_LD(Position position) { return position; } } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } diff --git a/src/main/java/domain/pieces/Guard.java b/src/main/java/domain/pieces/Guard.java index 5e26149a6f..0e0d2dd5db 100644 --- a/src/main/java/domain/pieces/Guard.java +++ b/src/main/java/domain/pieces/Guard.java @@ -9,10 +9,8 @@ public class Guard extends Piece { - private final PieceType pieceType = PieceType.GUARD; - public Guard(Camp camp) { - super(camp); + super(camp, PieceType.GUARD); } @Override @@ -95,9 +93,4 @@ private Position move_LD(Position position) { return position; } } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } diff --git a/src/main/java/domain/pieces/Horse.java b/src/main/java/domain/pieces/Horse.java index c10fce8065..ba724d3e57 100644 --- a/src/main/java/domain/pieces/Horse.java +++ b/src/main/java/domain/pieces/Horse.java @@ -11,10 +11,8 @@ public class Horse extends Piece { - private final PieceType pieceType = PieceType.HORSE; - public Horse(Camp camp) { - super(camp); + super(camp, PieceType.HORSE); } @Override @@ -172,9 +170,4 @@ private Map> move_D_LD(Position position) { } return routeOfDestination; } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 166031c14e..9abe30a2ed 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -7,11 +7,12 @@ public abstract class Piece { - private final PieceType pieceType = PieceType.NONE; + private final PieceType pieceType; private final Camp camp; - public Piece(Camp camp) { + public Piece(Camp camp, PieceType pieceType) { this.camp = camp; + this.pieceType = pieceType; } public boolean isSameCamp(Piece comparedPiece) { diff --git a/src/main/java/domain/pieces/Soldier.java b/src/main/java/domain/pieces/Soldier.java index 6fc0c8da5c..c0a1bed8e5 100644 --- a/src/main/java/domain/pieces/Soldier.java +++ b/src/main/java/domain/pieces/Soldier.java @@ -9,10 +9,8 @@ public class Soldier extends Piece { - private final PieceType pieceType = PieceType.SOLDIER; - public Soldier(Camp camp) { - super(camp); + super(camp, PieceType.SOLDIER); } @Override @@ -65,9 +63,4 @@ private Position move_D(Position position) { return position; } } - - @Override - public PieceType getPieceType() { - return this.pieceType; - } } From 23aa42e9d19fc488e879bf4ebb0aad0606aa38ec Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Tue, 31 Mar 2026 22:36:58 +0900 Subject: [PATCH 34/40] =?UTF-8?q?refactor(Position):=20=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EA=B0=92=EB=8F=84=20=EC=B6=9C=EB=A0=A5=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=98=A4=EB=A5=98=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=B2=B4=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Position.java | 4 ++-- src/test/java/domain/PositionTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index 3f1e282488..a6ff8bf9b6 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -29,13 +29,13 @@ public int getY() { private void validatePosX(int x) { if (x < MIN_X_VALUE || x > MAX_X_VALUE) { - throw new IllegalArgumentException("[ERROR] x 좌표는 " + MIN_X_VALUE + "~" + MAX_X_VALUE + "사이어야합니다."); + throw new IllegalArgumentException("[ERROR] x 좌표는 " + MIN_X_VALUE + "~" + MAX_X_VALUE + "사이어야합니다." + " 입력값: " + x); } } private void validatePosY(int y) { if (y < MIN_Y_VALUE || y > MAX_Y_VALUE) { - throw new IllegalArgumentException("[ERROR] y 좌표는 " + MIN_Y_VALUE + "~" + MAX_Y_VALUE + "사이어야합니다."); + throw new IllegalArgumentException("[ERROR] y 좌표는 " + MIN_Y_VALUE + "~" + MAX_Y_VALUE + "사이어야합니다." + " 입력값: " + y); } } diff --git a/src/test/java/domain/PositionTest.java b/src/test/java/domain/PositionTest.java index 6fa1492629..1c1cbc4300 100644 --- a/src/test/java/domain/PositionTest.java +++ b/src/test/java/domain/PositionTest.java @@ -34,6 +34,6 @@ class PositionTest { void Y_예외_값_입력_오류_검증(int y) { assertThatThrownBy(() -> new Position(1, y)) .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("[ERROR]", "y좌표"); + .hasMessageContaining("[ERROR]", "y 좌표"); } } From 6c0ec7141451a65074272673aa23f6869bed05ba Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Thu, 2 Apr 2026 00:06:07 +0900 Subject: [PATCH 35/40] refactor: rename PieceLocation to InitialPieceLocation --- src/main/java/domain/ElephantFormation.java | 40 +++++++++---------- ...ocation.java => InitialPieceLocation.java} | 4 +- 2 files changed, 22 insertions(+), 22 deletions(-) rename src/main/java/domain/{PieceLocation.java => InitialPieceLocation.java} (97%) diff --git a/src/main/java/domain/ElephantFormation.java b/src/main/java/domain/ElephantFormation.java index 94af1c4ddc..241b7180b8 100644 --- a/src/main/java/domain/ElephantFormation.java +++ b/src/main/java/domain/ElephantFormation.java @@ -12,15 +12,15 @@ public enum ElephantFormation { OUTER(4, initOuter()); private final int formationNumber; - private final Map>> positions; + private final Map>> positions; - ElephantFormation(int formationNumber, Map>> positions) { + ElephantFormation(int formationNumber, Map>> positions) { this.formationNumber = formationNumber; this.positions = positions; } - private static Map>> initRight() { - Map>> position = new HashMap<>(); + private static Map>> initRight() { + Map>> position = new HashMap<>(); Map> horseRightPosition = new HashMap<>(); horseRightPosition.put(Camp.HAN, List.of( new Position(2, 0), @@ -32,7 +32,7 @@ private static Map>> initRight() { new Position(6, 9) )); - position.put(PieceLocation.HORSE, horseRightPosition); + position.put(InitialPieceLocation.HORSE, horseRightPosition); Map> elephantRightPosition = new HashMap<>(); elephantRightPosition.put(Camp.HAN, List.of( @@ -45,13 +45,13 @@ private static Map>> initRight() { new Position(7, 9) )); - position.put(PieceLocation.ELEPHANT, elephantRightPosition); + position.put(InitialPieceLocation.ELEPHANT, elephantRightPosition); return position; } - private static Map>> initInner() { - Map>> position = new HashMap<>(); + private static Map>> initInner() { + Map>> position = new HashMap<>(); Map> horseInnerPosition = new HashMap<>(); horseInnerPosition.put(Camp.HAN, List.of( new Position(1, 0), @@ -63,7 +63,7 @@ private static Map>> initInner() { new Position(7, 9) )); - position.put(PieceLocation.HORSE, horseInnerPosition); + position.put(InitialPieceLocation.HORSE, horseInnerPosition); Map> elephantInnerPosition = new HashMap<>(); elephantInnerPosition.put(Camp.HAN, List.of( @@ -76,13 +76,13 @@ private static Map>> initInner() { new Position(6, 9) )); - position.put(PieceLocation.ELEPHANT, elephantInnerPosition); + position.put(InitialPieceLocation.ELEPHANT, elephantInnerPosition); return position; } - private static Map>> initLeft() { - Map>> position = new HashMap<>(); + private static Map>> initLeft() { + Map>> position = new HashMap<>(); Map> horseLeftPosition = new HashMap<>(); horseLeftPosition.put(Camp.HAN, List.of( new Position(1, 0), @@ -94,7 +94,7 @@ private static Map>> initLeft() { new Position(7, 9) )); - position.put(PieceLocation.HORSE, horseLeftPosition); + position.put(InitialPieceLocation.HORSE, horseLeftPosition); Map> elephantLeftPosition = new HashMap<>(); elephantLeftPosition.put(Camp.HAN, List.of( @@ -107,13 +107,13 @@ private static Map>> initLeft() { new Position(6, 9) )); - position.put(PieceLocation.ELEPHANT, elephantLeftPosition); + position.put(InitialPieceLocation.ELEPHANT, elephantLeftPosition); return position; } - private static Map>> initOuter() { - Map>> position = new HashMap<>(); + private static Map>> initOuter() { + Map>> position = new HashMap<>(); Map> horseOuterPosition = new HashMap<>(); horseOuterPosition.put(Camp.HAN, List.of( new Position(2, 0), @@ -125,7 +125,7 @@ private static Map>> initOuter() { new Position(6, 9) )); - position.put(PieceLocation.HORSE, horseOuterPosition); + position.put(InitialPieceLocation.HORSE, horseOuterPosition); Map> elephantOuterPosition = new HashMap<>(); elephantOuterPosition.put(Camp.HAN, List.of( @@ -138,7 +138,7 @@ private static Map>> initOuter() { new Position(7, 9) )); - position.put(PieceLocation.ELEPHANT, elephantOuterPosition); + position.put(InitialPieceLocation.ELEPHANT, elephantOuterPosition); return position; } @@ -150,7 +150,7 @@ public static ElephantFormation getFormationType(int formationNumber) { .orElseThrow(() -> new IllegalArgumentException("잘못된 타입 번호입니다." + formationNumber)); } - public List getPositions(PieceLocation pieceLocation, Camp camp) { - return positions.get(pieceLocation).get(camp); + public List getPositions(InitialPieceLocation initialPieceLocation, Camp camp) { + return positions.get(initialPieceLocation).get(camp); } } diff --git a/src/main/java/domain/PieceLocation.java b/src/main/java/domain/InitialPieceLocation.java similarity index 97% rename from src/main/java/domain/PieceLocation.java rename to src/main/java/domain/InitialPieceLocation.java index 4defdfcb92..dfd3f6a129 100644 --- a/src/main/java/domain/PieceLocation.java +++ b/src/main/java/domain/InitialPieceLocation.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; -public enum PieceLocation { +public enum InitialPieceLocation { GENERAL(initGeneralPosition()), GUARD(initGuardPosition()), HORSE(initHorsePosition()), @@ -15,7 +15,7 @@ public enum PieceLocation { private final Map> positions; - PieceLocation(Map> positions) { + InitialPieceLocation(Map> positions) { this.positions = positions; } From 6ca82a38beb2df34728f253d514d0fc5530d2cca Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Thu, 2 Apr 2026 09:35:29 +0900 Subject: [PATCH 36/40] =?UTF-8?q?refactor:=20PieceGenerator=20static?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Board.java | 3 +- src/main/java/domain/PieceGenerator.java | 48 +++++++++++++-------- src/test/java/PieceGeneratorTest.java | 53 ++++++------------------ 3 files changed, 44 insertions(+), 60 deletions(-) diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java index bbedace96e..3f5def2806 100644 --- a/src/main/java/domain/Board.java +++ b/src/main/java/domain/Board.java @@ -13,8 +13,7 @@ public class Board implements ExistBoard { private final Map board = new HashMap<>(); public void generatePiecesBy(Camp camp, ElephantFormation elephantFormation) { - PieceGenerator pieceGenerator = new PieceGenerator(); - Map pieces = pieceGenerator.generatePieces(camp, elephantFormation); + Map pieces = PieceGenerator.generatePieces(camp, elephantFormation); board.putAll(pieces); } diff --git a/src/main/java/domain/PieceGenerator.java b/src/main/java/domain/PieceGenerator.java index 8329d1527e..419dd047e4 100644 --- a/src/main/java/domain/PieceGenerator.java +++ b/src/main/java/domain/PieceGenerator.java @@ -14,71 +14,85 @@ public class PieceGenerator { - public Map generatePieces(Camp camp, ElephantFormation elephantFormation) { + public static Map generatePieces(Camp camp, ElephantFormation elephantFormation) { + Map board = new HashMap<>(); + board.putAll(generatePiece(camp)); + board.putAll(generatePiece(camp, elephantFormation)); + + return board; + } + + private static Map generatePiece(Camp camp) { Map board = new HashMap<>(); board.putAll(generateGeneral(camp)); board.putAll(generateSoldier(camp)); board.putAll(generateGuard(camp)); - board.putAll(generateHorse(camp, elephantFormation)); - board.putAll(generateElephant(camp, elephantFormation)); board.putAll(generateCannon(camp)); board.putAll(generateChariot(camp)); return board; } - private Map generateGeneral(Camp camp) { + private static Map generatePiece(Camp camp, ElephantFormation elephantFormation) { + Map board = new HashMap<>(); + board.putAll(generateHorse(camp, elephantFormation)); + board.putAll(generateElephant(camp, elephantFormation)); + + return board; + } + + private static Map generateGeneral(Camp camp) { Map generalPosition = new HashMap<>(); - List positions = PieceLocation.GENERAL.getPositions(camp); + List positions = InitialPieceLocation.GENERAL.getPositions(camp); positions.forEach(position -> generalPosition.put(position, new General(camp))); return generalPosition; } - private Map generateSoldier(Camp camp) { + private static Map generateSoldier(Camp camp) { Map soldierPosition = new HashMap<>(); - List positions = PieceLocation.SOLDIER.getPositions(camp); + List positions = InitialPieceLocation.SOLDIER.getPositions(camp); positions.forEach(position -> soldierPosition.put(position, new Soldier(camp))); return soldierPosition; } - private Map generateGuard(Camp camp) { + private static Map generateGuard(Camp camp) { Map guardPosition = new HashMap<>(); - List positions = PieceLocation.GUARD.getPositions(camp); + List positions = InitialPieceLocation.GUARD.getPositions(camp); positions.forEach(position -> guardPosition.put(position, new Guard(camp))); return guardPosition; } - private Map generateHorse(Camp camp, ElephantFormation elephantFormation) { + private static Map generateHorse(Camp camp, ElephantFormation elephantFormation) { Map horsePosition = new HashMap<>(); - List positions = PieceLocation.HORSE.getPositions(camp, elephantFormation); + List positions = InitialPieceLocation.HORSE.getPositions(camp, elephantFormation); positions.forEach(position -> horsePosition.put(position, new Horse(camp))); return horsePosition; } - private Map generateCannon(Camp camp) { + private static Map generateCannon(Camp camp) { Map cannonPosition = new HashMap<>(); - List positions = PieceLocation.CANNON.getPositions(camp); + List positions = InitialPieceLocation.CANNON.getPositions(camp); positions.forEach(position -> cannonPosition.put(position, new Cannon(camp))); return cannonPosition; } - private Map generateElephant(Camp camp, ElephantFormation elephantFormation) { + private static Map generateElephant(Camp camp, ElephantFormation elephantFormation) { Map elephantPosition = new HashMap<>(); - List positions = PieceLocation.ELEPHANT.getPositions(camp, elephantFormation); + List positions = InitialPieceLocation.ELEPHANT.getPositions(camp, elephantFormation); positions.forEach(position -> elephantPosition.put(position, new Elephant(camp))); return elephantPosition; } - private Map generateChariot(Camp camp) { + private static Map generateChariot(Camp camp) { Map chariotPosition = new HashMap<>(); - List positions = PieceLocation.CHARIOT.getPositions(camp); + List positions = InitialPieceLocation.CHARIOT.getPositions(camp); positions.forEach(position -> chariotPosition.put(position, new Chariot(camp))); return chariotPosition; diff --git a/src/test/java/PieceGeneratorTest.java b/src/test/java/PieceGeneratorTest.java index 4719dda3c6..a22240782d 100644 --- a/src/test/java/PieceGeneratorTest.java +++ b/src/test/java/PieceGeneratorTest.java @@ -5,38 +5,30 @@ import domain.pieces.Elephant; import domain.pieces.Horse; import domain.pieces.Piece; -import java.util.Map; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.Map; + public class PieceGeneratorTest { @Test void 한나라_말_16개_생성() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.HAN, - ElephantFormation.RIGHT); + Map board = PieceGenerator.generatePieces(Camp.HAN, ElephantFormation.RIGHT); Assertions.assertEquals(board.size(), 16); } @Test void 초나라_말_16개_생성() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.CHO, - ElephantFormation.RIGHT); + Map board = PieceGenerator.generatePieces(Camp.CHO, ElephantFormation.RIGHT); Assertions.assertEquals(board.size(), 16); } @Test void 한나라_오른상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.HAN, - ElephantFormation.RIGHT); + Map board = PieceGenerator.generatePieces(Camp.HAN, ElephantFormation.RIGHT); Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Elephant.class); Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); @@ -46,10 +38,7 @@ public class PieceGeneratorTest { @Test void 한나라_왼상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.HAN, - ElephantFormation.LEFT); + Map board = PieceGenerator.generatePieces(Camp.HAN, ElephantFormation.LEFT); Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Horse.class); Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); @@ -59,10 +48,7 @@ public class PieceGeneratorTest { @Test void 한나라_안상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.HAN, - ElephantFormation.INNER); + Map board = PieceGenerator.generatePieces(Camp.HAN, ElephantFormation.INNER); Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Horse.class); Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Elephant.class); @@ -72,10 +58,7 @@ public class PieceGeneratorTest { @Test void 한나라_바깥상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.HAN, - ElephantFormation.OUTER); + Map board = PieceGenerator.generatePieces(Camp.HAN, ElephantFormation.OUTER); Assertions.assertEquals(board.get(new Position(1, 0)).getClass(), Elephant.class); Assertions.assertEquals(board.get(new Position(2, 0)).getClass(), Horse.class); @@ -86,10 +69,7 @@ public class PieceGeneratorTest { @Test void 초나라_오른상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.CHO, - ElephantFormation.RIGHT); + Map board = PieceGenerator.generatePieces(Camp.CHO, ElephantFormation.RIGHT); Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Horse.class); Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Elephant.class); @@ -99,10 +79,7 @@ public class PieceGeneratorTest { @Test void 초나라_왼상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.CHO, - ElephantFormation.LEFT); + Map board = PieceGenerator.generatePieces(Camp.CHO, ElephantFormation.LEFT); Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Elephant.class); Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Horse.class); @@ -112,10 +89,7 @@ public class PieceGeneratorTest { @Test void 초나라_안상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.CHO, - ElephantFormation.INNER); + Map board = PieceGenerator.generatePieces(Camp.CHO, ElephantFormation.INNER); Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Horse.class); Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Elephant.class); @@ -125,10 +99,7 @@ public class PieceGeneratorTest { @Test void 초나라_바깥상차림() { - PieceGenerator pieceGenerator = new PieceGenerator(); - - Map board = pieceGenerator.generatePieces(Camp.CHO, - ElephantFormation.OUTER); + Map board = PieceGenerator.generatePieces(Camp.CHO, ElephantFormation.OUTER); Assertions.assertEquals(board.get(new Position(1, 9)).getClass(), Elephant.class); Assertions.assertEquals(board.get(new Position(2, 9)).getClass(), Horse.class); From b83bc3f2bbf833539cca40e299dce8259edc6df3 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Thu, 2 Apr 2026 09:50:16 +0900 Subject: [PATCH 37/40] =?UTF-8?q?refactor:=20view=EC=97=90=EC=84=9C=20Elep?= =?UTF-8?q?hantFormation=20=EC=88=9C=EC=84=9C=20=EC=B6=9C=EB=A0=A5?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=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/domain/ElephantFormation.java | 14 ++++++-------- src/main/java/view/InputView.java | 12 +++++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/domain/ElephantFormation.java b/src/main/java/domain/ElephantFormation.java index 241b7180b8..3bae02318e 100644 --- a/src/main/java/domain/ElephantFormation.java +++ b/src/main/java/domain/ElephantFormation.java @@ -6,16 +6,14 @@ import java.util.Map; public enum ElephantFormation { - RIGHT(1, initRight()), - INNER(2, initInner()), - LEFT(3, initLeft()), - OUTER(4, initOuter()); + RIGHT(initRight()), + INNER(initInner()), + LEFT(initLeft()), + OUTER(initOuter()); - private final int formationNumber; private final Map>> positions; - ElephantFormation(int formationNumber, Map>> positions) { - this.formationNumber = formationNumber; + ElephantFormation(Map>> positions) { this.positions = positions; } @@ -145,7 +143,7 @@ private static Map>> initOuter() public static ElephantFormation getFormationType(int formationNumber) { return Arrays.stream(ElephantFormation.values()) - .filter(n -> n.formationNumber == formationNumber) + .filter(n -> n.ordinal() == formationNumber) .findFirst() .orElseThrow(() -> new IllegalArgumentException("잘못된 타입 번호입니다." + formationNumber)); } diff --git a/src/main/java/view/InputView.java b/src/main/java/view/InputView.java index 46d80fd834..8e656e45b0 100644 --- a/src/main/java/view/InputView.java +++ b/src/main/java/view/InputView.java @@ -1,7 +1,9 @@ package view; import domain.Camp; +import domain.ElephantFormation; import domain.Position; + import java.util.Arrays; import java.util.Scanner; @@ -40,11 +42,11 @@ private int readElephantFormation(Camp camp) { while (true) { try { System.out.println(camp.getCampName() + " 상 차림을 결정해주세요."); - System.out.println("1. [마 상 마 상]"); - System.out.println("2. [마 상 상 마]"); - System.out.println("3. [상 마 상 마]"); - System.out.println("4. [상 마 마 상]"); - return Integer.parseInt(sc.nextLine()); + System.out.println(ElephantFormation.RIGHT.ordinal() + 1 + ". [마 상 마 상]"); + System.out.println(ElephantFormation.INNER.ordinal() + 1 + ". [마 상 상 마]"); + System.out.println(ElephantFormation.LEFT.ordinal() + 1 + ". [상 마 상 마]"); + System.out.println(ElephantFormation.OUTER.ordinal() + 1 + ". [상 마 마 상]"); + return Integer.parseInt(sc.nextLine()) - 1; } catch (IllegalArgumentException e) { System.out.println(e.getMessage()); } From 0d27ef044f82ea41c9944957cfabc50699d96ad0 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Thu, 2 Apr 2026 11:24:28 +0900 Subject: [PATCH 38/40] refactor: rename ExistBoard to BoardReader --- src/main/java/domain/Board.java | 2 +- .../{ExistBoard.java => BoardReader.java} | 2 +- src/main/java/domain/pieces/Cannon.java | 48 +++++++++---------- src/main/java/domain/pieces/Chariot.java | 28 +++++------ src/main/java/domain/pieces/Elephant.java | 6 +-- src/main/java/domain/pieces/General.java | 4 +- src/main/java/domain/pieces/Guard.java | 4 +- src/main/java/domain/pieces/Horse.java | 6 +-- src/main/java/domain/pieces/Piece.java | 4 +- src/main/java/domain/pieces/Soldier.java | 4 +- 10 files changed, 54 insertions(+), 54 deletions(-) rename src/main/java/domain/{ExistBoard.java => BoardReader.java} (83%) diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java index 3f5def2806..cb9ce27332 100644 --- a/src/main/java/domain/Board.java +++ b/src/main/java/domain/Board.java @@ -8,7 +8,7 @@ import java.util.List; import java.util.Map; -public class Board implements ExistBoard { +public class Board implements BoardReader { private final Map board = new HashMap<>(); diff --git a/src/main/java/domain/ExistBoard.java b/src/main/java/domain/BoardReader.java similarity index 83% rename from src/main/java/domain/ExistBoard.java rename to src/main/java/domain/BoardReader.java index b2bb3f8d01..6b6ffb3202 100644 --- a/src/main/java/domain/ExistBoard.java +++ b/src/main/java/domain/BoardReader.java @@ -2,7 +2,7 @@ import domain.pieces.Piece; -public interface ExistBoard { +public interface BoardReader { boolean isExist(Position position); diff --git a/src/main/java/domain/pieces/Cannon.java b/src/main/java/domain/pieces/Cannon.java index 0fe0759445..a2f6ddd9a6 100644 --- a/src/main/java/domain/pieces/Cannon.java +++ b/src/main/java/domain/pieces/Cannon.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.HashSet; @@ -14,25 +14,25 @@ public Cannon(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Set movablePositions = new HashSet<>(); - movablePositions.addAll(moveUp(from, existBoard)); - movablePositions.addAll(moveLeft(from, existBoard)); - movablePositions.addAll(moveRight(from, existBoard)); - movablePositions.addAll(moveDown(from, existBoard)); + movablePositions.addAll(moveUp(from, boardReader)); + movablePositions.addAll(moveLeft(from, boardReader)); + movablePositions.addAll(moveRight(from, boardReader)); + movablePositions.addAll(moveDown(from, boardReader)); return movablePositions.contains(to); } - private Set moveRight(Position position, ExistBoard existBoard) { + private Set moveRight(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); boolean jumping = false; try { while (!jumping) { position = right(position); - jumping = checkCannonJumping(position, existBoard); + jumping = checkCannonJumping(position, boardReader); } } catch (IllegalArgumentException e) { @@ -41,10 +41,10 @@ private Set moveRight(Position position, ExistBoard existBoard) { try { do { position = right(position); - if (existBoard.isDifferentPieceType(position, this)) { + if (boardReader.isDifferentPieceType(position, this)) { movablePositions.add(position); } - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } @@ -52,14 +52,14 @@ private Set moveRight(Position position, ExistBoard existBoard) { return movablePositions; } - private Set moveLeft(Position position, ExistBoard existBoard) { + private Set moveLeft(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); boolean jumping = false; try { while (!jumping) { position = left(position); - jumping = checkCannonJumping(position, existBoard); + jumping = checkCannonJumping(position, boardReader); } } catch (IllegalArgumentException e) { @@ -68,10 +68,10 @@ private Set moveLeft(Position position, ExistBoard existBoard) { try { do { position = left(position); - if (existBoard.isDifferentPieceType(position, this)) { + if (boardReader.isDifferentPieceType(position, this)) { movablePositions.add(position); } - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } @@ -79,14 +79,14 @@ private Set moveLeft(Position position, ExistBoard existBoard) { return movablePositions; } - private Set moveUp(Position position, ExistBoard existBoard) { + private Set moveUp(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); boolean jumping = false; try { while (!jumping) { position = up(position); - jumping = checkCannonJumping(position, existBoard); + jumping = checkCannonJumping(position, boardReader); } } catch (IllegalArgumentException e) { @@ -95,10 +95,10 @@ private Set moveUp(Position position, ExistBoard existBoard) { try { do { position = up(position); - if (existBoard.isDifferentPieceType(position, this)) { + if (boardReader.isDifferentPieceType(position, this)) { movablePositions.add(position); } - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } @@ -106,14 +106,14 @@ private Set moveUp(Position position, ExistBoard existBoard) { return movablePositions; } - private Set moveDown(Position position, ExistBoard existBoard) { + private Set moveDown(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); boolean jumping = false; try { while (!jumping) { position = down(position); - jumping = checkCannonJumping(position, existBoard); + jumping = checkCannonJumping(position, boardReader); } } catch (IllegalArgumentException e) { @@ -122,10 +122,10 @@ private Set moveDown(Position position, ExistBoard existBoard) { try { do { position = down(position); - if (existBoard.isDifferentPieceType(position, this)) { + if (boardReader.isDifferentPieceType(position, this)) { movablePositions.add(position); } - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } @@ -133,7 +133,7 @@ private Set moveDown(Position position, ExistBoard existBoard) { return movablePositions; } - private boolean checkCannonJumping(Position position, ExistBoard existBoard) { - return existBoard.isExist(position) && existBoard.isDifferentPieceType(position, this); + private boolean checkCannonJumping(Position position, BoardReader boardReader) { + return boardReader.isExist(position) && boardReader.isDifferentPieceType(position, this); } } diff --git a/src/main/java/domain/pieces/Chariot.java b/src/main/java/domain/pieces/Chariot.java index 111d1a2f4f..9beae0aced 100644 --- a/src/main/java/domain/pieces/Chariot.java +++ b/src/main/java/domain/pieces/Chariot.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.HashSet; @@ -14,63 +14,63 @@ public Chariot(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Set movablePositions = new HashSet<>(); - movablePositions.addAll(moveUp(from, existBoard)); - movablePositions.addAll(moveDown(from, existBoard)); - movablePositions.addAll(moveLeft(from, existBoard)); - movablePositions.addAll(moveRight(from, existBoard)); + movablePositions.addAll(moveUp(from, boardReader)); + movablePositions.addAll(moveDown(from, boardReader)); + movablePositions.addAll(moveLeft(from, boardReader)); + movablePositions.addAll(moveRight(from, boardReader)); return movablePositions.contains(to); } - private Set moveUp(Position position, ExistBoard existBoard) { + private Set moveUp(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); try { do { position = up(position); movablePositions.add(position); - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } return movablePositions; } - private Set moveLeft(Position position, ExistBoard existBoard) { + private Set moveLeft(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); try { do { position = left(position); movablePositions.add(position); - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } return movablePositions; } - private Set moveRight(Position position, ExistBoard existBoard) { + private Set moveRight(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); try { do { position = right(position); movablePositions.add(position); - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } return movablePositions; } - private Set moveDown(Position position, ExistBoard existBoard) { + private Set moveDown(Position position, BoardReader boardReader) { Set movablePositions = new HashSet<>(); try { do { position = down(position); movablePositions.add(position); - } while (!existBoard.isExist(position)); + } while (!boardReader.isExist(position)); } catch (IllegalArgumentException e) { } diff --git a/src/main/java/domain/pieces/Elephant.java b/src/main/java/domain/pieces/Elephant.java index 6434305914..53c561029e 100644 --- a/src/main/java/domain/pieces/Elephant.java +++ b/src/main/java/domain/pieces/Elephant.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.ArrayList; @@ -16,7 +16,7 @@ public Elephant(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Map> routeOfDestination = new HashMap<>(); routeOfDestination.putAll(move_U_RU(from)); @@ -34,7 +34,7 @@ public boolean canMove(Position from, Position to, ExistBoard existBoard) { List route = routeOfDestination.get(to); for (Position position : route) { - if (existBoard.isExist(position)) { + if (boardReader.isExist(position)) { return false; } } diff --git a/src/main/java/domain/pieces/General.java b/src/main/java/domain/pieces/General.java index 963da22782..c2981e5bce 100644 --- a/src/main/java/domain/pieces/General.java +++ b/src/main/java/domain/pieces/General.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.HashSet; @@ -14,7 +14,7 @@ public General(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Set destination = new HashSet<>(); diff --git a/src/main/java/domain/pieces/Guard.java b/src/main/java/domain/pieces/Guard.java index 0e0d2dd5db..7b3e11a172 100644 --- a/src/main/java/domain/pieces/Guard.java +++ b/src/main/java/domain/pieces/Guard.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.HashSet; @@ -14,7 +14,7 @@ public Guard(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Set destination = new HashSet<>(); diff --git a/src/main/java/domain/pieces/Horse.java b/src/main/java/domain/pieces/Horse.java index ba724d3e57..e168a05a37 100644 --- a/src/main/java/domain/pieces/Horse.java +++ b/src/main/java/domain/pieces/Horse.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.ArrayList; @@ -16,7 +16,7 @@ public Horse(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Map> routeOfDestination = new HashMap<>(); routeOfDestination.putAll(move_U_RU(from)); @@ -34,7 +34,7 @@ public boolean canMove(Position from, Position to, ExistBoard existBoard) { List route = routeOfDestination.get(to); for (Position position : route) { - if (existBoard.isExist(position)) { + if (boardReader.isExist(position)) { return false; } } diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 9abe30a2ed..4095652910 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; @@ -75,7 +75,7 @@ Position rightDownDiagonal(Position position) { return new Position(++x, ++y); } - public abstract boolean canMove(Position from, Position to, ExistBoard existBoard); + public abstract boolean canMove(Position from, Position to, BoardReader boardReader); public PieceType getPieceType() { return this.pieceType; diff --git a/src/main/java/domain/pieces/Soldier.java b/src/main/java/domain/pieces/Soldier.java index c0a1bed8e5..6ad0757ab4 100644 --- a/src/main/java/domain/pieces/Soldier.java +++ b/src/main/java/domain/pieces/Soldier.java @@ -1,7 +1,7 @@ package domain.pieces; import domain.Camp; -import domain.ExistBoard; +import domain.BoardReader; import domain.PieceType; import domain.Position; import java.util.HashSet; @@ -14,7 +14,7 @@ public Soldier(Camp camp) { } @Override - public boolean canMove(Position from, Position to, ExistBoard existBoard) { + public boolean canMove(Position from, Position to, BoardReader boardReader) { Set destination = new HashSet<>(); From 07fcc4bd2e0de19a3a933dfd4f5762cb2ddc0e82 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Fri, 3 Apr 2026 15:52:30 +0900 Subject: [PATCH 39/40] =?UTF-8?q?feat(Route):=20=EB=B0=A9=ED=96=A5?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20position=20=EA=B3=84=EC=82=B0?= =?UTF-8?q?=ED=95=98=EC=97=AC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20rou?= =?UTF-8?q?te=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/domain/Direction.java | 28 ++++++++++++++++++++++++++ src/main/java/domain/pieces/Route.java | 21 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 src/main/java/domain/Direction.java create mode 100644 src/main/java/domain/pieces/Route.java diff --git a/src/main/java/domain/Direction.java b/src/main/java/domain/Direction.java new file mode 100644 index 0000000000..5852851c8e --- /dev/null +++ b/src/main/java/domain/Direction.java @@ -0,0 +1,28 @@ +package domain; + +public enum Direction { + NORTH(0, -1), + NORTHEAST(1, -1), + EAST(1, 0), + SOUTHEAST(1, 1), + SOUTH(0,1), + SOUTHWEST(-1, 1), + WEST(-1, 0), + NORTHWEST(-1, -1); + + private final int x; + private final int y; + + Direction(int x, int y) { + this.x = x; + this.y = y; + } + + public int getDx() { + return x; + } + + public int getDy() { + return y; + } +} diff --git a/src/main/java/domain/pieces/Route.java b/src/main/java/domain/pieces/Route.java new file mode 100644 index 0000000000..0a48852556 --- /dev/null +++ b/src/main/java/domain/pieces/Route.java @@ -0,0 +1,21 @@ +package domain.pieces; + +import domain.Direction; +import domain.Position; + +import java.util.ArrayList; +import java.util.List; + +public class Route { + public static List path(Position position, List directions) { + List path = new ArrayList<>(); + for (Direction direction : directions) { + if(position.canMove(direction)) { + position = position.move(direction); + } + path.add(position); + } + + return path; + } +} From 457dcc49278e431dfb18c6288ad075e6bf064f35 Mon Sep 17 00:00:00 2001 From: CHOSEONGHYEON Date: Fri, 3 Apr 2026 15:55:30 +0900 Subject: [PATCH 40/40] =?UTF-8?q?refactor:=20=EA=B0=81=20=EA=B8=B0?= =?UTF-8?q?=EB=AC=BC=EB=93=A4=20canMove=20=EB=82=B4=EB=B6=80=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20=EB=B3=80=EA=B2=BD=20=EA=B0=81=20=EA=B8=B0=EB=AC=BC?= =?UTF-8?q?=EB=93=A4=EC=9D=80=20=EC=9D=B4=EB=8F=99=20=EA=B7=9C=EC=B9=99?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20Direction=EC=9D=84=20=EA=B0=80?= =?UTF-8?q?=EC=A7=80=EA=B3=A0=EC=9E=88=EB=8B=A4.=20route=EC=97=90=EC=84=9C?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99=20position=EC=9D=84=20=EA=B3=84=EC=82=B0?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/domain/Position.java | 13 +- src/main/java/domain/pieces/Cannon.java | 147 +++---------- src/main/java/domain/pieces/Chariot.java | 85 ++------ src/main/java/domain/pieces/Elephant.java | 204 ++---------------- src/main/java/domain/pieces/General.java | 87 +------- src/main/java/domain/pieces/Guard.java | 87 +------- src/main/java/domain/pieces/Horse.java | 171 ++------------- src/main/java/domain/pieces/Piece.java | 50 +---- .../java/domain/pieces/SingleStepPiece.java | 35 +++ src/main/java/domain/pieces/Soldier.java | 68 ++---- 10 files changed, 168 insertions(+), 779 deletions(-) create mode 100644 src/main/java/domain/pieces/SingleStepPiece.java diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index a6ff8bf9b6..55b889f16e 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -19,12 +19,17 @@ public Position(int x, int y) { this.y = y; } - public int getX() { - return x; + public boolean canMove(Direction direction) { + int dx = direction.getDx(); + int dy = direction.getDy(); + return ((MIN_X_VALUE <= x + dx && x + dx <= MAX_X_VALUE) + && (MIN_Y_VALUE <= y + dy && y + dy <= MAX_Y_VALUE)); } - public int getY() { - return y; + public Position move(Direction direction) { + int dx = direction.getDx(); + int dy = direction.getDy(); + return new Position(x + dx, y + dy); } private void validatePosX(int x) { diff --git a/src/main/java/domain/pieces/Cannon.java b/src/main/java/domain/pieces/Cannon.java index a2f6ddd9a6..1fdbc09129 100644 --- a/src/main/java/domain/pieces/Cannon.java +++ b/src/main/java/domain/pieces/Cannon.java @@ -1,13 +1,14 @@ package domain.pieces; -import domain.Camp; -import domain.BoardReader; -import domain.PieceType; -import domain.Position; -import java.util.HashSet; -import java.util.Set; +import domain.*; + +import java.util.List; +import java.util.Optional; public class Cannon extends Piece { + private final List linearDirections = List.of( + Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST + ); public Cannon(Camp camp) { super(camp, PieceType.CANNON); @@ -15,125 +16,47 @@ public Cannon(Camp camp) { @Override public boolean canMove(Position from, Position to, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - - movablePositions.addAll(moveUp(from, boardReader)); - movablePositions.addAll(moveLeft(from, boardReader)); - movablePositions.addAll(moveRight(from, boardReader)); - movablePositions.addAll(moveDown(from, boardReader)); - - return movablePositions.contains(to); - } - - private Set moveRight(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - boolean jumping = false; - - try { - while (!jumping) { - position = right(position); - jumping = checkCannonJumping(position, boardReader); + for (Direction direction : linearDirections) { + if (canJumpToTarget(from, to, boardReader, direction)) { + return true; } - } catch (IllegalArgumentException e) { - } - - try { - do { - position = right(position); - if (boardReader.isDifferentPieceType(position, this)) { - movablePositions.add(position); - } - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - - } - - return movablePositions; + return false; } - private Set moveLeft(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - boolean jumping = false; - - try { - while (!jumping) { - position = left(position); - jumping = checkCannonJumping(position, boardReader); - } - } catch (IllegalArgumentException e) { - - } - - try { - do { - position = left(position); - if (boardReader.isDifferentPieceType(position, this)) { - movablePositions.add(position); - } - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - + private boolean canJumpToTarget(Position from, Position to, BoardReader boardReader, Direction direction) { + Optional bridge = findBridge(from, direction, boardReader); + if (bridge.isEmpty()) { + return false; } - return movablePositions; + return checkAfterBridge(bridge.get(), to, boardReader, direction); } - private Set moveUp(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - boolean jumping = false; - - try { - while (!jumping) { - position = up(position); - jumping = checkCannonJumping(position, boardReader); + private Optional findBridge(Position current, Direction direction, BoardReader boardReader) { + while (current.canMove(direction)) { + current = current.move(direction); + if (boardReader.isExist(current) && boardReader.isDifferentPieceType(current, this)) { + return Optional.of(current); + } + if (boardReader.isExist(current)) { + break; } - } catch (IllegalArgumentException e) { - - } - - try { - do { - position = up(position); - if (boardReader.isDifferentPieceType(position, this)) { - movablePositions.add(position); - } - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - } - - return movablePositions; + return Optional.empty(); } - private Set moveDown(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - boolean jumping = false; - - try { - while (!jumping) { - position = down(position); - jumping = checkCannonJumping(position, boardReader); + private boolean checkAfterBridge(Position bridge, Position to, BoardReader boardReader, Direction direction) { + Position current = bridge; + while (current.canMove(direction)) { + current = current.move(direction); + if (current.equals(to)) { + return boardReader.isDifferentPieceType(to, this); + } + if (boardReader.isExist(current)) { + break; } - } catch (IllegalArgumentException e) { - - } - - try { - do { - position = down(position); - if (boardReader.isDifferentPieceType(position, this)) { - movablePositions.add(position); - } - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - } - - return movablePositions; - } - - private boolean checkCannonJumping(Position position, BoardReader boardReader) { - return boardReader.isExist(position) && boardReader.isDifferentPieceType(position, this); + return false; } } diff --git a/src/main/java/domain/pieces/Chariot.java b/src/main/java/domain/pieces/Chariot.java index 9beae0aced..2843657b29 100644 --- a/src/main/java/domain/pieces/Chariot.java +++ b/src/main/java/domain/pieces/Chariot.java @@ -1,13 +1,13 @@ package domain.pieces; -import domain.Camp; -import domain.BoardReader; -import domain.PieceType; -import domain.Position; -import java.util.HashSet; -import java.util.Set; +import domain.*; + +import java.util.List; public class Chariot extends Piece { + private final List linearDirections = List.of( + Direction.NORTH, Direction.SOUTH, Direction.EAST, Direction.WEST + ); public Chariot(Camp camp) { super(camp, PieceType.CHARIOT); @@ -15,65 +15,26 @@ public Chariot(Camp camp) { @Override public boolean canMove(Position from, Position to, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - - movablePositions.addAll(moveUp(from, boardReader)); - movablePositions.addAll(moveDown(from, boardReader)); - movablePositions.addAll(moveLeft(from, boardReader)); - movablePositions.addAll(moveRight(from, boardReader)); - - return movablePositions.contains(to); - } - - private Set moveUp(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - try { - do { - position = up(position); - movablePositions.add(position); - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - + for (Direction direction : linearDirections) { + if (canReachTarget(from, to, boardReader, direction)) { + return true; + } } - return movablePositions; + return false; } - private Set moveLeft(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - try { - do { - position = left(position); - movablePositions.add(position); - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - - } - return movablePositions; - } - - private Set moveRight(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - try { - do { - position = right(position); - movablePositions.add(position); - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - - } - return movablePositions; - } - - private Set moveDown(Position position, BoardReader boardReader) { - Set movablePositions = new HashSet<>(); - try { - do { - position = down(position); - movablePositions.add(position); - } while (!boardReader.isExist(position)); - } catch (IllegalArgumentException e) { - + private boolean canReachTarget(Position from, Position to, BoardReader boardReader, Direction direction) { + Position current = from; + while (current.canMove(direction)) { + current = current.move(direction); + if (current.equals(to)) { + return true; + } + + if (boardReader.isExist(current)) { + break; + } } - return movablePositions; + return false; } } diff --git a/src/main/java/domain/pieces/Elephant.java b/src/main/java/domain/pieces/Elephant.java index 53c561029e..d0abf727b9 100644 --- a/src/main/java/domain/pieces/Elephant.java +++ b/src/main/java/domain/pieces/Elephant.java @@ -1,15 +1,20 @@ package domain.pieces; -import domain.Camp; -import domain.BoardReader; -import domain.PieceType; -import domain.Position; -import java.util.ArrayList; -import java.util.HashMap; +import domain.*; + import java.util.List; -import java.util.Map; public class Elephant extends Piece { + private final List> elephantDirections = List.of( + List.of(Direction.NORTH, Direction.NORTHEAST, Direction.NORTHEAST), + List.of(Direction.NORTH, Direction.NORTHWEST, Direction.NORTHWEST), + List.of(Direction.SOUTH, Direction.SOUTHEAST, Direction.SOUTHEAST), + List.of(Direction.SOUTH, Direction.SOUTHWEST, Direction.SOUTHWEST), + List.of(Direction.EAST, Direction.NORTHEAST, Direction.NORTHEAST), + List.of(Direction.EAST, Direction.SOUTHEAST, Direction.SOUTHEAST), + List.of(Direction.WEST, Direction.NORTHWEST, Direction.NORTHWEST), + List.of(Direction.WEST, Direction.SOUTHWEST, Direction.SOUTHWEST) + ); public Elephant(Camp camp) { super(camp, PieceType.ELEPHANT); @@ -17,186 +22,21 @@ public Elephant(Camp camp) { @Override public boolean canMove(Position from, Position to, BoardReader boardReader) { - Map> routeOfDestination = new HashMap<>(); - - routeOfDestination.putAll(move_U_RU(from)); - routeOfDestination.putAll(move_U_LU(from)); - routeOfDestination.putAll(move_D_RD(from)); - routeOfDestination.putAll(move_D_LD(from)); - routeOfDestination.putAll(move_R_RU(from)); - routeOfDestination.putAll(move_R_RD(from)); - routeOfDestination.putAll(move_L_LU(from)); - routeOfDestination.putAll(move_L_LD(from)); - - if (!routeOfDestination.containsKey(to)) { - return false; + for (List directions : elephantDirections) { + List path = Route.path(from, directions); + if (path.size() == 3 && path.getLast().equals(to)) { + return checkPositionExist(boardReader, path); + } } + return false; + } - List route = routeOfDestination.get(to); - for (Position position : route) { - if (boardReader.isExist(position)) { + private static boolean checkPositionExist(BoardReader boardReader, List path) { + for (int i = 0; i < path.size() - 1; i++) { + if (boardReader.isExist(path.get(i))) { return false; } } - return true; } - - private Map> move_U_RU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = up(position); - route.add(position); - - position = rightUpDiagonal(position); - route.add(position); - - position = rightUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_U_LU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = up(position); - route.add(position); - - position = leftUpDiagonal(position); - route.add(position); - - position = leftUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } - - private Map> move_D_RD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = down(position); - route.add(position); - - position = rightDownDiagonal(position); - route.add(position); - - position = rightDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_D_LD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = down(position); - route.add(position); - - position = leftDownDiagonal(position); - route.add(position); - - position = leftDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } - - private Map> move_R_RU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = right(position); - route.add(position); - - position = rightUpDiagonal(position); - route.add(position); - - position = rightUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } - - private Map> move_R_RD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = right(position); - route.add(position); - - position = rightDownDiagonal(position); - route.add(position); - - position = rightDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } - - private Map> move_L_LU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = left(position); - route.add(position); - - position = leftUpDiagonal(position); - route.add(position); - - position = leftUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } - - private Map> move_L_LD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = left(position); - route.add(position); - - position = leftDownDiagonal(position); - route.add(position); - - position = leftDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } } diff --git a/src/main/java/domain/pieces/General.java b/src/main/java/domain/pieces/General.java index c2981e5bce..7919858887 100644 --- a/src/main/java/domain/pieces/General.java +++ b/src/main/java/domain/pieces/General.java @@ -1,96 +1,11 @@ package domain.pieces; import domain.Camp; -import domain.BoardReader; import domain.PieceType; -import domain.Position; -import java.util.HashSet; -import java.util.Set; -public class General extends Piece { +public class General extends SingleStepPiece { public General(Camp camp) { super(camp, PieceType.GENERAL); } - - @Override - public boolean canMove(Position from, Position to, BoardReader boardReader) { - - Set destination = new HashSet<>(); - - destination.add(move_L(from)); - destination.add(move_R(from)); - destination.add(move_D(from)); - destination.add(move_U(from)); - destination.add(move_RU(from)); - destination.add(move_RD(from)); - destination.add(move_LU(from)); - destination.add(move_LD(from)); - - return destination.contains(to); - } - - private Position move_U(Position position) { - try { - return up(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_L(Position position) { - try { - return left(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_R(Position position) { - try { - return right(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_D(Position position) { - try { - return down(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_RU(Position position) { - try { - return rightUpDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_RD(Position position) { - try { - return rightDownDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_LU(Position position) { - try { - return leftUpDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_LD(Position position) { - try { - return leftDownDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } } diff --git a/src/main/java/domain/pieces/Guard.java b/src/main/java/domain/pieces/Guard.java index 7b3e11a172..d2a10fedd5 100644 --- a/src/main/java/domain/pieces/Guard.java +++ b/src/main/java/domain/pieces/Guard.java @@ -1,96 +1,11 @@ package domain.pieces; import domain.Camp; -import domain.BoardReader; import domain.PieceType; -import domain.Position; -import java.util.HashSet; -import java.util.Set; -public class Guard extends Piece { +public class Guard extends SingleStepPiece { public Guard(Camp camp) { super(camp, PieceType.GUARD); } - - @Override - public boolean canMove(Position from, Position to, BoardReader boardReader) { - - Set destination = new HashSet<>(); - - destination.add(move_L(from)); - destination.add(move_R(from)); - destination.add(move_D(from)); - destination.add(move_U(from)); - destination.add(move_RU(from)); - destination.add(move_RD(from)); - destination.add(move_LU(from)); - destination.add(move_LD(from)); - - return destination.contains(to); - } - - private Position move_U(Position position) { - try { - return up(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_L(Position position) { - try { - return left(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_R(Position position) { - try { - return right(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_D(Position position) { - try { - return down(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_RU(Position position) { - try { - return rightUpDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_RD(Position position) { - try { - return rightDownDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_LU(Position position) { - try { - return leftUpDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } - - private Position move_LD(Position position) { - try { - return leftDownDiagonal(position); - } catch (IllegalArgumentException e) { - return position; - } - } } diff --git a/src/main/java/domain/pieces/Horse.java b/src/main/java/domain/pieces/Horse.java index e168a05a37..47481c61e6 100644 --- a/src/main/java/domain/pieces/Horse.java +++ b/src/main/java/domain/pieces/Horse.java @@ -1,15 +1,16 @@ package domain.pieces; -import domain.Camp; -import domain.BoardReader; -import domain.PieceType; -import domain.Position; -import java.util.ArrayList; -import java.util.HashMap; +import domain.*; + import java.util.List; -import java.util.Map; public class Horse extends Piece { + private final List> horseDirections = List.of( + List.of(Direction.NORTH, Direction.NORTHEAST), List.of(Direction.NORTH, Direction.NORTHWEST), + List.of(Direction.SOUTH, Direction.SOUTHEAST), List.of(Direction.SOUTH, Direction.SOUTHWEST), + List.of(Direction.EAST, Direction.NORTHEAST), List.of(Direction.EAST, Direction.SOUTHEAST), + List.of(Direction.WEST, Direction.NORTHWEST), List.of(Direction.WEST, Direction.SOUTHWEST) + ); public Horse(Camp camp) { super(camp, PieceType.HORSE); @@ -17,157 +18,21 @@ public Horse(Camp camp) { @Override public boolean canMove(Position from, Position to, BoardReader boardReader) { - Map> routeOfDestination = new HashMap<>(); - - routeOfDestination.putAll(move_U_RU(from)); - routeOfDestination.putAll(move_U_LU(from)); - routeOfDestination.putAll(move_R_RU(from)); - routeOfDestination.putAll(move_R_RD(from)); - routeOfDestination.putAll(move_L_LU(from)); - routeOfDestination.putAll(move_L_LD(from)); - routeOfDestination.putAll(move_D_RD(from)); - routeOfDestination.putAll(move_D_LD(from)); - - if (!routeOfDestination.containsKey(to)) { - return false; + for (List directions : horseDirections) { + List path = Route.path(from, directions); + if (path.size() == 2 && path.getLast().equals(to)) { + return checkPositionExist(boardReader, path); + } } + return false; + } - List route = routeOfDestination.get(to); - for (Position position : route) { - if (boardReader.isExist(position)) { + private static boolean checkPositionExist(BoardReader boardReader, List path) { + for (int i = 0; i < path.size() - 1; i++) { + if (boardReader.isExist(path.get(i))) { return false; } } - return true; } - - private Map> move_U_RU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = up(position); - route.add(position); - - position = rightUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - - return routeOfDestination; - } - - private Map> move_U_LU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = up(position); - route.add(position); - - position = leftUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_R_RU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = right(position); - route.add(position); - - position = rightUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_R_RD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = right(position); - route.add(position); - - position = rightDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_L_LU(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = left(position); - route.add(position); - - position = leftUpDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_L_LD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = left(position); - route.add(position); - - position = leftDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_D_RD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = down(position); - route.add(position); - - position = rightDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } - - private Map> move_D_LD(Position position) { - Map> routeOfDestination = new HashMap<>(); - List route = new ArrayList<>(); - try { - position = down(position); - route.add(position); - - position = leftDownDiagonal(position); - - routeOfDestination.put(position, route); - } catch (IllegalArgumentException e) { - // 생성할 수 없는 Position이면 무시 - } - return routeOfDestination; - } } diff --git a/src/main/java/domain/pieces/Piece.java b/src/main/java/domain/pieces/Piece.java index 4095652910..077fe4f3f2 100644 --- a/src/main/java/domain/pieces/Piece.java +++ b/src/main/java/domain/pieces/Piece.java @@ -1,7 +1,7 @@ package domain.pieces; -import domain.Camp; import domain.BoardReader; +import domain.Camp; import domain.PieceType; import domain.Position; @@ -27,54 +27,6 @@ public boolean isDifferentPieceType(Piece piece) { return this.getPieceType()!= piece.getPieceType(); } - Position up(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(x, --y); - } - - Position down(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(x, ++y); - } - - Position left(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(--x, y); - } - - Position right(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(++x, y); - } - - Position leftUpDiagonal(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(--x, --y); - } - - Position rightUpDiagonal(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(++x, --y); - } - - Position leftDownDiagonal(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(--x, ++y); - } - - Position rightDownDiagonal(Position position) { - int x = position.getX(); - int y = position.getY(); - return new Position(++x, ++y); - } - public abstract boolean canMove(Position from, Position to, BoardReader boardReader); public PieceType getPieceType() { diff --git a/src/main/java/domain/pieces/SingleStepPiece.java b/src/main/java/domain/pieces/SingleStepPiece.java new file mode 100644 index 0000000000..632851ea81 --- /dev/null +++ b/src/main/java/domain/pieces/SingleStepPiece.java @@ -0,0 +1,35 @@ +package domain.pieces; + +import domain.*; + +import java.util.List; + +public class SingleStepPiece extends Piece { + + private final List singleStepDirections = List.of( + Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, + Direction.NORTHWEST, Direction.NORTHEAST, Direction.SOUTHWEST, Direction.SOUTHEAST + ); + + public SingleStepPiece(Camp camp, PieceType pieceType) { + super(camp, pieceType); + } + + @Override + public boolean canMove(Position from, Position to, BoardReader boardReader) { + for (Direction direction : singleStepDirections) { + if (isTargetPosition(from, to, direction)) { + return true; + } + } + return false; + } + + private static boolean isTargetPosition(Position from, Position to, Direction direction) { + if (!from.canMove(direction)) { + return false; + } + + return from.move(direction).equals(to); + } +} diff --git a/src/main/java/domain/pieces/Soldier.java b/src/main/java/domain/pieces/Soldier.java index 6ad0757ab4..8153c9c7a1 100644 --- a/src/main/java/domain/pieces/Soldier.java +++ b/src/main/java/domain/pieces/Soldier.java @@ -1,11 +1,9 @@ package domain.pieces; -import domain.Camp; -import domain.BoardReader; -import domain.PieceType; -import domain.Position; -import java.util.HashSet; -import java.util.Set; +import domain.*; + +import java.util.ArrayList; +import java.util.List; public class Soldier extends Piece { @@ -15,52 +13,32 @@ public Soldier(Camp camp) { @Override public boolean canMove(Position from, Position to, BoardReader boardReader) { + List> soliderDirections = initSoliderDirections(); - Set destination = new HashSet<>(); - - destination.add(move_L(from)); - destination.add(move_R(from)); - - if (this.isSameCamp(Camp.HAN)) { - destination.add(move_D(from)); - } - - if (this.isSameCamp(Camp.CHO)) { - destination.add(move_U(from)); - } - - return destination.contains(to); - } - - private Position move_U(Position position) { - try { - return up(position); - } catch (IllegalArgumentException e) { - return position; + for (List directions : soliderDirections) { + List path = Route.path(from, directions); + if (path.size() == 1 && path.getLast().equals(to)) { + return true; + } } + return false; } - private Position move_L(Position position) { - try { - return left(position); - } catch (IllegalArgumentException e) { - return position; + private List> initSoliderDirections() { + List> soliderDirections = new ArrayList<>( + List.of( + List.of(Direction.WEST), + List.of(Direction.EAST) + ) + ); + if(this.isSameCamp(Camp.CHO)) { + soliderDirections.add(List.of(Direction.NORTH)); } - } - private Position move_R(Position position) { - try { - return right(position); - } catch (IllegalArgumentException e) { - return position; + if (this.isSameCamp(Camp.HAN)) { + soliderDirections.add(List.of(Direction.SOUTH)); } - } - private Position move_D(Position position) { - try { - return down(position); - } catch (IllegalArgumentException e) { - return position; - } + return soliderDirections; } }