Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[무늬] 체스 스프링 4단계 미션 제출합니다. #186

Merged
merged 12 commits into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
37 changes: 37 additions & 0 deletions src/main/java/wooteco/chess/ConsoleChessApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package wooteco.chess;

import wooteco.chess.controller.ConsoleChessController;
import wooteco.chess.domain.chessBoard.ChessBoard;
import wooteco.chess.domain.chessBoard.ChessBoardInitializer;
import wooteco.chess.domain.chessGame.ChessCommand;
import wooteco.chess.domain.chessGame.ChessGame;
import wooteco.chess.util.StringUtil;
import wooteco.chess.view.ConsoleInputView;
import wooteco.chess.view.ConsoleOutputView;

import java.util.List;

public class ConsoleChessApplication {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엥 갑자기 분위기 콘솔인가요??

Copy link
Author

@JinJuMoon JinJuMoon May 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

엇! 브랜치를 병합하는 과정에서 다시 추가된 것 같습니다. 콘솔프로그램 관련 클래스 모두 삭제했습니다~ 😄


public static void main(String[] args) {
ChessBoard chessBoard = new ChessBoard(ChessBoardInitializer.create());
ChessGame chessGame = ChessGame.from(chessBoard);
ConsoleChessController consoleChessController = new ConsoleChessController(chessGame);

ConsoleOutputView.printChessStart();
if (isStartChessCommand()) {
consoleChessController.run();
}
ConsoleOutputView.printChessEnd();
}

private static boolean isStartChessCommand() {
List<String> commandArguments = StringUtil.splitChessCommand(ConsoleInputView.inputChessCommand());

if (!ChessCommand.of(commandArguments).isStartChessCommand()) {
throw new IllegalArgumentException("게임을 시작해야 입력 가능한 명령어입니다.");
}
return true;
}

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

import wooteco.chess.domain.chessGame.ChessCommand;
import wooteco.chess.domain.chessGame.ChessGame;
import wooteco.chess.util.ChessBoardRenderer;

import java.util.Objects;

import static wooteco.chess.util.StringUtil.splitChessCommand;
import static wooteco.chess.view.ConsoleInputView.inputChessCommand;
import static wooteco.chess.view.ConsoleOutputView.*;

public class ConsoleChessController {

private final ChessGame chessGame;

public ConsoleChessController(ChessGame chessGame) {
Objects.requireNonNull(chessGame, "체스 게임이 null입니다.");
this.chessGame = chessGame;
}

public void run() {
do {
printChessBoard(ChessBoardRenderer.render(chessGame.getChessBoard()));

ChessCommand chessCommand = receiveChessCommand();
playChessGameBy(chessCommand);
} while (!isEndState());
}

private ChessCommand receiveChessCommand() {
ChessCommand chessCommand = ChessCommand.of(splitChessCommand(inputChessCommand()));

if (chessCommand.isStartChessCommand()) {
throw new IllegalArgumentException("start 명령어은 최초 시작 때만 사용 가능합니다.");
}
return chessCommand;
}

private void playChessGameBy(ChessCommand chessCommand) {
if (chessCommand.isMoveChessCommand()) {
chessGame.move(chessCommand);
}
if (chessCommand.isStatusChessCommand()) {
double score = chessGame.status(chessCommand);
printStatus(chessCommand.getStatusPieceColor(), score);
}
if (chessCommand.isEndChessCommand()) {
chessGame.end();
}
}

private boolean isEndState() {
if (!chessGame.isEndState()) {
return false;
}
return checkKingCaught();
}

private boolean checkKingCaught() {
if (chessGame.isKingCaught()) {
printKingCaught(chessGame.getCurrentPieceColor());
}
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public SpringChessController(final ChessService chessService) {

@GetMapping("/")
public String index(Model model) {
model.addAttribute("gameNames", chessService.showAllGames());
model.addAttribute("games", chessService.showAllGames());
return "index";
}

Expand Down Expand Up @@ -93,4 +93,5 @@ private String renderResult(final ChessGameDto chessGameDto, final Model model)
model.addAttribute("status", chessStatusDtos.getChessStatusDtos());
return "result";
}

}
14 changes: 6 additions & 8 deletions src/main/java/wooteco/chess/service/ChessService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import wooteco.chess.entity.GameHistory;
import wooteco.chess.entity.GameRoom;
import wooteco.chess.service.dto.ChessGameDto;
import wooteco.chess.service.dto.GameRoomDto;

import java.util.Arrays;
import java.util.List;
Expand Down Expand Up @@ -51,17 +52,14 @@ public ChessGameDto playChessGame(final Long gameId, final String sourcePosition
}

private ChessGameDto moveChessPiece(final Long gameId, final String sourcePosition, final String targetPosition) {
GameRoom gameRoom = gameRoomRepository.findById(gameId)
final GameRoom gameRoom = gameRoomRepository.findById(gameId)
.orElseThrow(() -> new NoSuchElementException("게임이 존재하지 않습니다."));

final ChessGame chessGame = initChessGameOf(gameRoom);
final ChessCommand chessCommand = ChessCommand.of(Arrays.asList(MOVE_COMMAND, sourcePosition, targetPosition));

chessGame.move(chessCommand);
gameRoom.addGameHistory(new GameHistory(sourcePosition, targetPosition, gameId));

gameRoomRepository.save(gameRoom);

gameRoomRepository.save(new GameRoom(gameRoom, chessGame.isEndState()));
return ChessGameDto.of(gameRoom.getId(), chessGame);
}

Expand All @@ -76,7 +74,7 @@ public ChessGameDto endChessGame(final Long gameId) {
final ChessGame chessGame = initChessGameOf(gameRoom);

chessGame.end();
gameRoomRepository.save(new GameRoom(gameRoom, true));
gameRoomRepository.save(new GameRoom(gameRoom, chessGame.isEndState()));
return ChessGameDto.of(gameRoom.getId(), chessGame);
}

Expand All @@ -86,11 +84,11 @@ public boolean isEndGame(final Long gameId) {
return gameRoom.getState();
}

public List<String> showAllGames() {
public List<GameRoomDto> showAllGames() {
List<GameRoom> gameRooms = gameRoomRepository.findAll();

return gameRooms.stream()
.map(GameRoom::getName)
.map(GameRoomDto::of)
.collect(toList());
}

Expand Down
23 changes: 12 additions & 11 deletions src/main/java/wooteco/chess/service/dto/ChessGameDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,18 @@ private ChessGameDto(final Long id, final ChessBoardDto chessBoardDto, final Pie
this.isKingCaught = isKingCaught;
}

public static ChessGameDto of(final Long id, final ChessGame chessGame) {
Objects.requireNonNull(chessGame, "체스 게임이 null입니다.");

final ChessBoardDto chessBoardDto = ChessBoardDto.of(chessGame.getChessBoard());
final PieceColorDto pieceColorDto = PieceColorDto.of(chessGame.getCurrentPieceColor());
final ChessStatusDtos chessStatusDtos = ChessStatusDtos.of(chessGame.getChessGameStatus());
final boolean isEndStatus = chessGame.isEndState();
final boolean isKingCaught = chessGame.isKingCaught();

return new ChessGameDto(id, chessBoardDto, pieceColorDto, chessStatusDtos, isEndStatus, isKingCaught);
}
// NOTE: 2020/04/28 DTO가 관리해야하는 필드의 종류
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

무슨 의미의 주석이신가요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

공부해야할 부분에 대한 주석인데 미처 제거하지 못했네요! 🤣 삭제했습니다~

public static ChessGameDto of(final Long id, final ChessGame chessGame) {
Objects.requireNonNull(chessGame, "체스 게임이 null입니다.");

final ChessBoardDto chessBoardDto = ChessBoardDto.of(chessGame.getChessBoard());
final PieceColorDto pieceColorDto = PieceColorDto.of(chessGame.getCurrentPieceColor());
final ChessStatusDtos chessStatusDtos = ChessStatusDtos.of(chessGame.getChessGameStatus());
final boolean isEndStatus = chessGame.isEndState();
final boolean isKingCaught = chessGame.isKingCaught();

return new ChessGameDto(id, chessBoardDto, pieceColorDto, chessStatusDtos, isEndStatus, isKingCaught);
}

public Long getId() {
return id;
Expand Down
36 changes: 36 additions & 0 deletions src/main/java/wooteco/chess/service/dto/GameRoomDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package wooteco.chess.service.dto;

import wooteco.chess.entity.GameRoom;

import java.util.Objects;

public class GameRoomDto {

private Long id;
private String name;
private Boolean state;

private GameRoomDto(final Long id, final String name, final Boolean state) {
this.id = id;
this.name = name;
this.state = state;
}

public static GameRoomDto of(final GameRoom gameRoom) {
Objects.requireNonNull(gameRoom, "게임이 null입니다.");
return new GameRoomDto(gameRoom.getId(), gameRoom.getName(), gameRoom.getState());
}

public Long getId() {
return id;
}

public String getName() {
return name;
}

public Boolean getState() {
return state;
}

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

import wooteco.chess.domain.chessBoard.ChessBoard;
import wooteco.chess.domain.position.ChessFile;
import wooteco.chess.domain.position.ChessRank;
import wooteco.chess.domain.position.Position;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import static java.util.stream.Collectors.*;

public class ChessBoardRenderer {

private static final String EMPTY_SPACE = "";
private static final String DELIMITER = " ";
private static final String RANK_APPEND_FORMAT = "%s %s";
private static final String EMPTY_POSITION = ".";

public static List<String> render(final ChessBoard chessBoard) {
Objects.requireNonNull(chessBoard, "체스 보드가 null입니다.");
final List<String> renderedChessBoard = renderEachChessRankFrom(chessBoard);

Collections.reverse(renderedChessBoard);
appendChessFileName(renderedChessBoard);
return renderedChessBoard;
}

private static List<String> renderEachChessRankFrom(final ChessBoard chessBoard) {
return Arrays.stream(ChessRank.values())
.map(chessRank -> renderChessRankFrom(chessBoard, chessRank))
.collect(toList());
}

private static String renderChessRankFrom(final ChessBoard chessBoard, final ChessRank chessRank) {
return Arrays.stream(ChessFile.values())
.map(chessFile -> renderChessPieceFrom(chessBoard, chessRank, chessFile))
.collect(collectingAndThen(joining(DELIMITER),
renderedRank -> String.format(RANK_APPEND_FORMAT, renderedRank, chessRank)));
}

private static String renderChessPieceFrom(final ChessBoard chessBoard, final ChessRank chessRank,
final ChessFile chessFile) {
final Position renderingPosition = Position.of(chessFile, chessRank);

if (chessBoard.isChessPieceOn(renderingPosition)) {
return chessBoard.getChessPieceNameOn(renderingPosition);
}
return EMPTY_POSITION;
}

private static void appendChessFileName(final List<String> renderedChessBoard) {
renderedChessBoard.add(EMPTY_SPACE);
renderedChessBoard.add(Arrays.stream(ChessFile.values())
.map(ChessFile::toString)
.collect(joining(DELIMITER)));
}

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

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

import static java.util.stream.Collectors.toList;

public class StringUtil {

private static final String DELIMITER = " ";

public static List<String> splitChessCommand(final String chessCommand) {
Objects.requireNonNull(chessCommand, "분리할 명령어가 null입니다.");

return Arrays.stream(chessCommand.split(DELIMITER))
.map(String::trim)
.collect(toList());
}

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

import java.util.Scanner;

public class ConsoleInputView {

private static final Scanner SCANNER = new Scanner(System.in);

public static String inputChessCommand() {
System.out.print(ConsoleOutputView.PROMPT);
return SCANNER.nextLine();
}

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

import wooteco.chess.domain.chessPiece.pieceType.PieceColor;

import java.util.List;

public class ConsoleOutputView {

static final String PROMPT = "> ";

private static void printNewLine() {
System.out.println();
}

public static void printChessStart() {
System.out.println(PROMPT + "체스 게임을 시작합니다.");
System.out.println(PROMPT + "게임 시작 : start");
System.out.println(PROMPT + "게임 이동 : move source위치 target위치 - 예. move b2 b3");
System.out.println(PROMPT + "게임 점수 : status 체스 색상 - 예. status white, status black");
System.out.println(PROMPT + "게임 종료 : end");
}

public static void printChessBoard(List<String> renderedChessBoard) {
printNewLine();
renderedChessBoard.forEach(System.out::println);
}

public static void printStatus(PieceColor statusPieceColor, double score) {
System.out.println(String.format("%s 점수 : %.1f", statusPieceColor.getColor(), score));
}

public static void printKingCaught(PieceColor catchingPieceColor) {
System.out.println(String.format("%s가 킹을 잡았습니다.", catchingPieceColor.getColor()));
}

public static void printChessEnd() {
System.out.println(PROMPT + "게임 종료!");
}

}
2 changes: 1 addition & 1 deletion src/main/java/wooteco/chess/web/PieceNameConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public enum PieceNameConverter {
BLACK_PAWN("P", "black-pawn"),
WHITE_PAWN("p", "white-pawn");

private static final String IMAGE_SOURCE_FORMAT = "<img class=\"chessboard\" src=\"./images/%s.png\">";
private static final String IMAGE_SOURCE_FORMAT = "<img class=\"chessboard\" src=\"/images/%s.png\">";

private final String chessPieceName;
private final String imageFileName;
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/black-king.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/black-knight.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/black-pawn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/black-queen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/black-rook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/white-bishop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/white-king.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/white-knight.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/white-pawn.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/white-queen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/main/resources/static/images/white-rook.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading