diff --git a/README.md b/README.md index ba64ac01dd..98fd6cf41f 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,20 @@ - 이동 위치는 “1,1”와 같이 좌표형태의 숫자값만 입력으로 들어올 수 있다. 좌표는 쉼표로 구분한다. - 추가적으로 “한수쉼”이 들어올 수 있다. +## 2-3. 기물 점수 규칙 +- 현재 장기판에 남아있는 기물들의 각 점수를 합산하여, 현재 점수를 계산한다. +- 각 기물의 점수는 중요도 순으로 높은 배점을 가지며, 각 점수는 다음과 같다. + +| 기물 | 점수 | +|-----|----------------| +| 궁 | 0점(점수 계산에서 배제) | +| 차 | 13점 | +| 포 | 7점 | +| 마 | 5점 | +| 상 | 3점 | +| 사 | 3점 | +| 졸(병) | 2점 | + # 3. 용어 사전 ### 3-1. 기본 용어 diff --git a/src/main/java/controller/JanggiController.java b/src/main/java/controller/JanggiController.java index debb3f655e..cb2ffdcef6 100644 --- a/src/main/java/controller/JanggiController.java +++ b/src/main/java/controller/JanggiController.java @@ -3,12 +3,16 @@ import controller.dto.CurrentBoardStatus; import controller.dto.MovedPieceRequest; import domain.GameManager; +import domain.HorseElephantFormation; import domain.Team; import exception.GameExceptionHandler; import exception.custom.GameException; + import java.util.HashMap; import java.util.List; import java.util.Map; +import strategy.InitializeStrategy; + import view.InputView; import view.OutputView; @@ -26,8 +30,9 @@ public JanggiController(GameExceptionHandler gameExceptionHandler, InputView inp public void start() { Map horseElephantFormations = readHorseElephantFormation(); - startJanggiGame(horseElephantFormations); - playJanggiGame(); + initializeJanggiGame(horseElephantFormations); + Team winnerTeam = playJanggiGame(); + printGameWinner(winnerTeam); } private Map readHorseElephantFormation() { @@ -38,24 +43,40 @@ private Map readHorseElephantFormation() { return horseElephantInputs; } - private void startJanggiGame(Map horseElephantFormations) { - this.gameManager = new GameManager(horseElephantFormations); + /** + * 1. 장기 게임 초기화 + */ + private void initializeJanggiGame(Map horseElephantFormations) { + this.gameManager = new GameManager(toInitializeStrategies(horseElephantFormations)); printCurrentBoardStatus(); } + private Map toInitializeStrategies(Map horseElephantFormations) { + Map initializeStrategies = new HashMap<>(); + horseElephantFormations.forEach( + (team, formation) -> initializeStrategies.put(team, getBoardInitializeStrategy(formation)) + ); + return initializeStrategies; + } + + private InitializeStrategy getBoardInitializeStrategy(String formationInput) { + return HorseElephantFormation.getStrategy(formationInput); + } + private void printCurrentBoardStatus() { List statuses = gameManager.getCurrentBoardStatus(); outputView.printCurrentBoard(statuses); } - private void playJanggiGame() { - /** - * TODO: 2차 사이클 - 게임 종료 조건 추가 예정 - */ - while (true) { - playTurn(Team.CHO); - playTurn(Team.HAN); + private Team playJanggiGame() { + Team currentTeam = Team.CHO; + + while (!gameManager.isGameFinished(currentTeam)) { + playTurn(currentTeam); + currentTeam = switchTeam(currentTeam); } + + return switchTeam(currentTeam); } private void playTurn(Team team) { @@ -69,6 +90,17 @@ private void playTurn(Team team) { } } + private Team switchTeam(Team team) { + if (team == Team.CHO) { + return Team.HAN; + } + return Team.CHO; + } + + private void printGameWinner(Team team) { + outputView.printGameWinner(team.getKoreanName()); + } + private void movePiece(Team team) { MovedPieceRequest movedPieceRequest = readMovedPiece(); gameManager.movePiece(movedPieceRequest, team); diff --git a/src/main/java/domain/Board.java b/src/main/java/domain/Board.java index eb40bb7602..bd2b048478 100644 --- a/src/main/java/domain/Board.java +++ b/src/main/java/domain/Board.java @@ -16,11 +16,21 @@ public class Board { private static final int MAX_COLUMN = 9; private static final int MIN_COLUMN = 1; + private static final int CHO_PALACE_MAX_ROW = 10; + private static final int CHO_PALACE_MIN_ROW = 8; + private static final int HAN_PALACE_MAX_ROW = 3; + private static final int HAN_PALACE_MIN_ROW = 1; + private static final int PALACE_MAX_COLUMN = 6; + private static final int PALACE_MIN_COLUMN = 4; + + private static final Position CHO_PALACE_CENTER = Position.from(9, 5); + private static final Position HAN_PALACE_CENTER = Position.from(2, 5); + protected final Map pieces = new HashMap<>(); - public Board(InitializeStrategy choInitializeStrategy, InitializeStrategy hanInitializeStrategy) { - initTeamBoard(choInitializeStrategy, Team.CHO); - initTeamBoard(hanInitializeStrategy, Team.HAN); + public Board(Map initializeStrategies) { + initializeStrategies.forEach(((team, initializeStrategy) -> + initTeamBoard(initializeStrategy, team))); } public void move(Position from, Position to, PieceType pieceType, Team team) { @@ -72,6 +82,26 @@ public List getCurrentStatus() { return currentBoardStatuses; } + public boolean isInPalace(Team team, Position target) { + if (Team.CHO == team) { + return target.isPossiblePosition(CHO_PALACE_MAX_ROW, CHO_PALACE_MIN_ROW, PALACE_MAX_COLUMN, + PALACE_MIN_COLUMN); + } + return target.isPossiblePosition(HAN_PALACE_MAX_ROW, HAN_PALACE_MIN_ROW, PALACE_MAX_COLUMN, PALACE_MIN_COLUMN); + } + + public boolean isCenterPositionInPalace(Team team, Position target) { + if (Team.CHO == team) { + return CHO_PALACE_CENTER.isSamePosition(target); + } + return HAN_PALACE_CENTER.isSamePosition(target); + } + + public boolean isExistPiece(PieceType target, Team team) { + return pieces.values().stream() + .anyMatch(piece -> piece.getType() == target && piece.getTeam() == team); + } + /** * 헬퍼 메서드 */ diff --git a/src/main/java/domain/GameManager.java b/src/main/java/domain/GameManager.java index 8ff48173b7..a69c3b5a87 100644 --- a/src/main/java/domain/GameManager.java +++ b/src/main/java/domain/GameManager.java @@ -9,11 +9,8 @@ public class GameManager { private final Board board; - public GameManager(Map formationInput) { - this.board = new Board( - getBoardInitializeStrategy(formationInput.get(Team.CHO)), - getBoardInitializeStrategy(formationInput.get(Team.HAN)) - ); + public GameManager(Map initializeStrategies) { + this.board = new Board(initializeStrategies); } public List getCurrentBoardStatus() { @@ -27,10 +24,7 @@ public void movePiece(MovedPieceRequest request, Team team) { team); } - /** - * 헬퍼 메서드 - */ - private InitializeStrategy getBoardInitializeStrategy(String formationInput) { - return HorseElephantFormation.getStrategy(formationInput); + public boolean isGameFinished(Team currentTeam) { + return !board.isExistPiece(PieceType.KING, currentTeam); } } diff --git a/src/main/java/domain/Position.java b/src/main/java/domain/Position.java index bb70276cef..d001b463ef 100644 --- a/src/main/java/domain/Position.java +++ b/src/main/java/domain/Position.java @@ -57,6 +57,10 @@ public boolean isSameRow(Position other) { return false; } + public boolean isSamePosition(Position other){ + return other.row == row && other.column == column; + } + public boolean isPossiblePosition(int maxRow, int minRow, int maxColumn, int minColumn) { if (this.row > maxRow || this.row < minRow) { return false; diff --git a/src/main/java/domain/piece/Guard.java b/src/main/java/domain/piece/Guard.java index 7f62b936d1..5d859c0c86 100644 --- a/src/main/java/domain/piece/Guard.java +++ b/src/main/java/domain/piece/Guard.java @@ -12,7 +12,15 @@ public Guard(Team team) { @Override public boolean canMove(Position from, Position to, Board board) { - if (!isCorrectMoveDistanceAndDirection(from, to)) { + if (!isPossiblePosition(to, board)) { + return false; + } + + if (!isCorrectMoveDistance(from, to)) { + return false; + } + + if (!isCorrectDirection(from, to, board)) { return false; } @@ -23,11 +31,30 @@ public boolean canMove(Position from, Position to, Board board) { return !board.hasSameTeamOn(to, this); } - private boolean isEmptySpace(Position to, Board board) { - return board.isEmpty(to); + private boolean isPossiblePosition(Position to, Board board) { + return board.isInPalace(this.team, to); } - private boolean isCorrectMoveDistanceAndDirection(Position from, Position to) { + private boolean isCorrectMoveDistance(Position from, Position to) { return Math.abs(from.columnDistanceTo(to)) == 1 || Math.abs(from.rowDistanceTo(to)) == 1; } + + private boolean isCorrectDirection(Position from, Position to, Board board) { + // 1. 출발지가 정중앙인 경우, 궁성 내 어디든지 이동 가능 + if (board.isCenterPositionInPalace(team, from)) { + return true; + } + + // 2. 출발지가 정중앙이 아닌 경우, 중앙으로 이동 가능 + if (board.isCenterPositionInPalace(team, to)) { + return true; + } + + // 3. 출발지가 정중앙이 아닌 경우, 상하좌우로 이동 가능 + return !(Math.abs(from.columnDistanceTo(to)) == 1 && Math.abs(from.rowDistanceTo(to)) == 1); + } + + private boolean isEmptySpace(Position to, Board board) { + return board.isEmpty(to); + } } diff --git a/src/main/java/domain/piece/King.java b/src/main/java/domain/piece/King.java index 089e8f711c..7757b7bcf7 100644 --- a/src/main/java/domain/piece/King.java +++ b/src/main/java/domain/piece/King.java @@ -12,7 +12,15 @@ public King(Team team) { @Override public boolean canMove(Position from, Position to, Board board) { - if (!isCorrectMoveDistanceAndDirection(from, to)) { + if (!isPossiblePosition(to, board)) { + return false; + } + + if (!isCorrectMoveDistance(from, to)) { + return false; + } + + if (!isCorrectDirection(from, to, board)) { return false; } @@ -23,11 +31,30 @@ public boolean canMove(Position from, Position to, Board board) { return !board.hasSameTeamOn(to, this); } - private boolean isEmptySpace(Position to, Board board) { - return board.isEmpty(to); + private boolean isPossiblePosition(Position to, Board board) { + return board.isInPalace(this.team, to); } - private boolean isCorrectMoveDistanceAndDirection(Position from, Position to) { + private boolean isCorrectMoveDistance(Position from, Position to) { return Math.abs(from.columnDistanceTo(to)) == 1 || Math.abs(from.rowDistanceTo(to)) == 1; } + + private boolean isCorrectDirection(Position from, Position to, Board board) { + // 1. 출발지가 정중앙인 경우, 궁성 내 어디든지 이동 가능 + if (board.isCenterPositionInPalace(team, from)) { + return true; + } + + // 2. 출발지가 정중앙이 아닌 경우, 중앙으로 이동 가능 + if (board.isCenterPositionInPalace(team, to)) { + return true; + } + + // 3. 출발지가 정중앙이 아닌 경우, 상하좌우로 이동 가능 + return !(Math.abs(from.columnDistanceTo(to)) == 1 && Math.abs(from.rowDistanceTo(to)) == 1); + } + + private boolean isEmptySpace(Position to, Board board) { + return board.isEmpty(to); + } } diff --git a/src/main/java/view/OutputView.java b/src/main/java/view/OutputView.java index 1edaa741db..1f7895bb6a 100644 --- a/src/main/java/view/OutputView.java +++ b/src/main/java/view/OutputView.java @@ -4,6 +4,8 @@ import java.util.List; public class OutputView { + private static final String GAME_WINNER_GUIDE = "장기 게임이 종료되었습니다. 게임의 우승자는 %s나라 입니다."; + private static final int BOARD_ROW_SIZE = 10; private static final int BOARD_COLUMN_SIZE = 9; private static final String EMPTY_CELL = " "; @@ -29,10 +31,13 @@ public void printErrorMessage(String message){ System.out.println(message); } + public void printGameWinner(String winner) { + System.out.println(String.format(GAME_WINNER_GUIDE, winner)); + } + /** * 헬퍼 메서드 */ - private String[][] createEmptyBoard() { String[][] board = new String[BOARD_ROW_SIZE][BOARD_COLUMN_SIZE]; diff --git a/src/test/java/domain/BoardTest.java b/src/test/java/domain/BoardTest.java index eeafc29ca1..c20fb043cd 100644 --- a/src/test/java/domain/BoardTest.java +++ b/src/test/java/domain/BoardTest.java @@ -10,6 +10,10 @@ import domain.piece.Rook; import domain.strategy.NoInitializeStrategy; import domain.stub.StubBoard; + +import exception.GameErrorMessage; +import exception.custom.InvalidGameInputException; + import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -37,12 +41,17 @@ protected Map initializeElephantHorseFormation(Team team) { } } + public Map createStrategies(InitializeStrategy choInitializeStrategy, + InitializeStrategy hanInitializeStrategy){ + return Map.of(Team.CHO, choInitializeStrategy, Team.HAN, hanInitializeStrategy); + } + /** * 1. 한나라 기본 기물이 올바르게 배치된다.(상,마 제외) */ @Test void 한나라_기본_기물들이_올바르게_배치된다() { - Board board = new Board(noElephantHorseStrategy, noElephantHorseStrategy); + Board board = new Board(createStrategies(noElephantHorseStrategy, noElephantHorseStrategy)); assertThat(board.isExistSameType(Position.from(1, 1), new Rook(Team.HAN))).isEqualTo(true); assertThat(board.isExistSameType(Position.from(1, 9), new Rook(Team.HAN))).isEqualTo(true); @@ -65,7 +74,7 @@ protected Map initializeElephantHorseFormation(Team team) { */ @Test void 초나라_기본_기물들이_올바르게_배치된다() { - Board board = new Board(noElephantHorseStrategy, noElephantHorseStrategy); + Board board = new Board(createStrategies(noElephantHorseStrategy, noElephantHorseStrategy)); assertThat(board.isExistSameType(Position.from(10, 1), new Rook(Team.CHO))).isEqualTo(true); assertThat(board.isExistSameType(Position.from(10, 4), new Guard(Team.CHO))).isEqualTo(true); @@ -95,7 +104,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new LeftElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position choFirstElephant = Position.from(10, 2); @@ -118,7 +127,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new OuterElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position choFirstElephant = Position.from(10, 2); @@ -141,7 +150,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new RightElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position choFirstElephant = Position.from(10, 3); @@ -164,7 +173,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new InnerElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position choFirstElephant = Position.from(10, 3); @@ -187,7 +196,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new LeftElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position hanFirstElephant = Position.from(1, 3); @@ -210,7 +219,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new OuterElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position hanFirstElephant = Position.from(1, 2); @@ -233,7 +242,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new RightElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position hanFirstElephant = Position.from(1, 2); @@ -256,7 +265,7 @@ protected Map initializeElephantHorseFormation(Team team) { InitializeStrategy strategy = new InnerElephantFormationStrategy(); // when - Board board = new Board(strategy, strategy); + Board board = new Board(createStrategies(strategy, strategy)); // then Position hanFirstElephant = Position.from(1, 3); @@ -285,9 +294,9 @@ protected Map initializeElephantHorseFormation(Team team) { Position to = Position.from(5, 2); // then - assertThatThrownBy(() -> board.move(from, to, targetType)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("해당 위치에 피스가 없습니다."); + assertThatThrownBy(() -> board.move(from, to, targetType, Team.CHO)) + .isInstanceOf(InvalidGameInputException.class) + .hasMessage(GameErrorMessage.PIECE_NOT_FOUND.getMessage()); } @Test @@ -306,9 +315,10 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatThrownBy(() -> board.move(from, to, targetType)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("해당 위치에 해당 타입이 없습니다."); + assertThatThrownBy(() -> board.move(from, to, targetType, Team.CHO)) + .isInstanceOf(InvalidGameInputException.class) + .hasMessage( + String.format(GameErrorMessage.INVALID_PIECE_TYPE.getMessage(), targetType.getKoreanName())); } @Test @@ -327,9 +337,9 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatThrownBy(() -> board.move(from, to, targetType)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("기물의 도착지점이 판 범위를 넘어섰습니다."); + assertThatThrownBy(() -> board.move(from, to, targetType, Team.CHO)) + .isInstanceOf(InvalidGameInputException.class) + .hasMessage(GameErrorMessage.INVALID_POSITION_RANGE.getMessage()); } /** @@ -352,7 +362,7 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PieceType.CANNON)) + assertThatCode(() -> board.move(from, to, PieceType.CANNON, Team.CHO)) .doesNotThrowAnyException(); } @@ -371,7 +381,7 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PieceType.ROOK)) + assertThatCode(() -> board.move(from, to, PieceType.ROOK, Team.CHO)) .doesNotThrowAnyException(); } @@ -381,8 +391,8 @@ protected Map initializeElephantHorseFormation(Team team) { StubBoard board = new StubBoard(noInitializeStrategy); // when - Position from = Position.from(7, 4); - Position to = Position.from(6, 4); + Position from = Position.from(10, 4); + Position to = Position.from(9, 4); Map testPiece = new HashMap<>(); testPiece.put(from, new Guard(Team.CHO)); @@ -390,7 +400,7 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PieceType.GUARD)) + assertThatCode(() -> board.move(from, to, PieceType.GUARD, Team.CHO)) .doesNotThrowAnyException(); } @@ -400,8 +410,8 @@ protected Map initializeElephantHorseFormation(Team team) { StubBoard board = new StubBoard(noInitializeStrategy); // when - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(9, 5); + Position to = Position.from(8, 5); Map testPiece = new HashMap<>(); testPiece.put(from, new King(Team.CHO)); @@ -409,7 +419,7 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PieceType.KING)) + assertThatCode(() -> board.move(from, to, PieceType.KING, Team.CHO)) .doesNotThrowAnyException(); } @@ -428,7 +438,7 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PAWN)) + assertThatCode(() -> board.move(from, to, PAWN, Team.CHO)) .doesNotThrowAnyException(); } @@ -447,7 +457,7 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PieceType.HORSE)) + assertThatCode(() -> board.move(from, to, PieceType.HORSE, Team.CHO)) .doesNotThrowAnyException(); } @@ -465,7 +475,55 @@ protected Map initializeElephantHorseFormation(Team team) { board.putPieces(testPiece); // then - assertThatCode(() -> board.move(from, to, PieceType.ELEPHANT)) + assertThatCode(() -> board.move(from, to, PieceType.ELEPHANT, Team.CHO)) .doesNotThrowAnyException(); } + + /** + * 보드에 궁 존재 여부 확인 테스트(게임 종료 조건에서 활용) + */ + @Test + void 초나라의_궁이_보드판에_존재하는_경우_정상테스트() { + StubBoard board = new StubBoard(noInitializeStrategy); + + // when + Position position = Position.from(9, 5); + + Map testPiece = new HashMap<>(); + testPiece.put(position, new King(Team.CHO)); + board.putPieces(testPiece); + + // then + assertThat(board.isExistPiece(PieceType.KING, Team.CHO)).isEqualTo(true); + } + + @Test + void 한나라의_궁이_보드판에_존재하는_경우_정상테스트() { + StubBoard board = new StubBoard(noInitializeStrategy); + + // when + Position position = Position.from(2, 5); + + Map testPiece = new HashMap<>(); + testPiece.put(position, new King(Team.HAN)); + board.putPieces(testPiece); + + // then + assertThat(board.isExistPiece(PieceType.KING, Team.HAN)).isEqualTo(true); + } + + @Test + void 초나라의_궁이_보드판에_존재하지_않는_경우_정상테스트() { + StubBoard board = new StubBoard(noInitializeStrategy); + + // then + assertThat(board.isExistPiece(PieceType.KING, Team.CHO)).isEqualTo(false); + } + + @Test + void 한나라의_궁이_보드판에_존재하지_않는_경우_정상테스트() { + StubBoard board = new StubBoard(noInitializeStrategy); + + assertThat(board.isExistPiece(PieceType.KING, Team.HAN)).isEqualTo(false); + } } diff --git a/src/test/java/domain/GameManagerTest.java b/src/test/java/domain/GameManagerTest.java new file mode 100644 index 0000000000..ffa8b704d6 --- /dev/null +++ b/src/test/java/domain/GameManagerTest.java @@ -0,0 +1,80 @@ +package domain; + +import static org.assertj.core.api.Assertions.assertThat; + +import domain.piece.King; +import domain.piece.Piece; +import domain.strategy.NoInitializeStrategy; +import java.util.Map; +import org.junit.jupiter.api.Test; +import strategy.InitializeStrategy; + +class GameManagerTest { + private final InitializeStrategy noInitializeStrategy = new NoInitializeStrategy(); + private final InitializeStrategy onlyChosKingExistInitializeStrategy = new OnlyChosKingExistInitializeStrategy(); + private final InitializeStrategy onlyHansKingExistInitializeStrategy = new OnlyHansKingExistInitializeStrategy(); + + static class OnlyChosKingExistInitializeStrategy extends InitializeStrategy { + @Override + protected Map initializeElephantHorseFormation(Team team) { + Position position = Position.from(9, 5); + return Map.of(position, new King(Team.CHO)); + } + } + + static class OnlyHansKingExistInitializeStrategy extends InitializeStrategy { + @Override + protected Map initializeElephantHorseFormation(Team team) { + Position position = Position.from(2, 5); + return Map.of(position, new King(Team.HAN)); + } + } + + @Test + void 초나라_턴인_경우_초나라의_궁이_존재하지_않는_경우_게임_종료() { + //given + GameManager gameManager = new GameManager(Map.of( + Team.CHO, noInitializeStrategy, + Team.HAN, noInitializeStrategy + )); + + //then + assertThat(gameManager.isGameFinished(Team.CHO)).isEqualTo(true); + } + + @Test + void 한나라_턴인_경우_한나라의_궁이_존재하지_않는_경우_게임_종료() { + //given + GameManager gameManager = new GameManager(Map.of( + Team.CHO, noInitializeStrategy, + Team.HAN, noInitializeStrategy + )); + + //then + assertThat(gameManager.isGameFinished(Team.HAN)).isEqualTo(true); + } + + @Test + void 초나라_턴인_경우_초나라의_궁이_존재하는_경우_게임_진행() { + //given + GameManager gameManager = new GameManager(Map.of( + Team.CHO, onlyChosKingExistInitializeStrategy, + Team.HAN, onlyChosKingExistInitializeStrategy + )); + + //then + assertThat(gameManager.isGameFinished(Team.CHO)).isEqualTo(false); + } + + @Test + void 한나라_턴인_경우_한나라의_궁이_존재하는_경우_게임_진행() { + //given + GameManager gameManager = new GameManager(Map.of( + Team.CHO, onlyChosKingExistInitializeStrategy, + Team.HAN, onlyChosKingExistInitializeStrategy + )); + + //then + assertThat(gameManager.isGameFinished(Team.HAN)).isEqualTo(false); + } +} diff --git a/src/test/java/domain/piece/GuardTest.java b/src/test/java/domain/piece/GuardTest.java index 30bae03687..29779644f6 100644 --- a/src/test/java/domain/piece/GuardTest.java +++ b/src/test/java/domain/piece/GuardTest.java @@ -25,8 +25,8 @@ class GuardTest { Piece guard = new Guard(Team.CHO); // when - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(10, 4); + Position to = Position.from(10, 5); // then assertThat(guard.canMove(from, to, board)).isEqualTo(true); @@ -42,8 +42,8 @@ class GuardTest { Piece guard = new Guard(Team.CHO); // when - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(10, 4); + Position to = Position.from(9, 4); // then assertThat(guard.canMove(from, to, board)).isEqualTo(true); @@ -59,12 +59,133 @@ class GuardTest { StubBoard board = new StubBoard(strategy); Piece guard = new Guard(Team.CHO); - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(10, 4); + Position to = Position.from(9, 4); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new Guard(Team.CHO)); + testPiece.put(to, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(guard.canMove(from, to, board)).isEqualTo(false); + } + + + /** + * 이동 경로가 1칸 초과인 경우 이동할 수 없다. + */ + @Test + void 이동_경로가_1칸_초과인_경우_이동할_수_없다() { + // given + StubBoard board = new StubBoard(strategy); + Piece guard = new Guard(Team.CHO); + + Position from = Position.from(10, 4); + Position to = Position.from(8, 4); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new Guard(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(guard.canMove(from, to, board)).isEqualTo(false); + } + + /** + * 도착지가 궁성을 벗어나면 이동할 수 없다. + */ + @Test + void 도착지가_궁성을_벗어나면_이동할_수_없다() { + // given + StubBoard board = new StubBoard(strategy); + Piece guard = new Guard(Team.CHO); + + Position from = Position.from(10, 4); + Position to = Position.from(10, 3); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new Guard(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(guard.canMove(from, to, board)).isEqualTo(false); + } + + /** + * 궁성의 중앙에서 출발하는 경우, 궁성 내부 어디로든 이동할 수 있다. + */ + @Test + void 궁성의_중앙에서_출발하는_경우_궁성_내부_어디로든_이동할_수_있다() { + // given + StubBoard board = new StubBoard(strategy); + Piece guard = new Guard(Team.CHO); + + Position from = Position.from(9, 5); + Position to = Position.from(8, 6); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new Guard(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(guard.canMove(from, to, board)).isEqualTo(true); + } + + /** + * 출발지가 궁성의 중앙이 아닌 경우, 궁성의 중앙으로 반드시 이동할 수 있다 + */ + @Test + void 출발지가_궁성의_중앙이_아닌_경우_궁성의_중앙으로_반드시_이동할_수_있다() { + // given + StubBoard board = new StubBoard(strategy); + Piece guard = new Guard(Team.CHO); + + Position from = Position.from(9, 4); + Position to = Position.from(9, 5); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new Guard(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(guard.canMove(from, to, board)).isEqualTo(true); + } + + /** + * 궁성의 중앙이 아닌 경우, 궁성의 중앙으로 반드시 이동할 수 있다 + */ + @Test + void 출발지가_궁성의_중앙이_아닌_경우_상하좌우로_이동가능하다() { + // given + StubBoard board = new StubBoard(strategy); + Piece guard = new Guard(Team.CHO); + + Position from = Position.from(9, 4); + Position to = Position.from(8, 4); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new Guard(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(guard.canMove(from, to, board)).isEqualTo(true); + } + + /** + * 궁성의 중앙이 아닌 경우, 궁성의 중앙으로 반드시 이동할 수 있다 + */ + @Test + void 출발지가_궁성의_중앙이_아닌_경우_중앙으로_가는_경로를_제외한_대각선으로_이동이_불가능하다() { + // given + StubBoard board = new StubBoard(strategy); + Piece guard = new Guard(Team.CHO); + + Position from = Position.from(8, 5); + Position to = Position.from(9, 4); Map testPiece = new HashMap<>(); testPiece.put(from, new Guard(Team.CHO)); - testPiece.put(to, new Pawn(Team.CHO)); board.putPieces(testPiece); // when & then diff --git a/src/test/java/domain/piece/KingTest.java b/src/test/java/domain/piece/KingTest.java index 8d387f99ed..5114468f05 100644 --- a/src/test/java/domain/piece/KingTest.java +++ b/src/test/java/domain/piece/KingTest.java @@ -26,8 +26,8 @@ class KingTest { Piece king = new King(Team.CHO); // when - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(9, 5); + Position to = Position.from(9, 4); // then assertThat(king.canMove(from, to, board)).isEqualTo(true); @@ -43,8 +43,8 @@ class KingTest { Piece king = new King(Team.CHO); // when - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(9, 5); + Position to = Position.from(8, 5); // then assertThat(king.canMove(from, to, board)).isEqualTo(true); @@ -63,8 +63,8 @@ class KingTest { StubBoard board = new StubBoard(strategy); Piece king = new King(Team.CHO); - Position from = Position.from(7, 1); - Position to = Position.from(6, 1); + Position from = Position.from(9, 5); + Position to = Position.from(8, 5); Map testPiece = new HashMap<>(); testPiece.put(from, new King(Team.CHO)); @@ -74,4 +74,124 @@ class KingTest { // when & then assertThat(king.canMove(from, to, board)).isEqualTo(false); } + + /** + * 이동 경로가 1칸 초과인 경우 이동할 수 없다. + */ + @Test + void 이동_경로가_1칸_초과인_경우_이동할_수_없다() { + // given + StubBoard board = new StubBoard(strategy); + Piece king = new King(Team.CHO); + + Position from = Position.from(10, 5); + Position to = Position.from(8, 5); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(king.canMove(from, to, board)).isEqualTo(false); + } + + /** + * 도착지가 궁성을 벗어나면 이동할 수 없다. + */ + @Test + void 도착지가_궁성을_벗어나면_이동할_수_없다() { + // given + StubBoard board = new StubBoard(strategy); + Piece king = new King(Team.CHO); + + Position from = Position.from(8, 6); + Position to = Position.from(8, 7); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(king.canMove(from, to, board)).isEqualTo(false); + } + + /** + * 궁성의 중앙에서 출발하는 경우, 궁성 내부 어디로든 이동할 수 있다. + */ + @Test + void 궁성의_중앙에서_출발하는_경우_궁성_내부_어디로든_이동할_수_있다() { + // given + StubBoard board = new StubBoard(strategy); + Piece king = new King(Team.CHO); + + Position from = Position.from(9, 5); + Position to = Position.from(8, 6); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(king.canMove(from, to, board)).isEqualTo(true); + } + + /** + * 출발지가 궁성의 중앙이 아닌 경우, 궁성의 중앙으로 반드시 이동할 수 있다 + */ + @Test + void 출발지가_궁성의_중앙이_아닌_경우_궁성의_중앙으로_반드시_이동할_수_있다() { + // given + StubBoard board = new StubBoard(strategy); + Piece king = new King(Team.CHO); + + Position from = Position.from(9, 4); + Position to = Position.from(9, 5); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(king.canMove(from, to, board)).isEqualTo(true); + } + + /** + * 궁성의 중앙이 아닌 경우, 궁성의 중앙으로 반드시 이동할 수 있다 + */ + @Test + void 출발지가_궁성의_중앙이_아닌_경우_상하좌우로_이동가능하다() { + // given + StubBoard board = new StubBoard(strategy); + Piece king = new King(Team.CHO); + + Position from = Position.from(9, 4); + Position to = Position.from(8, 4); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(king.canMove(from, to, board)).isEqualTo(true); + } + + /** + * 궁성의 중앙이 아닌 경우, 궁성의 중앙으로 반드시 이동할 수 있다 + */ + @Test + void 출발지가_궁성의_중앙이_아닌_경우_중앙으로_가는_경로를_제외한_대각선으로_이동이_불가능하다() { + // given + StubBoard board = new StubBoard(strategy); + Piece king = new King(Team.CHO); + + Position from = Position.from(8, 5); + Position to = Position.from(9, 4); + + Map testPiece = new HashMap<>(); + testPiece.put(from, new King(Team.CHO)); + board.putPieces(testPiece); + + // when & then + assertThat(king.canMove(from, to, board)).isEqualTo(false); + } } diff --git a/src/test/java/domain/stub/StubBoard.java b/src/test/java/domain/stub/StubBoard.java index c5402b384a..505e214a8f 100644 --- a/src/test/java/domain/stub/StubBoard.java +++ b/src/test/java/domain/stub/StubBoard.java @@ -2,13 +2,17 @@ import domain.Board; import domain.Position; +import domain.Team; import domain.piece.Piece; import java.util.Map; import strategy.InitializeStrategy; public class StubBoard extends Board { public StubBoard(InitializeStrategy noInitializeStrategy) { - super(noInitializeStrategy, noInitializeStrategy); + super(Map.of( + Team.CHO, noInitializeStrategy, + Team.HAN, noInitializeStrategy) + ); } public void putPieces(Map pieces) {