Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
fbcdc4a
feat: 비숍 장애물 없는 경우 가능한 목적지 반환 기능
minSsan Mar 22, 2025
46b1bc4
🔴red: 장애물이 존재하는 경우의 비숍 목적지 리스트 반환 테스트 작성
minSsan Mar 22, 2025
791c67a
🟢green: 비숍은 장애물이 존재하는 경우 통과할 수 없다 테스트 통과 코드 작성
minSsan Mar 22, 2025
d75ae49
🛠️refactor: 비숍 목적지 반환 코드 중복 제거
minSsan Mar 22, 2025
0557299
docs(README.md): 비숍 구현사항 체크
minSsan Mar 22, 2025
bf6346a
🔴red: 장애물이 없는 경우 왕은 8개의 방향을 목적지로 선택할 수 있다 테스트 작성
minSsan Mar 22, 2025
9034d44
🟢green: 장애물이 없는 경우 왕은 8개의 방향을 목적지로 선택할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
e2ac774
🛠️refactor: 장애물이 없는 경우 왕의 목적지 반환 코드 리팩터링
minSsan Mar 22, 2025
432c4cd
🔴red: 장애물이 존재하는 경우 왕의 목적지를 반환할 수 있다 테스트 작성
minSsan Mar 22, 2025
92e2fd8
🟢green: 장애물이 존재하는 경우 왕의 목적지를 반환할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
924ce91
docs(README.md): 왕 기물 이동 구현 체크
minSsan Mar 22, 2025
9ad71ed
🔴red: 왕은 같은 팀의 기물이 있는 위치로 이동할 수 없다 테스트 수정
minSsan Mar 22, 2025
865996d
🟢green: 왕은 같은 팀의 기물이 있는 위치로 이동할 수 없다 테스트 통과 로직 작성
minSsan Mar 22, 2025
f0611a7
fix: 비숍의 장애물 존재 테스트 수정 - 같은 팀의 기물이 존재하는 경우와 다른 팀으 기물이 존재하는 경우 분리
minSsan Mar 22, 2025
c7abdf5
🔴red: 비숍 - 다른 팀의 기물이 존재하는 위치까지 이동 가능하다 테스트 작성
minSsan Mar 22, 2025
5b42e3e
🟢green: 비숍의 이동 경로에 다른 팀의 기물이 존재하는 경우 테스트 통과 로직 작성
minSsan Mar 22, 2025
bd5de77
🛠️refactor: 비숍 목적지 반환 코드 메서드 분리
minSsan Mar 22, 2025
b2b4d8c
🔴red: 나이트는 목적지를 제외한 경로 상의 장애물을 신경쓰지 않는다 테스트 작성
minSsan Mar 22, 2025
679ac1b
🟢green: 나이트는 목적지를 제외한 경로 상의 장애물을 신경쓰지 않는다 테스트 통과 로직 구현
minSsan Mar 22, 2025
e6ce925
🔴red: 나이트는 목적지에 같은 팀의 기물이 없는 경로만 선택할 수 있다 테스트 작성
minSsan Mar 22, 2025
bff664d
🟢green: 나이트는 목적지에 같은 팀의 기물이 없는 경로만 선택할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
877ab33
🛠️refactor: 목적지 도달 조건 메서드 분리
minSsan Mar 22, 2025
912ed79
docs(README.md): 나이트 기물 이동 구현 체크
minSsan Mar 22, 2025
1870afd
🔴red: 퀸 - 장애물이 존재하지 않는 경우 목적지 반환 테스트 작성
minSsan Mar 22, 2025
6ba1977
🟢green: 퀸 - 장애물이 존재하지 않는 경우 목적지 반환 테스트 통과 코드 작성
minSsan Mar 22, 2025
c81e7a2
feat: 퀸 - 색상 반환 메서드
minSsan Mar 22, 2025
4b8211c
🔴red: 퀸 - 상대편 기물이 존재하는 위치까지 이동할 수 있다 테스트 작성
minSsan Mar 22, 2025
e71345a
🟢green: 퀸 - 상대편 기물이 존재하는 위치까지 이동할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
f1d5ce7
test(Queen): 같은 편 기물이 존재하는 경우 테스트 추가
minSsan Mar 22, 2025
6049751
docs(README.md): 여왕 기물 이동 구현 체크
minSsan Mar 22, 2025
04aa901
🔴red: 룩 - 장애물이 존재하지 않는 경우 끝까지 이동할 수 있다 테스트 작성
minSsan Mar 22, 2025
55ec868
🟢green: 룩 - 장애물이 존재하지 않는 경우 끝까지 이동할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
2f81746
test(Rook): 장애물이 존재하는 경우 테스트 케이스 추가
minSsan Mar 22, 2025
29e872b
docs(README.md): 룩 움직임 구현 체크
minSsan Mar 22, 2025
4192fc6
refactor(ChessPiece): move 메서드 추가
minSsan Mar 22, 2025
5e1fd2b
🔴red: 검은색 폰이 처음 움직이는 경우, 아래 방향으로 두 칸까지 이동할 수 있다 테스트 작성
minSsan Mar 22, 2025
f8e9aa7
feat(Pawn): color 반환
minSsan Mar 22, 2025
2f1d4b9
🟢green: 검은색 폰이 처음 움직이는 경우, 아래 방향으로 두 칸까지 이동할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
4109e7b
🔴red: 검은색 폰이 처음 움직이는 경우, 전진 방향의 대각선에 적이 위치하면 이동할 수 있다 테스트 작성
minSsan Mar 22, 2025
4f411a1
🟢green: 검은색 폰이 처음 움직이는 경우, 전진 방향의 대각선에 적이 위치하면 이동할 수 있다 테스트 통과 코드 작성
minSsan Mar 22, 2025
8b9a342
test(Pawn): 같은 편 기물이 있는 경우 이동 불가능 테스트 케이스 추가
minSsan Mar 22, 2025
bc806d0
🔴red: 하얀색 폰이 처음 움직이는 경우 두 칸까지 전진할 수 있다 테스트 작성
minSsan Mar 22, 2025
fddb3db
🟢green: 하얀색 폰이 처음 움직이는 경우 두 칸까지 전진할 수 있다 테스트 통과 로직 작성
minSsan Mar 22, 2025
8130ee9
🛠️refactor: 폰의 움직임 반환 메서드 분리
minSsan Mar 22, 2025
329c20d
test(Pawn): 하얀색 폰 테스트 케이스 추가
minSsan Mar 22, 2025
096bc1e
test(Pawn): 폰 테스트 케이스 추가 - 움직인 이력이 있는 경우
minSsan Mar 22, 2025
12b2a94
test(Pawn): 폰 테스트 케이스 추가 - 처음 움직일 때 두 칸 앞에 기물이 존재하는 경우
minSsan Mar 22, 2025
3932876
🔴red: 두 칸 이동시 바로 앞에 기물이 존재하는 경우 이동할 수 없다 테스트 작성
minSsan Mar 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,35 @@
## 우아한테크코스 코드리뷰

- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md)

## 실행 흐름
1. 보드에 있는 기물을 선택하면, 해당 기물이 이동할 수 있는 위치들을 알려준다.
2. 사용자가 위치를 입력하면 해당 기물을 지정 위치로 이동시킨다.
3. 이동 위치에 기물이 존재하는 경우, 해당 기물을 잡아서 점수를 얻을 수 있다.

## 기물 이동 구현하기

- [x] 비숍
- [x] 대각선으로 원하는만큼 이동 가능
- [x] 장애물을 통과할 수 없음
- [x] 왕
- [x] 상, 하, 좌, 우, 대각선 한 칸씩 이동 가능
- [x] 나이트
- [x] 상, 하, 좌, 우 방향으로 앞으로 한 칸, 대각선으로 한 칸 이동 가능
- [x] 장애물을 통과할 수 있음
- [ ] 폰
- [ ] 처음 이동할 때는 앞으로 두 칸 이동도 가능 (한 칸만 움직일 수도 있음)
- [ ] 상대 말을 잡을 때는 무조건 대각선으로만 잡을 수 있음
- [ ] 뒤로는 이동할 수 없음
- [x] 여왕
- [x] 상, 하, 좌, 우, 대각선 원하는만큼 이동 가능
- [x] 장애물을 통과할 수 없음
- [x] 룩
- [x] 상, 하, 좌, 우 원하는만큼 이동 가능
- [x] 장애물을 통과할 수 없음

