Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 31 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

체스 미션 저장소

## 우아한테크코스 코드리뷰
## 출력 예시

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

8 BR BN BB BQ BK BB BN BR
7 BP BP BP BP BP BP BP BP
6 - - - - - - - -
5 - - - - - - - -
4 - - - - - - - -
3 - - - - - - - -
2 WP WP WP WP WP WP WP WP
1 WR WN WB WQ WK WB WN WR
A B C D E F G H

백색 차례입니다
시작 좌표를 입력해주세요(ex)x,y
(B,1)

목표 좌표를 입력해주세요(ex)x,y
(A,3)

이동하였습니다
8 BL BN BB BQ BK BB BN BL
7 BP BP BP BP BP BP BP BP
6 - - - - - - - -
5 - - - - - - - -
4 - - - - - - - -
3 WN - - - - - - -
2 WP WP WP WP WP WP WP WP
1 WL - WB WQ WK WB WN WL
A B C D E F G H
```
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ repositories {
}

dependencies {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation platform('org.assertj:assertj-bom:3.25.1')
testImplementation platform('org.junit:junit-bom:5.11.4')
testImplementation platform('org.assertj:assertj-bom:3.27.3')
testImplementation('org.junit.jupiter:junit-jupiter')
testImplementation('org.assertj:assertj-core')
}

java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
languageVersion = JavaLanguageVersion.of(21)
}
}

Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
20 changes: 10 additions & 10 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/main/java/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import chess.ChessGame;
import chess.board.ChessBoard;
import view.ConsoleView;
import view.support.OutputSupporter;

public class Application {

public static void main(String[] args) {
ChessGame game = new ChessGame(ChessBoard.initialize(), new ConsoleView(new OutputSupporter()));
game.start();
}
}
34 changes: 34 additions & 0 deletions src/main/java/chess/ChessGame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package chess;

import chess.board.ChessBoard;
import chess.board.Position;
import view.ConsoleView;

public class ChessGame {

private final ChessBoard chessBoard;
private final ConsoleView consoleView;

public ChessGame(ChessBoard chessBoard, ConsoleView consoleView) {
this.chessBoard = chessBoard;
this.consoleView = consoleView;
}

public void start() {
Turn currentTurn = Turn.getStartingTurn();
boolean isGameStop = false;
while (!isGameStop) {
try {
consoleView.printBoard(chessBoard.getPieces());
consoleView.printTurn(currentTurn);
Position startPoint = consoleView.requestStartPoint();
Position destination = consoleView.requestDestination();

isGameStop = chessBoard.move(startPoint, destination);
currentTurn = currentTurn.changeTurn();
} catch (RuntimeException e) {
consoleView.printMessage(e.getMessage());
}
}
}
}
28 changes: 28 additions & 0 deletions src/main/java/chess/Color.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package chess;

public enum Color {

BLACK,
WHITE,
EMPTY;

public boolean isWhite() {
return this == WHITE;
}

public boolean isBlack() {
return this == BLACK;
}

public boolean isEmpty() {
return this == EMPTY;
}

public Color opposite() {
return switch (this) {
case BLACK -> WHITE;
case WHITE -> BLACK;
default -> EMPTY;
};
}
}
17 changes: 17 additions & 0 deletions src/main/java/chess/Turn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package chess;

public enum Turn {
WHITE_TURN,
BLACK_TURN;

public static Turn getStartingTurn() {
return WHITE_TURN;
}

public Turn changeTurn() {
if (this == WHITE_TURN) {
return BLACK_TURN;
}
return WHITE_TURN;
}
}
41 changes: 41 additions & 0 deletions src/main/java/chess/board/BoardVector.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package chess.board;

public record BoardVector(
int dx,
int dy
) {

public int getAbsDx() {
return Math.abs(dx);
}

public int getAbsDy() {
return Math.abs(dy);
}

public static BoardVector createVector(Position start, Position end) {
int dx = end.column().ordinal() - start.column().ordinal();
int dy = end.row().getValue() - start.row().getValue();
return new BoardVector(dx, dy);
}

public boolean isOneQuadrant() {
return dx > 0 && dy > 0;
}

public boolean isTwoQuadrant() {
return dx < 0 && dy > 0;
}

public boolean isThreeQuadrant() {
return dx < 0 && dy < 0;
}

public boolean isFourQuadrant() {
return dx > 0 && dy < 0;
}

public boolean isDxZero() {
return dx == 0;
}
}
105 changes: 105 additions & 0 deletions src/main/java/chess/board/ChessBoard.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package chess.board;

import chess.Color;
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 chess.piece.Rook;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ChessBoard {

private final Map<Position, Piece> pieces;

public ChessBoard(Map<Position, Piece> pieces) {
this.pieces = pieces;
}

public boolean move(Position startPoint, Position destination) {
if (!pieces.containsKey(startPoint)) {
throw new IllegalArgumentException("[ERROR] 해당 위치에 기물이 없습니다");
}

Piece startPiece = pieces.get(startPoint);
if (!startPiece.isMovable(startPoint, destination)) {
throw new IllegalArgumentException("[ERROR] 해당 기물은 목표 위치로 움직일 수 없습니다");
}

List<Position> paths = startPiece.createAllPaths(startPoint, destination); // 목표 위치 제외
List<Piece> pathPieces = extractPathPieces(paths);
if (!startPiece.canJumpOver() && !pathPieces.isEmpty()) {
throw new IllegalArgumentException("[ERROR] 경로에 기물이 있어 목표 위치로 움직일 수 없습니다");
}

if (pieces.containsKey(destination)) {
Piece destinationPiece = pieces.get(destination);
validateColor(destination, startPiece);
return destinationPiece.isGameStopIfDie();
}

pieces.put(destination, startPiece);
pieces.remove(startPoint);
return true;
}

private void validateColor(Position destination, Piece startPiece) {
Piece destinationPiece = pieces.get(destination);
if (startPiece.isEqualColor(destinationPiece)) {
throw new IllegalArgumentException("[ERROR] 목적지에 같은 색의 기물이 위치해 있어 움직일 수 없습니다");
}
}

private List<Piece> extractPathPieces(List<Position> paths) {
return paths.stream()
.filter(pieces::containsKey)
.map(pieces::get)
.toList();
}

public static ChessBoard initialize() {
Map<Position, Piece> initialPieces = new HashMap<>();
initialPieces.put(new Position(Row.ONE, Column.A), new Rook(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.B), new Knight(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.C), new Bishop(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.D), new Queen(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.E), new King(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.F), new Bishop(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.G), new Knight(Color.WHITE));
initialPieces.put(new Position(Row.ONE, Column.H), new Rook(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.A), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.B), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.C), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.D), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.E), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.F), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.G), new Pawn(Color.WHITE));
initialPieces.put(new Position(Row.TWO, Column.H), new Pawn(Color.WHITE));

initialPieces.put(new Position(Row.EIGHT, Column.A), new Rook(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.B), new Knight(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.C), new Bishop(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.D), new Queen(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.E), new King(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.F), new Bishop(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.G), new Knight(Color.BLACK));
initialPieces.put(new Position(Row.EIGHT, Column.H), new Rook(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.A), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.B), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.C), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.D), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.E), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.F), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.G), new Pawn(Color.BLACK));
initialPieces.put(new Position(Row.SEVEN, Column.H), new Pawn(Color.BLACK));
return new ChessBoard(initialPieces);
}

public Map<Position, Piece> getPieces() {
return pieces;
}
}
56 changes: 56 additions & 0 deletions src/main/java/chess/board/Column.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package chess.board;

import java.util.Arrays;
import java.util.Objects;

public enum Column {

A,
B,
C,
D,
E,
F,
G,
H;

public boolean isFarLeft() {
return ordinal() == 0;
}

public boolean isFarRight() {
return ordinal() + 1 == values().length;
}

public Column moveLeft() {
return moveLeft(1);
}

public Column moveLeft(final int step) {
if (canMoveLeft(step)) {
return values()[ordinal() - step];
}

throw new IllegalStateException("움직일 수 없는 위치입니다.");
}

public Column moveRight() {
return moveRight(1);
}

public Column moveRight(final int step) {
if (canMoveRight(step)) {
return values()[ordinal() + step];
}

throw new IllegalStateException("움직일 수 없는 위치입니다.");
}

public boolean canMoveRight(final int step) {
return ordinal() + step < values().length;
}

public boolean canMoveLeft(final int step) {
return ordinal() - step >= 0;
}
}
Loading