From 2c15f8e06224bd75366c2e6acf2365f3080de54a Mon Sep 17 00:00:00 2001 From: originalchaltteokcookie Date: Wed, 25 Mar 2026 13:54:03 +0900 Subject: [PATCH 01/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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/27] =?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. [상 마 상 마]");