## 기물 배치하기

## 기물 잡기

- [ ] 기물이 이동한 위치에 다른 팀의 기물이 존재하는 경우
5 changes: 5 additions & 0 deletions src/main/java/chess/Board.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package chess;

public class Board {

}
14 changes: 14 additions & 0 deletions src/main/java/chess/ChessPositions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package chess;

import chess.piece.ChessPiece;

import java.util.List;
import java.util.Map;

public class ChessPositions {
private final Map<Position, ChessPiece> positions;

public ChessPositions(Map<Position, ChessPiece> positions) {
this.positions = positions;
}
}
3 changes: 2 additions & 1 deletion src/main/java/chess/Column.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package chess;

public enum Column {
public enum
Column {

A,
B,
Expand Down
66 changes: 65 additions & 1 deletion src/main/java/chess/piece/Bishop.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,69 @@
package chess.piece;

public class Bishop {
import chess.Color;
import chess.Movement;
import chess.Position;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class Bishop implements ChessPiece {
private final Color color;
private final List<Movement> movements = List.of(
Movement.LEFT_UP,
Movement.RIGHT_UP,
Movement.LEFT_DOWN,
Movement.RIGHT_DOWN
);

public Bishop(Color color) {
this.color = color;
}

@Override
public Position move(Position from, Position to, Map<Position, ChessPiece> positions) {
if (!isValidPath(from, to, positions)) {
throw new IllegalArgumentException("경로가 유효하지 않습니다.");
}
return to;
}

private boolean isValidPath(Position from, Position to, Map<Position, ChessPiece> positions) {
List<Position> availableDestinations = getAvailableDestinations(from, positions);
return availableDestinations.contains(to);
}

public List<Position> getAvailableDestinations(Position startPosition, Map<Position, ChessPiece> positions) {
List<Position> destinations = new ArrayList<>();

for (Movement movement : movements) {
Position currentPosition = startPosition;
while (currentPosition.canMove(movement)) {
currentPosition = currentPosition.move(movement);
if (!canMove(currentPosition, positions)) {
break;
}
destinations.add(currentPosition);
if (positions.containsKey(currentPosition)) {
break;
}
}
}

return destinations;
}

private boolean canMove(Position targetPosition, Map<Position, ChessPiece> positions) {
return !positions.containsKey(targetPosition) || canCatch(targetPosition, positions);
}

private boolean canCatch(Position targetPosition, Map<Position, ChessPiece> positions) {
return positions.containsKey(targetPosition) && positions.get(targetPosition).getColor() != color;
}

@Override
public Color getColor() {
return color;
}
}
13 changes: 13 additions & 0 deletions src/main/java/chess/piece/ChessPiece.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package chess.piece;

import chess.Color;
import chess.Position;

import java.util.List;
import java.util.Map;

public interface ChessPiece {
List<Position> getAvailableDestinations(Position startPosition, Map<Position, ChessPiece> positions);
Color getColor();
Position move(Position from, Position to, Map<Position, ChessPiece> positions);
}
54 changes: 53 additions & 1 deletion src/main/java/chess/piece/King.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,57 @@
package chess.piece;

public class King {
import chess.Color;
import chess.Movement;
import chess.Position;

import java.util.List;
import java.util.Map;

public class King implements ChessPiece {
private final Color color;
private final List<Movement> movements = List.of(
Movement.UP,
Movement.DOWN,
Movement.LEFT,
Movement.RIGHT,
Movement.LEFT_UP,
Movement.RIGHT_UP,
Movement.LEFT_DOWN,
Movement.RIGHT_DOWN
);

public King(Color color) {
this.color = color;
}

@Override
public Position move(Position from, Position to, Map<Position, ChessPiece> positions) {
if (!isValidPath(from, to, positions)) {
throw new IllegalArgumentException("경로가 유효하지 않습니다.");
}
return to;
}

private boolean isValidPath(Position from, Position to, Map<Position, ChessPiece> positions) {
List<Position> availableDestinations = getAvailableDestinations(from, positions);
return availableDestinations.contains(to);
}

@Override
public List<Position> getAvailableDestinations(Position startPosition, Map<Position, ChessPiece> positions) {
return movements.stream()
.filter(startPosition::canMove)
.map(startPosition::move)
.filter(position -> canMove(position, positions))
.toList();
}

private boolean canMove(Position targetPosition, Map<Position, ChessPiece> positions) {
return !positions.containsKey(targetPosition) || positions.get(targetPosition).getColor() != color;
}

@Override
public Color getColor() {
return color;
}
}
57 changes: 56 additions & 1 deletion src/main/java/chess/piece/Knight.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
package chess.piece;

public class Knight {
import chess.Color;
import chess.Movement;
import chess.Position;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class Knight implements ChessPiece {
private final Color color;
private final List<Movement> movements = List.of(
Movement.UP_UP_LEFT,
Movement.UP_UP_RIGHT,
Movement.DOWN_DOWN_LEFT,
Movement.DOWN_DOWN_RIGHT,
Movement.LEFT_LEFT_UP,
Movement.LEFT_LEFT_DOWN,
Movement.RIGHT_RIGHT_UP,
Movement.RIGHT_RIGHT_DOWN
);

public Knight(Color color) {
this.color = color;
}

@Override
public Position move(Position from, Position to, Map<Position, ChessPiece> positions) {
if (!isValidPath(from, to, positions)) {
throw new IllegalArgumentException("경로가 유효하지 않습니다.");
}
return to;
}

private boolean isValidPath(Position from, Position to, Map<Position, ChessPiece> positions) {
List<Position> availableDestinations = getAvailableDestinations(from, positions);
return availableDestinations.contains(to);
}

@Override
public List<Position> getAvailableDestinations(Position startPosition, Map<Position, ChessPiece> positions) {
List<Position> destinations = new ArrayList<>();
for (Movement movement : movements) {
if (startPosition.canMove(movement) && canMove(startPosition.move(movement), positions)) {
destinations.add(startPosition.move(movement));
}
}
return destinations;
}

private boolean canMove(Position targetPosition, Map<Position, ChessPiece> positions) {
return !positions.containsKey(targetPosition) || positions.get(targetPosition).getColor() != color;
}

@Override
public Color getColor() {
return color;
}
}
83 changes: 82 additions & 1 deletion src/main/java/chess/piece/Pawn.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,86 @@
package chess.piece;

public class Pawn {
import chess.Color;
import chess.Movement;
import chess.Position;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class Pawn implements ChessPiece {
private final Color color;
private boolean isFirstMove;

public Pawn(Color color) {
this.color = color;
isFirstMove = true;
}

@Override
public Position move(Position from, Position to, Map<Position, ChessPiece> positions) {
isFirstMove = false;
return null;
}

@Override
public List<Position> getAvailableDestinations(Position startPosition, Map<Position, ChessPiece> positions) {
List<Position> destinations = new ArrayList<>();
for (Movement movement : getMovements()) {
if (canMove(startPosition, movement, positions)) {
destinations.add(startPosition.move(movement));
}
}
return destinations;
}

private List<Movement> getMovements() {
if (color.isBlack()) {
return getBlackMovements();
}
return getWhiteMovements();
}

private List<Movement> getBlackMovements() {
List<Movement> result = new ArrayList<>(List.of(
Movement.DOWN,
Movement.LEFT_DOWN,
Movement.RIGHT_DOWN
));
if (isFirstMove) {
result.add(Movement.DOWN_DOWN);
}
return Collections.unmodifiableList(result);
}

private List<Movement> getWhiteMovements() {
List<Movement> result = new ArrayList<>(List.of(
Movement.UP,
Movement.LEFT_UP,
Movement.RIGHT_UP
));
if (isFirstMove) {
result.add(Movement.UP_UP);
}
return Collections.unmodifiableList(result);
}

private boolean canMove(Position startPosition, Movement movement, Map<Position, ChessPiece> positions) {
if (!startPosition.canMove(movement)) {
return false;
}
Position targetPosition = startPosition.move(movement);
if (movement.isDiagonal()) {
// 대각선 방향인 경우 - 상대 기물이 존재하는지 확인
return positions.containsKey(targetPosition) && positions.get(targetPosition).getColor() != color;
}
// 빈 칸 확인
return !positions.containsKey(targetPosition);
}

@Override
public Color getColor() {
return color;
}
}
Loading