From a0056c37230ae5c62b909a0c906a81a9437404e3 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 13:48:09 +0900 Subject: [PATCH 01/15] =?UTF-8?q?docs(README):=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=9A=94=EA=B5=AC=EC=82=AC=ED=95=AD=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index 8102f91c870..2b51975b347 100644 --- a/README.md +++ b/README.md @@ -5,3 +5,47 @@ ## 우아한테크코스 코드리뷰 - [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md) + +## 기존 코드 + +Column +A: 가장 왼쪽 +H: 가장 오른쪽 + +Row +EIGHT: 가장 위 +ONE: 가장 아래 + +Position +말의 움직임 가능 여부 확인 및 움직임 + +## 장기말 + +공통 내용 +- [ ] 각 말은 팀(Color)를 가지고 있다. +- [ ] 도착지에 같은 팀이 있다면 이동할 수 없다. +- [ ] 장기판 말 밖으로 이동할 수 없다. + +비숍 +- [ ] 대각선 원하는만큼 +- [ ] 뛰어넘기 불가 + +왕 +- [ ] 상하좌우 + 대각선 + +나이트 +- [ ] 상하좌우 한 칸 + 진행 방향으로 대각선 한 칸 +- [ ] 뛰어넘기 가능 + +폰 +- [ ] 각 팀마다 진행방향으로 한칸 혹은 두 칸 +- [ ] 상대편 말을 잡을 경우 대각선 이동 가능 + +퀸 +- [ ] 상하좌우 원하는 만큼 +- [ ] 대각선 원하는 만큼 +- [ ] 뛰어넘기 불가 + +룩 +- [ ] 상하좌우 원하는 만큼 +- [ ] 뛰어넘기 불가 From ba94eb7f0eb7593caeea3f93ea27e40c796b7d43 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 14:23:06 +0900 Subject: [PATCH 02/15] =?UTF-8?q?feat(Bishop):=20=EB=B9=84=EC=88=8D=20?= =?UTF-8?q?=EB=8C=80=EA=B0=81=EC=84=A0=20=EC=9D=B4=EB=8F=99=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/Position.java | 28 +++++++++++++++ src/main/java/chess/piece/Bishop.java | 44 ++++++++++++++++++++++- src/main/java/chess/piece/Piece.java | 16 +++++++++ src/test/java/chess/piece/BishopTest.java | 34 ++++++++++++++++++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/main/java/chess/piece/Piece.java create mode 100644 src/test/java/chess/piece/BishopTest.java diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/Position.java index 3ebeb0ea185..cde1b412e25 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/Position.java @@ -76,14 +76,26 @@ public boolean canMoveLeftUp() { return canMoveLeft() && canMoveUp(); } + public boolean canMoveLeftUp(final int step) { + return canMoveLeft(step) && canMoveUp(step); + } + public Position moveLeftUp() { return moveLeft().moveUp(); } + public Position moveLeftUp(final int step) { + return moveLeft(step).moveUp(step); + } + public boolean canMoveLeftDown() { return canMoveLeft() && canMoveDown(); } + public boolean canMoveLeftDown(final int step) { + return canMoveLeft(step) && canMoveDown(step); + } + public Position moveLeftDown() { return moveLeft().moveDown(); } @@ -92,18 +104,34 @@ public boolean canMoveRightUp() { return canMoveUp() && canMoveRight(); } + public boolean canMoveRightUp(final int step) { + return canMoveUp(step) && canMoveRight(step); + } + public Position moveRightUp() { return moveRight().moveUp(); } + public Position moveRightUp(final int step) { + return moveRight(step).moveUp(step); + } + public boolean canMoveRightDown() { return canMoveRight() && canMoveDown(); } + public boolean canMoveRightDown(final int step) { + return canMoveRight(step) && canMoveDown(step); + } + public Position moveRightDown() { return moveRight().moveDown(); } + public Position moveRightDown(final int step) { + return moveRight(step).moveDown(step); + } + public boolean isTop() { return row.isTop(); } diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index b14ab70f981..8bf03440611 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -1,5 +1,47 @@ package chess.piece; -public class Bishop { +import chess.Position; +public class Bishop extends Piece { + + public Bishop(final Position position) { + super(position); + } + + public void move(final int x, final int y) { + if (Math.abs(x) != Math.abs(y)) { + throw new IllegalArgumentException("대각선으로만 이동 가능합니다."); + } + int step = Math.abs(x); + boolean canMove = false; + if (x < 0 && y < 0) { + canMove = position.canMoveLeftDown(step); + } + if (x < 0 && y > 0) { + canMove = position.canMoveLeftUp(step); + } + if (x > 0 && y < 0) { + canMove = position.canMoveRightDown(step); + } + if (x > 0 && y > 0) { + canMove = position.canMoveRightUp(step); + } + + if (canMove) { + if (x < 0 && y < 0) { + position = position.moveLeftUp(step); + } + if (x < 0 && y > 0) { + position = position.moveLeftUp(step); + } + if (x > 0 && y < 0) { + position = position.moveRightDown(step); + } + if (x > 0 && y > 0) { + position = position.moveRightUp(step); + } + return; + } + throw new IllegalArgumentException("이동할 수 없습니다"); + } } diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java new file mode 100644 index 00000000000..4975d3070f3 --- /dev/null +++ b/src/main/java/chess/piece/Piece.java @@ -0,0 +1,16 @@ +package chess.piece; + +import chess.Position; + +public abstract class Piece { + + protected Position position; + + public Piece(Position position) { + this.position = position; + } + + public Position getPosition() { + return position; + } +} diff --git a/src/test/java/chess/piece/BishopTest.java b/src/test/java/chess/piece/BishopTest.java new file mode 100644 index 00000000000..96d081c2bc7 --- /dev/null +++ b/src/test/java/chess/piece/BishopTest.java @@ -0,0 +1,34 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.Fixtures; +import chess.Position; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class BishopTest { + + @DisplayName("대각선으로 이동할 수 있다.") + @Test + void move_diagonal() { + Position current = Fixtures.C1; + Position dest = Fixtures.B2; + Bishop bishop = new Bishop(current); + + bishop.move(-1, 1); + + assertThat(bishop.getPosition()).isEqualTo(dest); + } + + @DisplayName("대각선이 아니라면 이동할 수 없다.") + @Test + void cant_move_not_diagonal() { + Position current = Fixtures.C1; + Bishop bishop = new Bishop(current); + + assertThatThrownBy(() -> bishop.move(1, 0)) + .isInstanceOf(IllegalArgumentException.class); + } +} From e52c865a5f359c8d678ffc8f285aeb79cc95485f Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 14:39:05 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat(Rook):=20=EB=A3=A9=20=EC=83=81?= =?UTF-8?q?=ED=95=98=EC=A2=8C=EC=9A=B0=20=EC=9D=B4=EB=8F=99=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/piece/Rook.java | 31 +++++++++++++- src/test/java/chess/piece/RookTest.java | 57 +++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/test/java/chess/piece/RookTest.java diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index 7ed4d08bf03..f76d5fee583 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -1,5 +1,34 @@ package chess.piece; -public class Rook { +import chess.Position; +public class Rook extends Piece { + + public Rook(final Position position) { + super(position); + } + + public void move(final int x, final int y) { + if (x != 0 && y != 0) { + throw new IllegalArgumentException("대각선으로는 이동할 수 없습니다."); + } + + boolean canMove = false; + if (x != 0) { + canMove = position.canMoveHorizontal(x); + } + if (y != 0) { + canMove = position.canMoveHorizontal(y); + } + + if (canMove) { + if (x != 0) { + position = position.moveHorizontal(x); + return; + } + position = position.moveVertical(y); + return; + } + throw new IllegalArgumentException("이동할 수 없습니다."); + } } diff --git a/src/test/java/chess/piece/RookTest.java b/src/test/java/chess/piece/RookTest.java new file mode 100644 index 00000000000..c60a1d7feb0 --- /dev/null +++ b/src/test/java/chess/piece/RookTest.java @@ -0,0 +1,57 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.Fixtures; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class RookTest { + + @DisplayName("대각선으로 이동하려고 하면, 예외를 던진다.") + @Test + void throw_exception_move_diagonal() { + Rook rook = new Rook(Fixtures.A1); + + assertThatThrownBy(() -> rook.move(1, 1)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("상하로 원하는 만큼 이동 가능하다.") + @Test + void move_vertical() { + Rook rook = new Rook(Fixtures.A1); + + rook.move(0, 5); + + assertThat(rook.getPosition()).isEqualTo(Fixtures.A6); + } + + @DisplayName("좌우로 원하는 만큼 이동 가능하다.") + @Test + void move_horizontal() { + Rook rook = new Rook(Fixtures.A1); + + rook.move(5, 0); + + assertThat(rook.getPosition()).isEqualTo(Fixtures.F1); + } + + @DisplayName("장기판 밖으로는 이동 불가능하다.") + @ParameterizedTest + @CsvSource(value = { + "-1, 0", + "100, 0", + "0, -1", + "0, 100" + }) + void cant_move_out_of_board(int x, int y) { + Rook rook = new Rook(Fixtures.A1); + + assertThatThrownBy(() -> rook.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 22d5b3e833414d7e31d90f74692dd7bee9df2187 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 14:54:23 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat(King):=20=EC=99=95=20=EC=83=81?= =?UTF-8?q?=ED=95=98=EC=A2=8C=EC=9A=B0=20=EB=8C=80=EA=B0=81=EC=84=A0=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/chess/piece/King.java | 23 +++++++- src/test/java/chess/piece/KingTest.java | 71 +++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/test/java/chess/piece/KingTest.java diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index d64210cad13..b8f585bc054 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -1,5 +1,26 @@ package chess.piece; -public class King { +import chess.Position; +public class King extends Piece { + + public King(final Position position) { + super(position); + } + + public void move(final int x, final int y) { + if (x > 1 || y > 1) { + throw new IllegalArgumentException("한 칸만 이동 가능합니다"); + } + + boolean canMoveHorizontal = position.canMoveHorizontal(x); + boolean canMoveVertical = position.canMoveVertical(y); + + if (canMoveHorizontal && canMoveVertical) { + position = position.moveHorizontal(x); + position = position.moveVertical(y); + return; + } + throw new IllegalArgumentException("움직일 수 없습니다."); + } } diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java new file mode 100644 index 00000000000..2c6dba97d63 --- /dev/null +++ b/src/test/java/chess/piece/KingTest.java @@ -0,0 +1,71 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.Fixtures; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class KingTest { + + @DisplayName("상하좌우로 한 칸 이상 이동하면 예외를 던진다.") + @ParameterizedTest + @CsvSource(value = { + "2, 0", + "0, 2", + "2, 1", + "1, 2" + }) + void cant_move_over_two_step(int x, int y) { + King king = new King(Fixtures.D1); + + assertThatThrownBy(() -> king.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("상하로 한 칸 이동 가능하다.") + @Test + void move_vertical_one_step() { + King king = new King(Fixtures.D1); + + king.move(0, 1); + + assertThat(king.getPosition()).isEqualTo(Fixtures.D2); + } + + @DisplayName("좌우로 한 칸 이동 가능하다.") + @Test + void move_horizontal_one_step() { + King king = new King(Fixtures.D1); + + king.move(1, 0); + + assertThat(king.getPosition()).isEqualTo(Fixtures.E1); + } + + @DisplayName("대각선으로 한 칸 이동 가능하다.") + @Test + void move_diagonal_one_step() { + King king = new King(Fixtures.D1); + + king.move(1, 1); + + assertThat(king.getPosition()).isEqualTo(Fixtures.E2); + } + + @DisplayName("장기판 밖으로는 이동 불가능하다.") + @ParameterizedTest + @CsvSource(value = { + "-1, 0", + "0, -1", + }) + void cant_move_out_of_board(int x, int y) { + King king = new King(Fixtures.A1); + + assertThatThrownBy(() -> king.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } +} From ce197f253e86ca29a998e7dc6c3d37729d8d5f58 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 14:59:29 +0900 Subject: [PATCH 05/15] =?UTF-8?q?fix(Rook):=20canMove=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=20=EB=B2=84=EA=B7=B8=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/chess/piece/Rook.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index f76d5fee583..a9b991785f5 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -18,7 +18,7 @@ public void move(final int x, final int y) { canMove = position.canMoveHorizontal(x); } if (y != 0) { - canMove = position.canMoveHorizontal(y); + canMove = position.canMoveVertical(y); } if (canMove) { From d751b4ba5c3d88a47e7c5e3f2668af9c08ecc595 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 15:17:05 +0900 Subject: [PATCH 06/15] =?UTF-8?q?feat(Queen):=20=ED=80=B8=20=EC=83=81?= =?UTF-8?q?=ED=95=98=EC=A2=8C=EC=9A=B0=20=EB=8C=80=EA=B0=81=EC=84=A0=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/chess/Position.java | 4 ++ src/main/java/chess/piece/Queen.java | 70 +++++++++++++++++++++- src/test/java/chess/piece/QueenTest.java | 75 ++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/test/java/chess/piece/QueenTest.java diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/Position.java index cde1b412e25..9cd261346d0 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/Position.java @@ -172,6 +172,10 @@ public boolean canMoveHorizontal(final int step) { return true; } + public boolean canMoveDiagonal(final int x, final int y) { + return canMoveHorizontal(x) && canMoveVertical(y); + } + public Position move(final Movement movement) { return moveVertical(movement.y()).moveHorizontal(movement.x()); } diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 9b547261c4b..42862cb0ba0 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -1,5 +1,73 @@ package chess.piece; -public class Queen { +import chess.Position; +public class Queen extends Piece { + + public Queen(final Position position) { + super(position); + } + + public void move(final int x, final int y) { + if (x == 0 || y == 0) { + moveHorizontalOrVertical(x, y); + } + if (Math.abs(x) == Math.abs(y)) { + moveDiagonal(x, y); + } + } + + private void moveHorizontalOrVertical(final int x, final int y) { + boolean canMove = false; + if (x != 0) { + canMove = position.canMoveHorizontal(x); + } + if (y != 0) { + canMove = position.canMoveVertical(y); + } + + if (canMove) { + if (x != 0) { + position = position.moveHorizontal(x); + return; + } + position = position.moveVertical(y); + return; + } + throw new IllegalArgumentException("이동할 수 없습니다."); + } + + private void moveDiagonal(final int x, final int y) { + int step = Math.abs(x); + boolean canMove = false; + if (x < 0 && y < 0) { + canMove = position.canMoveLeftDown(step); + } + if (x < 0 && y > 0) { + canMove = position.canMoveLeftUp(step); + } + if (x > 0 && y < 0) { + canMove = position.canMoveRightDown(step); + } + if (x > 0 && y > 0) { + canMove = position.canMoveRightUp(step); + } + + if (canMove) { + if (x < 0 && y < 0) { + position = position.moveLeftUp(step); + } + if (x < 0 && y > 0) { + position = position.moveLeftUp(step); + } + if (x > 0 && y < 0) { + position = position.moveRightDown(step); + } + if (x > 0 && y > 0) { + position = position.moveRightUp(step); + } + return; + } + throw new IllegalArgumentException("이동할 수 없습니다"); + } } diff --git a/src/test/java/chess/piece/QueenTest.java b/src/test/java/chess/piece/QueenTest.java new file mode 100644 index 00000000000..08d37bc2361 --- /dev/null +++ b/src/test/java/chess/piece/QueenTest.java @@ -0,0 +1,75 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.Fixtures; +import chess.Position; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class QueenTest { + + @DisplayName("상하로 원하는 만큼 이동 가능하다.") + @Test + void move_vertical() { + Queen queen = new Queen(Fixtures.A1); + + queen.move(0, 5); + + assertThat(queen.getPosition()).isEqualTo(Fixtures.A6); + } + + @DisplayName("좌우로 원하는 만큼 이동 가능하다.") + @Test + void move_horizontal() { + Queen queen = new Queen(Fixtures.A1); + + queen.move(5, 0); + + assertThat(queen.getPosition()).isEqualTo(Fixtures.F1); + } + + @DisplayName("대각선으로 이동할 수 있다.") + @Test + void move_diagonal() { + Position current = Fixtures.C1; + Position dest = Fixtures.B2; + Queen queen = new Queen(current); + + queen.move(-1, 1); + + assertThat(queen.getPosition()).isEqualTo(dest); + } + + @DisplayName("상하좌우 대각선외에는 이동 불가능하다.") + @ParameterizedTest + @CsvSource(value = { + "5, 4", + "2, 1", + }) + void cant_move_not_diagonal_not_horizontal_or_vertical(int x, int y) { + Position current = Fixtures.C1; + Queen queen = new Queen(current); + + assertThatThrownBy(() -> queen.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("장기판 밖으로는 이동 불가능하다.") + @ParameterizedTest + @CsvSource(value = { + "-1, 0", + "100, 0", + "0, -1", + "0, 100" + }) + void cant_move_out_of_board(int x, int y) { + Queen queen = new Queen(Fixtures.A1); + + assertThatThrownBy(() -> queen.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 88cf074e843e0f728444b2d1db0576fb2a1f60d2 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 15:22:52 +0900 Subject: [PATCH 07/15] =?UTF-8?q?refactor:=20Piece=EC=97=90=EA=B2=8C=20Col?= =?UTF-8?q?or=20=ED=95=84=EB=93=9C=20=EC=9C=A0=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/piece/Bishop.java | 5 +++-- src/main/java/chess/piece/King.java | 5 +++-- src/main/java/chess/piece/Piece.java | 5 ++++- src/main/java/chess/piece/Queen.java | 5 +++-- src/main/java/chess/piece/Rook.java | 5 +++-- src/test/java/chess/piece/BishopTest.java | 5 +++-- src/test/java/chess/piece/KingTest.java | 11 ++++++----- src/test/java/chess/piece/QueenTest.java | 11 ++++++----- src/test/java/chess/piece/RookTest.java | 9 +++++---- 9 files changed, 36 insertions(+), 25 deletions(-) diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index 8bf03440611..97aaabf2c65 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -1,11 +1,12 @@ package chess.piece; +import chess.Color; import chess.Position; public class Bishop extends Piece { - public Bishop(final Position position) { - super(position); + public Bishop(final Color color, final Position position) { + super(color, position); } public void move(final int x, final int y) { diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index b8f585bc054..0012da84cb8 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -1,11 +1,12 @@ package chess.piece; +import chess.Color; import chess.Position; public class King extends Piece { - public King(final Position position) { - super(position); + public King(final Color color, final Position position) { + super(color, position); } public void move(final int x, final int y) { diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java index 4975d3070f3..6eacf31f16a 100644 --- a/src/main/java/chess/piece/Piece.java +++ b/src/main/java/chess/piece/Piece.java @@ -1,12 +1,15 @@ package chess.piece; +import chess.Color; import chess.Position; public abstract class Piece { + protected final Color color; protected Position position; - public Piece(Position position) { + public Piece(Color color, Position position) { + this.color = color; this.position = position; } diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 42862cb0ba0..706aaf1e9a0 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -1,11 +1,12 @@ package chess.piece; +import chess.Color; import chess.Position; public class Queen extends Piece { - public Queen(final Position position) { - super(position); + public Queen(final Color color, final Position position) { + super(color, position); } public void move(final int x, final int y) { diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index a9b991785f5..447dd26570a 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -1,11 +1,12 @@ package chess.piece; +import chess.Color; import chess.Position; public class Rook extends Piece { - public Rook(final Position position) { - super(position); + public Rook(final Color color, final Position position) { + super(color, position); } public void move(final int x, final int y) { diff --git a/src/test/java/chess/piece/BishopTest.java b/src/test/java/chess/piece/BishopTest.java index 96d081c2bc7..769ada9263c 100644 --- a/src/test/java/chess/piece/BishopTest.java +++ b/src/test/java/chess/piece/BishopTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import chess.Color; import chess.Fixtures; import chess.Position; import org.junit.jupiter.api.DisplayName; @@ -15,7 +16,7 @@ class BishopTest { void move_diagonal() { Position current = Fixtures.C1; Position dest = Fixtures.B2; - Bishop bishop = new Bishop(current); + Bishop bishop = new Bishop(Color.WHITE, current); bishop.move(-1, 1); @@ -26,7 +27,7 @@ void move_diagonal() { @Test void cant_move_not_diagonal() { Position current = Fixtures.C1; - Bishop bishop = new Bishop(current); + Bishop bishop = new Bishop(Color.WHITE, current); assertThatThrownBy(() -> bishop.move(1, 0)) .isInstanceOf(IllegalArgumentException.class); diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java index 2c6dba97d63..90de6023dd6 100644 --- a/src/test/java/chess/piece/KingTest.java +++ b/src/test/java/chess/piece/KingTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import chess.Color; import chess.Fixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -20,7 +21,7 @@ class KingTest { "1, 2" }) void cant_move_over_two_step(int x, int y) { - King king = new King(Fixtures.D1); + King king = new King(Color.WHITE, Fixtures.D1); assertThatThrownBy(() -> king.move(x, y)) .isInstanceOf(IllegalArgumentException.class); @@ -29,7 +30,7 @@ void cant_move_over_two_step(int x, int y) { @DisplayName("상하로 한 칸 이동 가능하다.") @Test void move_vertical_one_step() { - King king = new King(Fixtures.D1); + King king = new King(Color.WHITE, Fixtures.D1); king.move(0, 1); @@ -39,7 +40,7 @@ void move_vertical_one_step() { @DisplayName("좌우로 한 칸 이동 가능하다.") @Test void move_horizontal_one_step() { - King king = new King(Fixtures.D1); + King king = new King(Color.WHITE, Fixtures.D1); king.move(1, 0); @@ -49,7 +50,7 @@ void move_horizontal_one_step() { @DisplayName("대각선으로 한 칸 이동 가능하다.") @Test void move_diagonal_one_step() { - King king = new King(Fixtures.D1); + King king = new King(Color.WHITE, Fixtures.D1); king.move(1, 1); @@ -63,7 +64,7 @@ void move_diagonal_one_step() { "0, -1", }) void cant_move_out_of_board(int x, int y) { - King king = new King(Fixtures.A1); + King king = new King(Color.WHITE, Fixtures.A1); assertThatThrownBy(() -> king.move(x, y)) .isInstanceOf(IllegalArgumentException.class); diff --git a/src/test/java/chess/piece/QueenTest.java b/src/test/java/chess/piece/QueenTest.java index 08d37bc2361..af554b39ec5 100644 --- a/src/test/java/chess/piece/QueenTest.java +++ b/src/test/java/chess/piece/QueenTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import chess.Color; import chess.Fixtures; import chess.Position; import org.junit.jupiter.api.DisplayName; @@ -15,7 +16,7 @@ class QueenTest { @DisplayName("상하로 원하는 만큼 이동 가능하다.") @Test void move_vertical() { - Queen queen = new Queen(Fixtures.A1); + Queen queen = new Queen(Color.WHITE, Fixtures.A1); queen.move(0, 5); @@ -25,7 +26,7 @@ void move_vertical() { @DisplayName("좌우로 원하는 만큼 이동 가능하다.") @Test void move_horizontal() { - Queen queen = new Queen(Fixtures.A1); + Queen queen = new Queen(Color.WHITE, Fixtures.A1); queen.move(5, 0); @@ -37,7 +38,7 @@ void move_horizontal() { void move_diagonal() { Position current = Fixtures.C1; Position dest = Fixtures.B2; - Queen queen = new Queen(current); + Queen queen = new Queen(Color.WHITE, current); queen.move(-1, 1); @@ -52,7 +53,7 @@ void move_diagonal() { }) void cant_move_not_diagonal_not_horizontal_or_vertical(int x, int y) { Position current = Fixtures.C1; - Queen queen = new Queen(current); + Queen queen = new Queen(Color.WHITE, current); assertThatThrownBy(() -> queen.move(x, y)) .isInstanceOf(IllegalArgumentException.class); @@ -67,7 +68,7 @@ void cant_move_not_diagonal_not_horizontal_or_vertical(int x, int y) { "0, 100" }) void cant_move_out_of_board(int x, int y) { - Queen queen = new Queen(Fixtures.A1); + Queen queen = new Queen(Color.WHITE, Fixtures.A1); assertThatThrownBy(() -> queen.move(x, y)) .isInstanceOf(IllegalArgumentException.class); diff --git a/src/test/java/chess/piece/RookTest.java b/src/test/java/chess/piece/RookTest.java index c60a1d7feb0..40507b35d88 100644 --- a/src/test/java/chess/piece/RookTest.java +++ b/src/test/java/chess/piece/RookTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import chess.Color; import chess.Fixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -14,7 +15,7 @@ class RookTest { @DisplayName("대각선으로 이동하려고 하면, 예외를 던진다.") @Test void throw_exception_move_diagonal() { - Rook rook = new Rook(Fixtures.A1); + Rook rook = new Rook(Color.WHITE, Fixtures.A1); assertThatThrownBy(() -> rook.move(1, 1)) .isInstanceOf(IllegalArgumentException.class); @@ -23,7 +24,7 @@ void throw_exception_move_diagonal() { @DisplayName("상하로 원하는 만큼 이동 가능하다.") @Test void move_vertical() { - Rook rook = new Rook(Fixtures.A1); + Rook rook = new Rook(Color.WHITE, Fixtures.A1); rook.move(0, 5); @@ -33,7 +34,7 @@ void move_vertical() { @DisplayName("좌우로 원하는 만큼 이동 가능하다.") @Test void move_horizontal() { - Rook rook = new Rook(Fixtures.A1); + Rook rook = new Rook(Color.WHITE, Fixtures.A1); rook.move(5, 0); @@ -49,7 +50,7 @@ void move_horizontal() { "0, 100" }) void cant_move_out_of_board(int x, int y) { - Rook rook = new Rook(Fixtures.A1); + Rook rook = new Rook(Color.WHITE, Fixtures.A1); assertThatThrownBy(() -> rook.move(x, y)) .isInstanceOf(IllegalArgumentException.class); From 45eb697ba7a880b83ffd3b7d26d370c7838eae4b Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 15:32:19 +0900 Subject: [PATCH 08/15] =?UTF-8?q?feat(Pawn):=20=ED=8F=B0=20=ED=8C=80?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EC=9C=84=EC=95=84=EB=9E=98=20?= =?UTF-8?q?=ED=95=9C=20=EC=B9=B8=20=EC=9B=80=EC=A7=81=EC=9E=84=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/piece/Pawn.java | 30 ++++++++++++++- src/test/java/chess/piece/PawnTest.java | 50 +++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/test/java/chess/piece/PawnTest.java diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index c8b6cafa51e..3cf83586bbd 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -1,5 +1,33 @@ package chess.piece; -public class Pawn { +import chess.Color; +import chess.Position; +public class Pawn extends Piece { + + public Pawn(Color color, Position position) { + super(color, position); + } + + public void move(final int x, final int y) { + boolean canMove = false; + if (color == Color.WHITE && y > 0) { + canMove = position.canMoveUp(); + } + if (color == Color.BLACK && y < 0) { + canMove = position.canMoveDown(); + } + + if (canMove) { + if (color == Color.WHITE) { + position = position.moveUp(); + return; + } + if (color == Color.BLACK) { + position = position.moveDown(); + return; + } + } + throw new IllegalArgumentException("이동할 수 없습니다."); + } } diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java new file mode 100644 index 00000000000..a5be6d03a03 --- /dev/null +++ b/src/test/java/chess/piece/PawnTest.java @@ -0,0 +1,50 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.Color; +import chess.Fixtures; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +class PawnTest { + + @DisplayName("백팀이라면 위로 한 칸 이동 가능하다.") + @Test + void move_up_one_step_white_color() { + Pawn pawn = new Pawn(Color.WHITE, Fixtures.D2); + + pawn.move(0, 1); + + assertThat(pawn.getPosition()).isEqualTo(Fixtures.D3); + } + + @DisplayName("흑팀이라면 아래로 한 칸 이동 가능하다.") + @Test + void move_down_one_step_black_color() { + Pawn pawn = new Pawn(Color.BLACK, Fixtures.D7); + + pawn.move(0, -1); + + assertThat(pawn.getPosition()).isEqualTo(Fixtures.D6); + } + + @DisplayName("백팀이라면 아래로 이동 불가능하다.") + @Test + void cant_move_down_white_color() { + Pawn pawn = new Pawn(Color.WHITE, Fixtures.D2); + + assertThatThrownBy(()->pawn.move(0, -1)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("흑팀이라면 위로 이동 불가능하다.") + @Test + void cant_move_up_black_color() { + Pawn pawn = new Pawn(Color.BLACK, Fixtures.D7); + + assertThatThrownBy(()->pawn.move(0, 1)) + .isInstanceOf(IllegalArgumentException.class); + } +} From b56e8a1bba6f71c15d2da54820c9816e9e203152 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 15:44:36 +0900 Subject: [PATCH 09/15] =?UTF-8?q?feat(Pawn):=20=EC=B2=AB=20=EB=B2=88?= =?UTF-8?q?=EC=A7=B8=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C,=202=EC=B9=B8=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/piece/Pawn.java | 29 ++++++++----- src/test/java/chess/piece/PawnTest.java | 56 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index 3cf83586bbd..21968a545ea 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -2,31 +2,38 @@ import chess.Color; import chess.Position; +import chess.Row; public class Pawn extends Piece { - public Pawn(Color color, Position position) { + public Pawn(final Color color, final Position position) { super(color, position); } public void move(final int x, final int y) { boolean canMove = false; - if (color == Color.WHITE && y > 0) { + if (color == Color.WHITE && y > 0 && y <= 2) { canMove = position.canMoveUp(); } - if (color == Color.BLACK && y < 0) { + if (color == Color.BLACK && y < 0 && y >= -2) { canMove = position.canMoveDown(); } + boolean isNotFirstMove = true; + if (color == Color.WHITE && position.row() == Row.TWO) { + isNotFirstMove = false; + } + if (color == Color.BLACK && position.row() == Row.SEVEN) { + isNotFirstMove = false; + } + + if (isNotFirstMove && y != 1) { + canMove = false; + } + if (canMove) { - if (color == Color.WHITE) { - position = position.moveUp(); - return; - } - if (color == Color.BLACK) { - position = position.moveDown(); - return; - } + position = position.moveVertical(y); + return; } throw new IllegalArgumentException("이동할 수 없습니다."); } diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java index a5be6d03a03..f1315e35129 100644 --- a/src/test/java/chess/piece/PawnTest.java +++ b/src/test/java/chess/piece/PawnTest.java @@ -30,6 +30,44 @@ void move_down_one_step_black_color() { assertThat(pawn.getPosition()).isEqualTo(Fixtures.D6); } + @DisplayName("백팀이라면 처음 이동할 때, 위로 두 칸 이동 가능하다.") + @Test + void move_up_two_step_white_color_first_move() { + Pawn pawn = new Pawn(Color.WHITE, Fixtures.D2); + + pawn.move(0, 2); + + assertThat(pawn.getPosition()).isEqualTo(Fixtures.D4); + } + + @DisplayName("흑팀이라면 처음 이동할 때 아래로 두 칸 이동 가능하다.") + @Test + void move_down_two_step_black_color_first_move() { + Pawn pawn = new Pawn(Color.BLACK, Fixtures.D7); + + pawn.move(0, -2); + + assertThat(pawn.getPosition()).isEqualTo(Fixtures.D5); + } + + @DisplayName("처음 이동 아니라면, 백팀은 위로 두 칸 이동할 수 없다.") + @Test + void cant_move_up_two_step_white_color_not_first_move() { + Pawn pawn = new Pawn(Color.WHITE, Fixtures.D3); + + assertThatThrownBy(()->pawn.move(0, 2)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("처음 이동 아니라면, 흑팀은 아래로 두 칸 이동할 수 없다.") + @Test + void cnat_move_down_two_step_black_color_not_first_move() { + Pawn pawn = new Pawn(Color.BLACK, Fixtures.D6); + + assertThatThrownBy(()->pawn.move(0, -2)) + .isInstanceOf(IllegalArgumentException.class); + } + @DisplayName("백팀이라면 아래로 이동 불가능하다.") @Test void cant_move_down_white_color() { @@ -47,4 +85,22 @@ void cant_move_up_black_color() { assertThatThrownBy(()->pawn.move(0, 1)) .isInstanceOf(IllegalArgumentException.class); } + + @DisplayName("백팀은 위로 두 칸 이상 이동할 수 없다.") + @Test + void cant_move_up_over_two_step_white_color() { + Pawn pawn = new Pawn(Color.WHITE, Fixtures.D3); + + assertThatThrownBy(()->pawn.move(0, 3)) + .isInstanceOf(IllegalArgumentException.class); + } + + @DisplayName("흑팀은 아래로 두 칸 이상 이동할 수 없다.") + @Test + void cnat_move_down_over_two_step_black_color() { + Pawn pawn = new Pawn(Color.BLACK, Fixtures.D6); + + assertThatThrownBy(()->pawn.move(0, -3)) + .isInstanceOf(IllegalArgumentException.class); + } } From 40e30b2fbd91611bf610e25cc308deda8e43ed65 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 16:15:17 +0900 Subject: [PATCH 10/15] =?UTF-8?q?feat(Knight):=20=EB=A7=90=20=EC=9D=B4?= =?UTF-8?q?=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/chess/piece/Knight.java | 24 ++++++- src/test/java/chess/piece/KnightTest.java | 86 +++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/test/java/chess/piece/KnightTest.java diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index 2ee7c47a3bc..2edea7194b0 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -1,5 +1,27 @@ package chess.piece; -public class Knight { +import chess.Color; +import chess.Position; +public class Knight extends Piece { + + public Knight(Color color, Position position) { + super(color, position); + } + + public void move(final int x, final int y) { + boolean canMove = position.canMoveHorizontal(x) && position.canMoveVertical(y); + + if (isMovingRule(x, y) && canMove) { + position = position.moveHorizontal(x).moveVertical(y); + return; + } + throw new IllegalArgumentException("이동할 수 없습니다."); + } + + private boolean isMovingRule(final int x, final int y) { + int absX = Math.abs(x); + int absY = Math.abs(y); + return ((absX == 2 && absY == 1) || (absX == 1 && absY == 2)); + } } diff --git a/src/test/java/chess/piece/KnightTest.java b/src/test/java/chess/piece/KnightTest.java new file mode 100644 index 00000000000..7fb0aac50e4 --- /dev/null +++ b/src/test/java/chess/piece/KnightTest.java @@ -0,0 +1,86 @@ +package chess.piece; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import chess.Color; +import chess.Fixtures; +import chess.Position; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class KnightTest { + + Knight knight; + + @BeforeEach + void initKnight() { + knight = new Knight(Color.WHITE, Fixtures.D4); + } + + @DisplayName("말은 상하좌우 한 칸과 대각선으로 이동 가능하다.") + @ParameterizedTest + @MethodSource("knightDestination") + void move_up_and_up_right(int x, int y, Position dest) { + knight.move(x, y); + + assertThat(knight.getPosition()).isEqualTo(dest); + } + + static Stream knightDestination() { + return Stream.of( + Arguments.of(1, 2, Fixtures.E6), + Arguments.of(-1, 2, Fixtures.C6), + Arguments.of(1, -2, Fixtures.E2), + Arguments.of(-1, -2, Fixtures.C2), + Arguments.of(2, 1, Fixtures.F5), + Arguments.of(2, -1, Fixtures.F3), + Arguments.of(-2, 1, Fixtures.B5), + Arguments.of(-2, -1, Fixtures.B3) + ); + } + + @DisplayName("말은 상하좌우 한 칸과 대각선이 아니면 이동이 불가능하다.") + @ParameterizedTest + @MethodSource("notKnightMovingRule") + void move_up_and_up_right(int x, int y) { + assertThatThrownBy(() -> knight.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } + + static Stream notKnightMovingRule() { + return Stream.of( + Arguments.of(2, 2), + Arguments.of(0, 2), + Arguments.of(2, 0), + Arguments.of(3, 2), + Arguments.of(2, 3), + Arguments.of(5, 2) + ); + } + + @DisplayName("말은 장기판 밖으로 이동할 수 없다.") + @ParameterizedTest + @MethodSource("outOfBoardMove") + void cant_move_out_of_board(int x, int y) { + Knight knight_A1 = new Knight(Color.WHITE, Fixtures.A1); + + assertThatThrownBy(() -> knight_A1.move(x, y)) + .isInstanceOf(IllegalArgumentException.class); + } + + static Stream outOfBoardMove() { + return Stream.of( + Arguments.of(-1, 2), + Arguments.of(1, -2), + Arguments.of(-1, -2), + Arguments.of(2, -1), + Arguments.of(-2, 1), + Arguments.of(-2, -1) + ); + } +} From 70d7599b574cd945d47b2acbc9576598df51a7d2 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 16:30:47 +0900 Subject: [PATCH 11/15] =?UTF-8?q?fix(Queen):=20=ED=80=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=20=EA=B2=80=EC=A6=9D=20=EB=B2=84=EA=B7=B8=20=ED=94=BD?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/piece/Queen.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 706aaf1e9a0..019b94963ee 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -12,10 +12,13 @@ public Queen(final Color color, final Position position) { public void move(final int x, final int y) { if (x == 0 || y == 0) { moveHorizontalOrVertical(x, y); + return; } if (Math.abs(x) == Math.abs(y)) { moveDiagonal(x, y); + return; } + throw new IllegalArgumentException("이동할 수 없습니다."); } private void moveHorizontalOrVertical(final int x, final int y) { From bfceb2036cc623517f343d50b4b0bd3536d463c6 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 16:37:01 +0900 Subject: [PATCH 12/15] =?UTF-8?q?refactor:=20=EB=8C=80=EA=B0=81=EC=84=A0?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99/=EA=B2=80=EC=A6=9D=20=EA=B3=BC=EC=A0=95?= =?UTF-8?q?=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/chess/Position.java | 4 ++++ src/main/java/chess/piece/Bishop.java | 28 ++------------------------- src/main/java/chess/piece/Knight.java | 2 +- src/main/java/chess/piece/Queen.java | 27 ++------------------------ 4 files changed, 9 insertions(+), 52 deletions(-) diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/Position.java index 9cd261346d0..4c308e54c16 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/Position.java @@ -199,4 +199,8 @@ public Position moveHorizontal(final int step) { } return this; } + + public Position moveDiagonal(final int horizontalStep, final int verticalStep) { + return moveHorizontal(horizontalStep).moveVertical(verticalStep); + } } diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index 97aaabf2c65..f46f71cc126 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -13,34 +13,10 @@ public void move(final int x, final int y) { if (Math.abs(x) != Math.abs(y)) { throw new IllegalArgumentException("대각선으로만 이동 가능합니다."); } - int step = Math.abs(x); - boolean canMove = false; - if (x < 0 && y < 0) { - canMove = position.canMoveLeftDown(step); - } - if (x < 0 && y > 0) { - canMove = position.canMoveLeftUp(step); - } - if (x > 0 && y < 0) { - canMove = position.canMoveRightDown(step); - } - if (x > 0 && y > 0) { - canMove = position.canMoveRightUp(step); - } + boolean canMove = position.canMoveDiagonal(x, y); if (canMove) { - if (x < 0 && y < 0) { - position = position.moveLeftUp(step); - } - if (x < 0 && y > 0) { - position = position.moveLeftUp(step); - } - if (x > 0 && y < 0) { - position = position.moveRightDown(step); - } - if (x > 0 && y > 0) { - position = position.moveRightUp(step); - } + position = position.moveDiagonal(x, y); return; } throw new IllegalArgumentException("이동할 수 없습니다"); diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index 2edea7194b0..170f07c6405 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -13,7 +13,7 @@ public void move(final int x, final int y) { boolean canMove = position.canMoveHorizontal(x) && position.canMoveVertical(y); if (isMovingRule(x, y) && canMove) { - position = position.moveHorizontal(x).moveVertical(y); + position = position.moveDiagonal(x, y); return; } throw new IllegalArgumentException("이동할 수 없습니다."); diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 019b94963ee..c5d325751bd 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -43,33 +43,10 @@ private void moveHorizontalOrVertical(final int x, final int y) { private void moveDiagonal(final int x, final int y) { int step = Math.abs(x); - boolean canMove = false; - if (x < 0 && y < 0) { - canMove = position.canMoveLeftDown(step); - } - if (x < 0 && y > 0) { - canMove = position.canMoveLeftUp(step); - } - if (x > 0 && y < 0) { - canMove = position.canMoveRightDown(step); - } - if (x > 0 && y > 0) { - canMove = position.canMoveRightUp(step); - } + boolean canMove = position.canMoveDiagonal(x, y); if (canMove) { - if (x < 0 && y < 0) { - position = position.moveLeftUp(step); - } - if (x < 0 && y > 0) { - position = position.moveLeftUp(step); - } - if (x > 0 && y < 0) { - position = position.moveRightDown(step); - } - if (x > 0 && y > 0) { - position = position.moveRightUp(step); - } + position = position.moveDiagonal(x, y); return; } throw new IllegalArgumentException("이동할 수 없습니다"); From a13760164134c00997d5b1803344198fc66eeee4 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 17:28:23 +0900 Subject: [PATCH 13/15] =?UTF-8?q?feat:=20=EB=B3=B4=EB=93=9C=ED=8C=90=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5=20=EB=B0=8F=20=EB=A7=90=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=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/chess/Application.java | 11 +++ src/main/java/chess/board/Board.java | 32 +++++++++ src/main/java/chess/board/BoardFactory.java | 53 ++++++++++++++ src/main/java/chess/board/BoardManager.java | 34 +++++++++ src/main/java/chess/piece/Piece.java | 10 +++ src/main/java/chess/piece/Pieces.java | 30 ++++++++ src/main/java/chess/piece/Queen.java | 1 - src/main/java/chess/view/InputView.java | 18 +++++ src/main/java/chess/view/OutputView.java | 78 +++++++++++++++++++++ 9 files changed, 266 insertions(+), 1 deletion(-) create mode 100644 src/main/java/chess/Application.java create mode 100644 src/main/java/chess/board/Board.java create mode 100644 src/main/java/chess/board/BoardFactory.java create mode 100644 src/main/java/chess/board/BoardManager.java create mode 100644 src/main/java/chess/piece/Pieces.java create mode 100644 src/main/java/chess/view/InputView.java create mode 100644 src/main/java/chess/view/OutputView.java diff --git a/src/main/java/chess/Application.java b/src/main/java/chess/Application.java new file mode 100644 index 00000000000..2e4b2fe3f87 --- /dev/null +++ b/src/main/java/chess/Application.java @@ -0,0 +1,11 @@ +package chess; + +import chess.board.BoardManager; + +public class Application { + + public static void main(String[] args) { + BoardManager manager = new BoardManager(); + manager.move(); + } +} diff --git a/src/main/java/chess/board/Board.java b/src/main/java/chess/board/Board.java new file mode 100644 index 00000000000..6c62a17737c --- /dev/null +++ b/src/main/java/chess/board/Board.java @@ -0,0 +1,32 @@ +package chess.board; + +import chess.Position; +import chess.piece.Piece; +import chess.piece.Pieces; +import java.util.List; + +public class Board { + + private final Pieces pieces; + + public Board(Pieces pieces) { + this.pieces = pieces; + } + + public void move(Position current, Position destination) { + Piece pickedPiece = pieces.findByPosition(current); + int differenceX = destination.column().ordinal() - current.column().ordinal(); + int differenceY = current.row().ordinal() - destination.row().ordinal(); + if (pieces.existsByPosition(destination)) { + Piece targetPiece = pieces.findByPosition(destination); + if (pickedPiece.isSameColor(targetPiece)) { + throw new IllegalArgumentException("같은 팀이 있는 위치로는 이동할 수 없습니다."); + } + } + pickedPiece.move(differenceX, differenceY); + } + + public List getPieces() { + return pieces.getPieces(); + } +} diff --git a/src/main/java/chess/board/BoardFactory.java b/src/main/java/chess/board/BoardFactory.java new file mode 100644 index 00000000000..9f65d56fe2b --- /dev/null +++ b/src/main/java/chess/board/BoardFactory.java @@ -0,0 +1,53 @@ +package chess.board; + +import chess.Color; +import chess.Column; +import chess.Position; +import chess.Row; +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Piece; +import chess.piece.Pieces; +import chess.piece.Queen; +import chess.piece.Rook; +import java.util.ArrayList; +import java.util.List; + +public class BoardFactory { + + private BoardFactory() { + } + + public static Board init() { + List initPieces = new ArrayList<>(); + for (Column column : Column.values()) { + initPieces.add(new Pawn(Color.WHITE, new Position(column, Row.TWO))); + initPieces.add(new Pawn(Color.BLACK, new Position(column, Row.SEVEN))); + } + initPieces.add(new Rook(Color.WHITE, new Position(Column.A, Row.ONE))); + initPieces.add(new Rook(Color.WHITE, new Position(Column.H, Row.ONE))); + initPieces.add(new Rook(Color.BLACK, new Position(Column.A, Row.EIGHT))); + initPieces.add(new Rook(Color.BLACK, new Position(Column.H, Row.EIGHT))); + + initPieces.add(new Knight(Color.WHITE, new Position(Column.B, Row.ONE))); + initPieces.add(new Knight(Color.WHITE, new Position(Column.G, Row.ONE))); + initPieces.add(new Knight(Color.BLACK, new Position(Column.B, Row.EIGHT))); + initPieces.add(new Knight(Color.BLACK, new Position(Column.G, Row.EIGHT))); + + initPieces.add(new Bishop(Color.WHITE, new Position(Column.C, Row.ONE))); + initPieces.add(new Bishop(Color.WHITE, new Position(Column.F, Row.ONE))); + initPieces.add(new Bishop(Color.BLACK, new Position(Column.C, Row.EIGHT))); + initPieces.add(new Bishop(Color.BLACK, new Position(Column.F, Row.EIGHT))); + + initPieces.add(new King(Color.WHITE, new Position(Column.D, Row.ONE))); + initPieces.add(new Queen(Color.WHITE, new Position(Column.E, Row.ONE))); + + initPieces.add(new King(Color.BLACK, new Position(Column.D, Row.EIGHT))); + initPieces.add(new Queen(Color.BLACK, new Position(Column.E, Row.EIGHT))); + + Pieces pieces = new Pieces(initPieces); + return new Board(pieces); + } +} diff --git a/src/main/java/chess/board/BoardManager.java b/src/main/java/chess/board/BoardManager.java new file mode 100644 index 00000000000..3ffd1261eca --- /dev/null +++ b/src/main/java/chess/board/BoardManager.java @@ -0,0 +1,34 @@ +package chess.board; + +import chess.Column; +import chess.Position; +import chess.Row; +import chess.view.InputView; +import chess.view.OutputView; + +public class BoardManager { + + public void move() { + Board board = BoardFactory.init(); + while(true) + { + OutputView.printBoard(board); + String inputCurrentCoordinate = InputView.inputCurrentCoordinate(); + if (inputCurrentCoordinate.equals("Q")) { + break; + } + String inputDestinationCoordinate = InputView.inputDestinationCoordinate(); + Position currentPosition = parsePosition(inputCurrentCoordinate); + Position destinationPosition = parsePosition(inputDestinationCoordinate); + board.move(currentPosition, destinationPosition); + } + } + + private Position parsePosition(String input) { + String[] coordinate = input.split(""); + Column column = Column.valueOf(coordinate[0]); + int rowNumber = Integer.parseInt(coordinate[1]); + Row row = Row.values()[8 - rowNumber]; + return new Position(column, row); + } +} diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java index 6eacf31f16a..98c9fc8c9b5 100644 --- a/src/main/java/chess/piece/Piece.java +++ b/src/main/java/chess/piece/Piece.java @@ -13,6 +13,16 @@ public Piece(Color color, Position position) { this.position = position; } + public boolean isSameColor(Piece other) { + return this.color == other.color; + } + + public abstract void move(int x, int y); + + public Color getColor() { + return color; + } + public Position getPosition() { return position; } diff --git a/src/main/java/chess/piece/Pieces.java b/src/main/java/chess/piece/Pieces.java new file mode 100644 index 00000000000..28fa12047de --- /dev/null +++ b/src/main/java/chess/piece/Pieces.java @@ -0,0 +1,30 @@ +package chess.piece; + +import chess.Position; +import java.util.Collections; +import java.util.List; + +public class Pieces { + + private final List pieces; + + public Pieces(List pieces) { + this.pieces = pieces; + } + + public Piece findByPosition(Position position) { + return pieces.stream() + .filter(piece -> piece.getPosition().equals(position)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException("말이 존재하지 않습니다.")); + } + + public boolean existsByPosition(Position position) { + return pieces.stream() + .anyMatch(piece -> piece.getPosition().equals(position)); + } + + public List getPieces() { + return Collections.unmodifiableList(pieces); + } +} diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index c5d325751bd..82b72deaa5a 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -42,7 +42,6 @@ private void moveHorizontalOrVertical(final int x, final int y) { } private void moveDiagonal(final int x, final int y) { - int step = Math.abs(x); boolean canMove = position.canMoveDiagonal(x, y); if (canMove) { diff --git a/src/main/java/chess/view/InputView.java b/src/main/java/chess/view/InputView.java new file mode 100644 index 00000000000..517c55c5e96 --- /dev/null +++ b/src/main/java/chess/view/InputView.java @@ -0,0 +1,18 @@ +package chess.view; + +import java.util.Scanner; + +public class InputView { + + private final static Scanner scanner = new Scanner(System.in); + + public static String inputCurrentCoordinate() { + System.out.println("움직이고 싶은 말의 좌표를 입력하시오. (x,y)"); + return scanner.nextLine(); + } + + public static String inputDestinationCoordinate() { + System.out.println("도착지의 좌표를 입력하시오. (x,y)"); + return scanner.nextLine(); + } +} diff --git a/src/main/java/chess/view/OutputView.java b/src/main/java/chess/view/OutputView.java new file mode 100644 index 00000000000..9c9a205d7f1 --- /dev/null +++ b/src/main/java/chess/view/OutputView.java @@ -0,0 +1,78 @@ +package chess.view; + +import chess.Color; +import chess.board.Board; +import chess.piece.Bishop; +import chess.piece.King; +import chess.piece.Knight; +import chess.piece.Pawn; +import chess.piece.Piece; +import chess.piece.Queen; +import java.util.List; + +public class OutputView { + + public static void printBoard(Board board) { + String[][] boardOutput = new String[8][8]; + List pieces = board.getPieces(); + for (int i = 0; i < boardOutput.length; i++) { + for (int j = 0; j < boardOutput[i].length; j++) { + boardOutput[i][j] = "."; + } + } + for (Piece piece : pieces) { + int row = piece.getPosition().row().ordinal(); + int column = piece.getPosition().column().ordinal(); + boardOutput[row][column] = PieceOutput.getPieceOutputByPieceAndColor(piece); + } + for (int i = 0; i < 8; i++) { + for (int j = 0; j < boardOutput.length; j++) { + System.out.printf("%s\t", boardOutput[i][j]); + } + System.out.printf("\t%d%n", i + 1); + } + System.out.println(); + System.out.println("A\tB\tC\tD\tE\tF\tG\tH"); + } + + enum PieceOutput { + BISHOP("B"), + KING("K"), + KNIGHT("N"), + PAWN("P"), + QUEEN("Q"), + ROOK("R"); + + private final String output; + + PieceOutput(String output) { + this.output = output; + } + + private static String getPieceOutputByPieceAndColor(Piece piece) { + if (piece.getColor() == Color.BLACK) { + return getPieceOutputByPiece(piece).toLowerCase(); + } + return getPieceOutputByPiece(piece); + } + + private static String getPieceOutputByPiece(Piece piece) { + if (piece instanceof Bishop) { + return BISHOP.output; + } + if (piece instanceof King) { + return KING.output; + } + if (piece instanceof Knight) { + return KNIGHT.output; + } + if (piece instanceof Pawn) { + return PAWN.output; + } + if (piece instanceof Queen) { + return QUEEN.output; + } + return ROOK.output; + } + } +} From ce90ec630ee417426dca37cc98d71c1c36afb7e6 Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 17:29:23 +0900 Subject: [PATCH 14/15] =?UTF-8?q?refactor:=20=EC=9C=84=EC=B9=98=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 15 ++++++++------- src/main/java/chess/board/Board.java | 2 +- src/main/java/chess/board/BoardFactory.java | 8 ++++---- src/main/java/chess/board/BoardManager.java | 6 +++--- src/main/java/chess/piece/Bishop.java | 4 ++-- src/main/java/chess/piece/King.java | 4 ++-- src/main/java/chess/piece/Knight.java | 4 ++-- src/main/java/chess/piece/Pawn.java | 6 +++--- src/main/java/chess/piece/Piece.java | 4 ++-- src/main/java/chess/piece/Pieces.java | 2 +- src/main/java/chess/piece/Queen.java | 4 ++-- src/main/java/chess/piece/Rook.java | 4 ++-- src/main/java/chess/{ => position}/Color.java | 2 +- src/main/java/chess/{ => position}/Column.java | 2 +- src/main/java/chess/{ => position}/Movement.java | 2 +- src/main/java/chess/{ => position}/Position.java | 2 +- src/main/java/chess/{ => position}/Row.java | 2 +- src/main/java/chess/view/OutputView.java | 2 +- src/test/java/chess/ColumnTest.java | 1 + src/test/java/chess/Fixtures.java | 4 ++++ src/test/java/chess/PositionTest.java | 2 ++ src/test/java/chess/RowTest.java | 1 + src/test/java/chess/piece/BishopTest.java | 4 ++-- src/test/java/chess/piece/KingTest.java | 2 +- src/test/java/chess/piece/KnightTest.java | 4 ++-- src/test/java/chess/piece/PawnTest.java | 2 +- src/test/java/chess/piece/QueenTest.java | 4 ++-- src/test/java/chess/piece/RookTest.java | 2 +- 28 files changed, 55 insertions(+), 46 deletions(-) rename src/main/java/chess/{ => position}/Color.java (94%) rename src/main/java/chess/{ => position}/Column.java (97%) rename src/main/java/chess/{ => position}/Movement.java (97%) rename src/main/java/chess/{ => position}/Position.java (99%) rename src/main/java/chess/{ => position}/Row.java (97%) diff --git a/README.md b/README.md index 2b51975b347..b7fa263d3db 100644 --- a/README.md +++ b/README.md @@ -24,28 +24,29 @@ Position 공통 내용 - [ ] 각 말은 팀(Color)를 가지고 있다. - [ ] 도착지에 같은 팀이 있다면 이동할 수 없다. -- [ ] 장기판 말 밖으로 이동할 수 없다. +- [x] 장기판 말 밖으로 이동할 수 없다. 비숍 -- [ ] 대각선 원하는만큼 +- [x] 대각선 원하는만큼 - [ ] 뛰어넘기 불가 왕 -- [ ] 상하좌우 + 대각선 +- [x] 상하좌우 + 대각선 나이트 - [ ] 상하좌우 한 칸 + 진행 방향으로 대각선 한 칸 - [ ] 뛰어넘기 가능 폰 -- [ ] 각 팀마다 진행방향으로 한칸 혹은 두 칸 +- [x] 각 팀마다 진행방향으로 한칸 이동 가능 +- [x] 처음 이동에는 두 칸 이동 가능 - [ ] 상대편 말을 잡을 경우 대각선 이동 가능 퀸 -- [ ] 상하좌우 원하는 만큼 -- [ ] 대각선 원하는 만큼 +- [x] 상하좌우 원하는 만큼 +- [x] 대각선 원하는 만큼 - [ ] 뛰어넘기 불가 룩 -- [ ] 상하좌우 원하는 만큼 +- [x] 상하좌우 원하는 만큼 - [ ] 뛰어넘기 불가 diff --git a/src/main/java/chess/board/Board.java b/src/main/java/chess/board/Board.java index 6c62a17737c..91ed704a5da 100644 --- a/src/main/java/chess/board/Board.java +++ b/src/main/java/chess/board/Board.java @@ -1,6 +1,6 @@ package chess.board; -import chess.Position; +import chess.position.Position; import chess.piece.Piece; import chess.piece.Pieces; import java.util.List; diff --git a/src/main/java/chess/board/BoardFactory.java b/src/main/java/chess/board/BoardFactory.java index 9f65d56fe2b..f57f6212b82 100644 --- a/src/main/java/chess/board/BoardFactory.java +++ b/src/main/java/chess/board/BoardFactory.java @@ -1,9 +1,9 @@ package chess.board; -import chess.Color; -import chess.Column; -import chess.Position; -import chess.Row; +import chess.position.Color; +import chess.position.Column; +import chess.position.Position; +import chess.position.Row; import chess.piece.Bishop; import chess.piece.King; import chess.piece.Knight; diff --git a/src/main/java/chess/board/BoardManager.java b/src/main/java/chess/board/BoardManager.java index 3ffd1261eca..d1dd9d0993d 100644 --- a/src/main/java/chess/board/BoardManager.java +++ b/src/main/java/chess/board/BoardManager.java @@ -1,8 +1,8 @@ package chess.board; -import chess.Column; -import chess.Position; -import chess.Row; +import chess.position.Column; +import chess.position.Position; +import chess.position.Row; import chess.view.InputView; import chess.view.OutputView; diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index f46f71cc126..a067de5c42c 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -1,7 +1,7 @@ package chess.piece; -import chess.Color; -import chess.Position; +import chess.position.Color; +import chess.position.Position; public class Bishop extends Piece { diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index 0012da84cb8..be5a7c4b5f2 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -1,7 +1,7 @@ package chess.piece; -import chess.Color; -import chess.Position; +import chess.position.Color; +import chess.position.Position; public class King extends Piece { diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index 170f07c6405..ee83837cb78 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -1,7 +1,7 @@ package chess.piece; -import chess.Color; -import chess.Position; +import chess.position.Color; +import chess.position.Position; public class Knight extends Piece { diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index 21968a545ea..de828ba9606 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -1,8 +1,8 @@ package chess.piece; -import chess.Color; -import chess.Position; -import chess.Row; +import chess.position.Color; +import chess.position.Position; +import chess.position.Row; public class Pawn extends Piece { diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java index 98c9fc8c9b5..dc5e9015f1d 100644 --- a/src/main/java/chess/piece/Piece.java +++ b/src/main/java/chess/piece/Piece.java @@ -1,7 +1,7 @@ package chess.piece; -import chess.Color; -import chess.Position; +import chess.position.Color; +import chess.position.Position; public abstract class Piece { diff --git a/src/main/java/chess/piece/Pieces.java b/src/main/java/chess/piece/Pieces.java index 28fa12047de..6de1ce98df6 100644 --- a/src/main/java/chess/piece/Pieces.java +++ b/src/main/java/chess/piece/Pieces.java @@ -1,6 +1,6 @@ package chess.piece; -import chess.Position; +import chess.position.Position; import java.util.Collections; import java.util.List; diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index 82b72deaa5a..eacad2c90b2 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -1,7 +1,7 @@ package chess.piece; -import chess.Color; -import chess.Position; +import chess.position.Color; +import chess.position.Position; public class Queen extends Piece { diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index 447dd26570a..82c85b4cc35 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -1,7 +1,7 @@ package chess.piece; -import chess.Color; -import chess.Position; +import chess.position.Color; +import chess.position.Position; public class Rook extends Piece { diff --git a/src/main/java/chess/Color.java b/src/main/java/chess/position/Color.java similarity index 94% rename from src/main/java/chess/Color.java rename to src/main/java/chess/position/Color.java index 55cd020b681..6c385d831ba 100644 --- a/src/main/java/chess/Color.java +++ b/src/main/java/chess/position/Color.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Color { diff --git a/src/main/java/chess/Column.java b/src/main/java/chess/position/Column.java similarity index 97% rename from src/main/java/chess/Column.java rename to src/main/java/chess/position/Column.java index b64b4dc77a3..4099a335b6a 100644 --- a/src/main/java/chess/Column.java +++ b/src/main/java/chess/position/Column.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Column { diff --git a/src/main/java/chess/Movement.java b/src/main/java/chess/position/Movement.java similarity index 97% rename from src/main/java/chess/Movement.java rename to src/main/java/chess/position/Movement.java index e57c6e91bb9..60d4815db36 100644 --- a/src/main/java/chess/Movement.java +++ b/src/main/java/chess/position/Movement.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Movement { UP(0, 1), diff --git a/src/main/java/chess/Position.java b/src/main/java/chess/position/Position.java similarity index 99% rename from src/main/java/chess/Position.java rename to src/main/java/chess/position/Position.java index 4c308e54c16..5e89e9a8928 100644 --- a/src/main/java/chess/Position.java +++ b/src/main/java/chess/position/Position.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public record Position( Column column, diff --git a/src/main/java/chess/Row.java b/src/main/java/chess/position/Row.java similarity index 97% rename from src/main/java/chess/Row.java rename to src/main/java/chess/position/Row.java index 126ed048daa..12ff8956d5f 100644 --- a/src/main/java/chess/Row.java +++ b/src/main/java/chess/position/Row.java @@ -1,4 +1,4 @@ -package chess; +package chess.position; public enum Row { diff --git a/src/main/java/chess/view/OutputView.java b/src/main/java/chess/view/OutputView.java index 9c9a205d7f1..8d2d1fc833b 100644 --- a/src/main/java/chess/view/OutputView.java +++ b/src/main/java/chess/view/OutputView.java @@ -1,6 +1,6 @@ package chess.view; -import chess.Color; +import chess.position.Color; import chess.board.Board; import chess.piece.Bishop; import chess.piece.King; diff --git a/src/test/java/chess/ColumnTest.java b/src/test/java/chess/ColumnTest.java index e43523240f7..571288f13b4 100644 --- a/src/test/java/chess/ColumnTest.java +++ b/src/test/java/chess/ColumnTest.java @@ -1,5 +1,6 @@ package chess; +import chess.position.Column; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/chess/Fixtures.java b/src/test/java/chess/Fixtures.java index f940ab37137..64cac0f44f1 100644 --- a/src/test/java/chess/Fixtures.java +++ b/src/test/java/chess/Fixtures.java @@ -1,5 +1,9 @@ package chess; +import chess.position.Column; +import chess.position.Position; +import chess.position.Row; + @SuppressWarnings("unused") public final class Fixtures { diff --git a/src/test/java/chess/PositionTest.java b/src/test/java/chess/PositionTest.java index 3ad7cc64084..02384b050db 100644 --- a/src/test/java/chess/PositionTest.java +++ b/src/test/java/chess/PositionTest.java @@ -1,5 +1,7 @@ package chess; +import chess.position.Movement; +import chess.position.Position; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/chess/RowTest.java b/src/test/java/chess/RowTest.java index fcb65485410..62d98ca8de9 100644 --- a/src/test/java/chess/RowTest.java +++ b/src/test/java/chess/RowTest.java @@ -1,5 +1,6 @@ package chess; +import chess.position.Row; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/chess/piece/BishopTest.java b/src/test/java/chess/piece/BishopTest.java index 769ada9263c..994f88a628c 100644 --- a/src/test/java/chess/piece/BishopTest.java +++ b/src/test/java/chess/piece/BishopTest.java @@ -3,9 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import chess.Color; +import chess.position.Color; import chess.Fixtures; -import chess.Position; +import chess.position.Position; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/chess/piece/KingTest.java b/src/test/java/chess/piece/KingTest.java index 90de6023dd6..7c86c524698 100644 --- a/src/test/java/chess/piece/KingTest.java +++ b/src/test/java/chess/piece/KingTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import chess.Color; +import chess.position.Color; import chess.Fixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/chess/piece/KnightTest.java b/src/test/java/chess/piece/KnightTest.java index 7fb0aac50e4..ff0b3a341f7 100644 --- a/src/test/java/chess/piece/KnightTest.java +++ b/src/test/java/chess/piece/KnightTest.java @@ -3,9 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import chess.Color; +import chess.position.Color; import chess.Fixtures; -import chess.Position; +import chess.position.Position; import java.util.stream.Stream; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; diff --git a/src/test/java/chess/piece/PawnTest.java b/src/test/java/chess/piece/PawnTest.java index f1315e35129..ff30f2292a2 100644 --- a/src/test/java/chess/piece/PawnTest.java +++ b/src/test/java/chess/piece/PawnTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import chess.Color; +import chess.position.Color; import chess.Fixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; diff --git a/src/test/java/chess/piece/QueenTest.java b/src/test/java/chess/piece/QueenTest.java index af554b39ec5..cb3294b6a2d 100644 --- a/src/test/java/chess/piece/QueenTest.java +++ b/src/test/java/chess/piece/QueenTest.java @@ -3,9 +3,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import chess.Color; +import chess.position.Color; import chess.Fixtures; -import chess.Position; +import chess.position.Position; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; diff --git a/src/test/java/chess/piece/RookTest.java b/src/test/java/chess/piece/RookTest.java index 40507b35d88..035a5834ad6 100644 --- a/src/test/java/chess/piece/RookTest.java +++ b/src/test/java/chess/piece/RookTest.java @@ -3,7 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; -import chess.Color; +import chess.position.Color; import chess.Fixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; From 04238167dfa409d9cffae7ae5b451009261004ef Mon Sep 17 00:00:00 2001 From: sung-june27 Date: Sat, 22 Mar 2025 19:24:30 +0900 Subject: [PATCH 15/15] =?UTF-8?q?feat:=20=EA=B2=BD=EB=A1=9C=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EA=B8=B0=EB=8A=A5=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/chess/board/Board.java | 9 ++++ src/main/java/chess/piece/Bishop.java | 30 +++++++++++ src/main/java/chess/piece/King.java | 7 +++ src/main/java/chess/piece/Knight.java | 7 +++ src/main/java/chess/piece/Pawn.java | 7 +++ src/main/java/chess/piece/Piece.java | 3 ++ src/main/java/chess/piece/Queen.java | 65 ++++++++++++++++++++++++ src/main/java/chess/piece/Rook.java | 32 ++++++++++++ src/main/java/chess/view/OutputView.java | 2 +- 9 files changed, 161 insertions(+), 1 deletion(-) diff --git a/src/main/java/chess/board/Board.java b/src/main/java/chess/board/Board.java index 91ed704a5da..2d14efa668a 100644 --- a/src/main/java/chess/board/Board.java +++ b/src/main/java/chess/board/Board.java @@ -4,6 +4,7 @@ import chess.piece.Piece; import chess.piece.Pieces; import java.util.List; +import java.util.Set; public class Board { @@ -23,6 +24,14 @@ public void move(Position current, Position destination) { throw new IllegalArgumentException("같은 팀이 있는 위치로는 이동할 수 없습니다."); } } + + Set path = pickedPiece.calculatePath(differenceX, differenceY); + boolean existsPieceOnPath = path.stream() + .anyMatch(pieces::existsByPosition); + if (existsPieceOnPath) { + throw new IllegalArgumentException("경로 상에 말이 존재합니다"); + } + pickedPiece.move(differenceX, differenceY); } diff --git a/src/main/java/chess/piece/Bishop.java b/src/main/java/chess/piece/Bishop.java index a067de5c42c..6447449e011 100644 --- a/src/main/java/chess/piece/Bishop.java +++ b/src/main/java/chess/piece/Bishop.java @@ -2,6 +2,8 @@ import chess.position.Color; import chess.position.Position; +import java.util.HashSet; +import java.util.Set; public class Bishop extends Piece { @@ -9,6 +11,7 @@ public Bishop(final Color color, final Position position) { super(color, position); } + @Override public void move(final int x, final int y) { if (Math.abs(x) != Math.abs(y)) { throw new IllegalArgumentException("대각선으로만 이동 가능합니다."); @@ -21,4 +24,31 @@ public void move(final int x, final int y) { } throw new IllegalArgumentException("이동할 수 없습니다"); } + + @Override + public Set calculatePath(final int x, final int y) { + Set path = new HashSet<>(); + int step = Math.abs(x); + if (x > 0 && y > 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveRightUp()); + } + } + if (x > 0 && y < 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveRightDown()); + } + } + if (x < 0 && y > 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveLeftUp()); + } + } + if (x < 0 && y < 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveLeftDown()); + } + } + return path; + } } diff --git a/src/main/java/chess/piece/King.java b/src/main/java/chess/piece/King.java index be5a7c4b5f2..ee1dbd9da1a 100644 --- a/src/main/java/chess/piece/King.java +++ b/src/main/java/chess/piece/King.java @@ -2,6 +2,7 @@ import chess.position.Color; import chess.position.Position; +import java.util.Set; public class King extends Piece { @@ -9,6 +10,7 @@ public King(final Color color, final Position position) { super(color, position); } + @Override public void move(final int x, final int y) { if (x > 1 || y > 1) { throw new IllegalArgumentException("한 칸만 이동 가능합니다"); @@ -24,4 +26,9 @@ public void move(final int x, final int y) { } throw new IllegalArgumentException("움직일 수 없습니다."); } + + @Override + public Set calculatePath(int x, int y) { + return Set.of(); + } } diff --git a/src/main/java/chess/piece/Knight.java b/src/main/java/chess/piece/Knight.java index ee83837cb78..1cb6ad9e22c 100644 --- a/src/main/java/chess/piece/Knight.java +++ b/src/main/java/chess/piece/Knight.java @@ -2,6 +2,7 @@ import chess.position.Color; import chess.position.Position; +import java.util.Set; public class Knight extends Piece { @@ -9,6 +10,7 @@ public Knight(Color color, Position position) { super(color, position); } + @Override public void move(final int x, final int y) { boolean canMove = position.canMoveHorizontal(x) && position.canMoveVertical(y); @@ -19,6 +21,11 @@ public void move(final int x, final int y) { throw new IllegalArgumentException("이동할 수 없습니다."); } + @Override + public Set calculatePath(int x, int y) { + return Set.of(); + } + private boolean isMovingRule(final int x, final int y) { int absX = Math.abs(x); int absY = Math.abs(y); diff --git a/src/main/java/chess/piece/Pawn.java b/src/main/java/chess/piece/Pawn.java index de828ba9606..25cd704687d 100644 --- a/src/main/java/chess/piece/Pawn.java +++ b/src/main/java/chess/piece/Pawn.java @@ -3,6 +3,7 @@ import chess.position.Color; import chess.position.Position; import chess.position.Row; +import java.util.Set; public class Pawn extends Piece { @@ -10,6 +11,7 @@ public Pawn(final Color color, final Position position) { super(color, position); } + @Override public void move(final int x, final int y) { boolean canMove = false; if (color == Color.WHITE && y > 0 && y <= 2) { @@ -37,4 +39,9 @@ public void move(final int x, final int y) { } throw new IllegalArgumentException("이동할 수 없습니다."); } + + @Override + public Set calculatePath(int x, int y) { + return Set.of(); + } } diff --git a/src/main/java/chess/piece/Piece.java b/src/main/java/chess/piece/Piece.java index dc5e9015f1d..edcb31eabbd 100644 --- a/src/main/java/chess/piece/Piece.java +++ b/src/main/java/chess/piece/Piece.java @@ -2,6 +2,7 @@ import chess.position.Color; import chess.position.Position; +import java.util.Set; public abstract class Piece { @@ -19,6 +20,8 @@ public boolean isSameColor(Piece other) { public abstract void move(int x, int y); + public abstract Set calculatePath(int x, int y); + public Color getColor() { return color; } diff --git a/src/main/java/chess/piece/Queen.java b/src/main/java/chess/piece/Queen.java index eacad2c90b2..623f6f05409 100644 --- a/src/main/java/chess/piece/Queen.java +++ b/src/main/java/chess/piece/Queen.java @@ -2,6 +2,8 @@ import chess.position.Color; import chess.position.Position; +import java.util.HashSet; +import java.util.Set; public class Queen extends Piece { @@ -9,6 +11,7 @@ public Queen(final Color color, final Position position) { super(color, position); } + @Override public void move(final int x, final int y) { if (x == 0 || y == 0) { moveHorizontalOrVertical(x, y); @@ -50,4 +53,66 @@ private void moveDiagonal(final int x, final int y) { } throw new IllegalArgumentException("이동할 수 없습니다"); } + + @Override + public Set calculatePath(final int x, final int y) { + if (x != 0 && y != 0) { + return calculateDiagonalPath(x, y); + } + return calculateHorizontalOrVerticalPath(x, y); + } + + public Set calculateDiagonalPath(final int x, final int y) { + Set path = new HashSet<>(); + int step = Math.abs(x); + if (x > 0 && y > 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveRightUp()); + } + } + if (x > 0 && y < 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveRightDown()); + } + } + if (x < 0 && y > 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveLeftUp()); + } + } + if (x < 0 && y < 0) { + for (int i = 0; i < step; i++) { + path.add(position.moveLeftDown()); + } + } + return path; + } + + public Set calculateHorizontalOrVerticalPath(final int x, final int y) { + Set path = new HashSet<>(); + int horizontalStep = Math.abs(x); + if (x > 0) { + for (int i = 0; i < horizontalStep; i++) { + path.add(position.moveRight()); + } + } + if (x < 0) { + for (int i = 0; i < horizontalStep; i++) { + path.add(position.moveLeftDown()); + } + } + + int verticalStep = Math.abs(y); + if (y > 0) { + for (int i = 0; i < verticalStep; i++) { + path.add(position.moveUp()); + } + } + if (y < 0) { + for (int i = 0; i < verticalStep; i++) { + path.add(position.moveRightDown()); + } + } + return path; + } } diff --git a/src/main/java/chess/piece/Rook.java b/src/main/java/chess/piece/Rook.java index 82c85b4cc35..b44a78fae67 100644 --- a/src/main/java/chess/piece/Rook.java +++ b/src/main/java/chess/piece/Rook.java @@ -2,6 +2,8 @@ import chess.position.Color; import chess.position.Position; +import java.util.HashSet; +import java.util.Set; public class Rook extends Piece { @@ -9,6 +11,7 @@ public Rook(final Color color, final Position position) { super(color, position); } + @Override public void move(final int x, final int y) { if (x != 0 && y != 0) { throw new IllegalArgumentException("대각선으로는 이동할 수 없습니다."); @@ -32,4 +35,33 @@ public void move(final int x, final int y) { } throw new IllegalArgumentException("이동할 수 없습니다."); } + + @Override + public Set calculatePath(final int x, final int y) { + Set path = new HashSet<>(); + int horizontalStep = Math.abs(x); + if (x > 0) { + for (int i = 0; i < horizontalStep; i++) { + path.add(position.moveRight()); + } + } + if (x < 0) { + for (int i = 0; i < horizontalStep; i++) { + path.add(position.moveLeftDown()); + } + } + + int verticalStep = Math.abs(y); + if (y > 0) { + for (int i = 0; i < verticalStep; i++) { + path.add(position.moveUp()); + } + } + if (y < 0) { + for (int i = 0; i < verticalStep; i++) { + path.add(position.moveRightDown()); + } + } + return path; + } } diff --git a/src/main/java/chess/view/OutputView.java b/src/main/java/chess/view/OutputView.java index 8d2d1fc833b..72d9195c605 100644 --- a/src/main/java/chess/view/OutputView.java +++ b/src/main/java/chess/view/OutputView.java @@ -29,7 +29,7 @@ public static void printBoard(Board board) { for (int j = 0; j < boardOutput.length; j++) { System.out.printf("%s\t", boardOutput[i][j]); } - System.out.printf("\t%d%n", i + 1); + System.out.printf("\t%d%n", 8 - i); } System.out.println(); System.out.println("A\tB\tC\tD\tE\tF\tG\tH");