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

[3, 4단계 - 체스] 제이(이재윤) 미션 제출합니다. #530

Merged
merged 45 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
9c2396a
docs: 기능 구현 목록 수정
sosow0212 Mar 19, 2023
6cb22ba
refactor: 커맨드를 일급 컬렉션으로 변경
sosow0212 Mar 19, 2023
832bd00
refactor: 사용하지 않는 상수 제거
sosow0212 Mar 19, 2023
aeebb02
refactor: 값이 없는 경우 예외 메시지 출력하도록 변경
sosow0212 Mar 19, 2023
9b4442a
refactor: 조건문을 더욱 직관적이게 변경
sosow0212 Mar 19, 2023
d2c2a6e
test: Command에서 성공하는 경우의 테스트도 추가
sosow0212 Mar 19, 2023
48824eb
style: 개행 맞춤
sosow0212 Mar 19, 2023
11282d7
feat: 체스의 말이 점수를 가지고 있게 리팩토링 및 Board에서 팀 별로 점수 반환
sosow0212 Mar 19, 2023
700da6f
refactor: 체스 말에서 폰이 같은 Column에 있을 경우 0.5점을 반환하도록 리팩토링 진행
sosow0212 Mar 19, 2023
2a3a624
test: 3단계 요구사항에 나온 테스트용 맵을 통해 점수 계산 테스트 추가
sosow0212 Mar 19, 2023
b64a004
feat: King이 죽으면 게임이 종료하는 기능 추가
sosow0212 Mar 19, 2023
3f8d963
feat: 점수 출력 및 승패 출력을 해주는 기능 추가
sosow0212 Mar 20, 2023
6ff9da9
docs: 기능 구현 목록 수정
sosow0212 Mar 20, 2023
330b809
refactor: 킹이 잡혀서 종료된 경우 추가
sosow0212 Mar 20, 2023
3d77a16
refactor: 상수 처리 및 주석 제거
sosow0212 Mar 20, 2023
051ee0e
style: 필요 없는 개행 삭제
sosow0212 Mar 20, 2023
063af9f
docs: DB설계 내용 작성
sosow0212 Mar 20, 2023
7a719bc
feat: 체스 보드를 DB에 저장하는 기능 추가
sosow0212 Mar 21, 2023
62577bf
feat: 체스 게임 저장 기능 구현 (리팩토링 전)
sosow0212 Mar 21, 2023
86f0102
style: 패키지명 변경
sosow0212 Mar 21, 2023
f222984
fix: 게임을 불러올 때 Rook이 Place로 생성되는 오류 해결
sosow0212 Mar 21, 2023
41ce6c7
refactor: 리네이밍 및 컨트롤러 구조 변경
sosow0212 Mar 21, 2023
0db7ea5
feat: 체스 게임의 턴을 나타내는 기능 추가
sosow0212 Mar 21, 2023
189dd1b
feat: 저장된 체스 게임을 할 것인지 새로운 게임을 할 것인지 선택하는 기능 추가
sosow0212 Mar 21, 2023
dcdbb80
refactor: Pawn의 점수 계산 로직 변경
sosow0212 Mar 21, 2023
5f87010
style: 디렉토리 구조 변경
sosow0212 Mar 21, 2023
14ae3ed
del: 미니 미션 제거
sosow0212 Mar 21, 2023
028bbc7
test: 테스트하지 못한 메서드에 대해 테스트 추가
sosow0212 Mar 21, 2023
72e6bf2
feat: 게임 종료시 문구 출력 기능 추가
sosow0212 Mar 21, 2023
f5c2788
style: 개행 통일 및 안 쓰는 공백 제거
sosow0212 Mar 21, 2023
60513f8
refactor: 컨트롤러 코드 리팩토링
sosow0212 Mar 21, 2023
0299e0c
refactor: 클래스 네이밍 변경
sosow0212 Mar 21, 2023
9f591d6
refactor: 메서드명 변경
sosow0212 Mar 21, 2023
454c09d
docs: 기능 구현 목록 수정
sosow0212 Mar 21, 2023
00c90d1
refactor: DB에 저장될 때 Piece, Position을 문자열로 압축하도록 변경
sosow0212 Mar 22, 2023
cea5745
refactor: 클래스 네이밍 통일
sosow0212 Mar 22, 2023
b8c9fd9
refactor: DB에 체스판을 저장하거나 가져올 때 문자열로 파싱해주는 기능 추가
sosow0212 Mar 22, 2023
4eb9c8d
refactor: DB 테이블 변경함에 따라 코드 리팩토링 진행
sosow0212 Mar 22, 2023
b0f58da
docs: 테이블 DDL 추가
sosow0212 Mar 22, 2023
6a23cba
refactor: 상수 추출
sosow0212 Mar 22, 2023
5a144d4
refactor: View <-> Controller <-> Dao 통신을 Dto를 통해서 하도록 리팩토링 진행
sosow0212 Mar 22, 2023
6b0a221
refactor: 불필요한 if문 제거
sosow0212 Mar 22, 2023
5c6b8fc
refactor: 코드 메서드 참조로 변경
sosow0212 Mar 22, 2023
262eb61
refactor: Dto에서 String, Integer 같은 클래스만 전달하도록 리팩토링
sosow0212 Mar 22, 2023
1073412
refactor: OutputView에서 status 출력문 추가
sosow0212 Mar 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 8 additions & 4 deletions src/main/java/chess/controller/ChessGameController.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package chess.controller;

import chess.domain.board.Board;
import chess.domain.commnad.Command;
import chess.domain.commnad.LoadGameCommand;
import chess.domain.game.ChessGame;
import chess.dto.BoardResultDto;
import chess.dto.BoardSaveDto;
import chess.dto.ChessGameResponseDto;
import chess.dto.GameScoreResultDto;
import chess.factory.BoardFactory;
import chess.service.BoardService;
Expand Down Expand Up @@ -43,9 +45,11 @@ public void run() {

private ChessGame loadGame(final LoadGameCommand loadCommand) {
if (loadCommand.isSavedGame()) {
ChessGame chessGame = boardService.findById(BOARD_ID).getChessGame();
outputView.printBoard(BoardResultDto.toDto(chessGame));
return chessGame;
ChessGameResponseDto chessGameResponseDto = boardService.findById(BOARD_ID);
BoardResultDto boardResultDto = chessGameResponseDto.getBoardResultDto();

outputView.printBoard(boardResultDto.getPieces());
return new ChessGame(BoardFactory.createFromDto(boardResultDto), chessGameResponseDto.isLowerTeamTurn());
}

Choose a reason for hiding this comment

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

나중에 room 을 구현하게 되면 여기에서는 room에 포함되는 boardId로만 대체해줘도 로딩에 문제가 없겠네요.
로드하는 부분의 구조를 잘 짜주셨습니다.


return new ChessGame(BoardFactory.createBoard(), true);
Expand All @@ -59,7 +63,7 @@ private void playChess(ChessGame chessGame) {
chessGame = checkCreateNewGame(chessGame, command);

checkMovePiece(chessGame, command);
outputView.printBoard(BoardResultDto.toDto(chessGame));
outputView.printBoard(BoardResultDto.toDto(new Board(chessGame.getBoard())).getPieces());

Choose a reason for hiding this comment

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

생성하는 부분에서 불필요하게 객체를 새로 생성할 필요는 없어보입니다.
이부분을 개선할 수 있는 방법을 고민해보면 좋겠네요.


if (isGameDone(chessGame)) {
break;
Expand Down
27 changes: 15 additions & 12 deletions src/main/java/chess/dto/BoardResultDto.java
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
package chess.dto;

import chess.domain.board.Position;
import chess.domain.game.ChessGame;
import chess.domain.pieces.Piece;
import java.util.Collections;
import java.util.Map;
import chess.domain.board.Board;
import java.util.List;
import java.util.stream.Collectors;

public class BoardResultDto {

private final Map<Position, Piece> board;
private final List<PieceDto> pieces;

Choose a reason for hiding this comment

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

DTO 작업하신 코드 봤는데, 구조를 잘 짜주셨네요!
DTO들이 toDto 메소드를 통해 생성되도록 구조를 짰는데, 이 부분도 적절하다고 생각됩니다.💯


private BoardResultDto(final Map<Position, Piece> board) {
this.board = board;
private BoardResultDto(final List<PieceDto> pieces) {
this.pieces = pieces;
}

public static BoardResultDto toDto(final ChessGame chessGame) {
return new BoardResultDto(chessGame.getBoard());
public static BoardResultDto toDto(final Board board) {

List<PieceDto> positionsWithPieces = board.getBoard().entrySet().stream()
.map(entry -> PieceDto.toDto(entry.getKey(), board.getBoard().get(entry.getKey())))
.collect(Collectors.toList());

return new BoardResultDto(positionsWithPieces);
}

public Map<Position, Piece> getBoard() {
return Collections.unmodifiableMap(board);
public List<PieceDto> getPieces() {
return pieces;
}
}
19 changes: 12 additions & 7 deletions src/main/java/chess/dto/ChessGameResponseDto.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
package chess.dto;

import chess.domain.board.Board;
import chess.domain.game.ChessGame;

public class ChessGameResponseDto {

private final ChessGame chessGame;
private final BoardResultDto boardResultDto;
private final boolean isLowerTeamTurn;

private ChessGameResponseDto(final ChessGame chessGame) {
this.chessGame = chessGame;
public ChessGameResponseDto(final BoardResultDto boardResultDto, final boolean isLowerTeamTurn) {
this.boardResultDto = boardResultDto;
this.isLowerTeamTurn = isLowerTeamTurn;
}

public static ChessGameResponseDto toDto(final Board board, final boolean isLowerTeamTurn) {
return new ChessGameResponseDto(new ChessGame(board, isLowerTeamTurn));
return new ChessGameResponseDto(BoardResultDto.toDto(board), isLowerTeamTurn);
}

public ChessGame getChessGame() {
return chessGame;
public BoardResultDto getBoardResultDto() {
return boardResultDto;
}

public boolean isLowerTeamTurn() {
return isLowerTeamTurn;
}
}
33 changes: 33 additions & 0 deletions src/main/java/chess/dto/PieceDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package chess.dto;

import chess.domain.board.Position;
import chess.domain.pieces.Piece;

public class PieceDto {

private final char col;
private final char row;
private final String piece;

private PieceDto(final char row, final char col, final String piece) {
this.row = row;
this.col = col;
this.piece = piece;
}

public static PieceDto toDto(final Position position, final Piece piece) {
return new PieceDto(position.getCol(), position.getRow(), piece.getName());
}

public char getCol() {
return col;
}

public char getRow() {
return row;
}

public String getPiece() {
return piece;
}
}
19 changes: 19 additions & 0 deletions src/main/java/chess/factory/BoardFactory.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package chess.factory;

import static chess.util.PieceParser.parsePiece;

import chess.domain.board.Board;
import chess.domain.board.Column;
import chess.domain.board.Position;
Expand All @@ -13,6 +15,8 @@
import chess.domain.pieces.Place;
import chess.domain.pieces.Queen;
import chess.domain.pieces.Rook;
import chess.dto.BoardResultDto;
import chess.dto.PieceDto;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand All @@ -30,6 +34,21 @@ public static Board createBoard() {
return new Board(chessBoard);
}

public static Board createFromDto(final BoardResultDto boardResultDto) {

Choose a reason for hiding this comment

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

DTO -> Board 처리를 어디서 할까 궁금했는데, BoardFactory에서 수행해주고 있네요! 이부분은 책임을 적절히 지정해주었다고 생각됩니다.

Map<Position, Piece> chessBoard = new HashMap<>();
List<PieceDto> pieces = boardResultDto.getPieces();

pieces.stream()
.forEach(piece -> chessBoard.put(Position.from(String.valueOf(piece.getRow()) + piece.getCol()),
parsePiece(piece.getPiece())));

return new Board(chessBoard);
}

public static Board createFromUncompressedBoard(final Map<Position, Piece> unCompressedBoard) {
return new Board(unCompressedBoard);
}

private static List<Position> makePosition() {
List<Position> positions = Arrays.stream(Column.values())
.flatMap(col -> Arrays.stream(Row.values())
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/chess/service/BoardService.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package chess.service;

import chess.dao.board.BoardDao;
import chess.domain.board.Board;
import chess.domain.board.Position;
import chess.domain.game.ChessGame;
import chess.domain.pieces.Piece;
import chess.dto.ChessGameResponseDto;
import chess.dto.BoardSaveDto;
import chess.dto.ChessGameResponseDto;
import chess.factory.BoardFactory;
import chess.util.BoardUtil;
import java.util.List;
Expand Down Expand Up @@ -36,7 +34,9 @@ public ChessGameResponseDto findById(final int boardId) {
}

Map<Position, Piece> unCompressedBoard = boardUtil.unCompressBoard(compressedBoardFromDatabase);
return ChessGameResponseDto.toDto(new Board(unCompressedBoard), boardDao.isLowerTeamTurnByBoardId(boardId));

return ChessGameResponseDto.toDto(BoardFactory.createFromUncompressedBoard(unCompressedBoard),
boardDao.isLowerTeamTurnByBoardId(boardId));
}

public void delete(final int boardId) {
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/chess/util/PieceParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package chess.util;

import chess.domain.pieces.Bishop;
import chess.domain.pieces.King;
import chess.domain.pieces.Knight;
import chess.domain.pieces.Name;
import chess.domain.pieces.Pawn;
import chess.domain.pieces.Piece;
import chess.domain.pieces.Place;
import chess.domain.pieces.Queen;
import chess.domain.pieces.Rook;

public class PieceParser {

Choose a reason for hiding this comment

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

PieceParser에 대한 테스트도 간단하게 만들어두면 좋을 것으로 보이네요. 😄


public static Piece parsePiece(final String name) {
if (name.equals("r") || name.equals("R")) {
return new Rook(new Name(name));
}

if (name.equals("n") || name.equals("N")) {
return new Knight(new Name(name));
}

if (name.equals("b") || name.equals("B")) {
return new Bishop(new Name(name));
}

if (name.equals("q") || name.equals("Q")) {
return new Queen(new Name(name));
}

if (name.equals("p") || name.equals("P")) {
return new Pawn(new Name(name));
}

if (name.equals("k") || name.equals("K")) {
return new King(new Name(name));
}

return new Place();
}
}
19 changes: 15 additions & 4 deletions src/main/java/chess/view/OutputView.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package chess.view;

import static chess.util.PieceParser.parsePiece;

import chess.domain.board.Position;
import chess.domain.pieces.Piece;
import chess.dto.BoardResultDto;
import chess.dto.PieceDto;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class OutputView {
Expand All @@ -16,14 +20,21 @@ public void printStartMessage() {
+ "> 게임 이동 : move source위치 target위치 - 예. move b2 b3");

Choose a reason for hiding this comment

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

아, 그리고 여기에 status 명령어에 대한 설명도 추가해야겠네요 😄

}

public void printBoard(final BoardResultDto boardResultDto) {
System.out.println();
public void printBoard(final List<PieceDto> pieces) {
Map<Position, Piece> board = new HashMap<>();

Choose a reason for hiding this comment

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

Position은 위치에 대한 정보만 가지니까 여기서 키로 써도 괜찮을 것 같고, 다만 value로는 Piece 대신 PieceDto의 piece값(String)을 넣어줘도 되지 않을까요?


pieces.forEach(pieceDto -> board.put(Position.from(findPosition(pieceDto)), parsePiece(pieceDto.getPiece())));

for (char row = '8'; row >= '1'; row--) {
printLine(boardResultDto.getBoard(), row);
printLine(board, row);
System.out.println();
}
}

private String findPosition(final PieceDto pieceDto) {
return String.valueOf(pieceDto.getRow()) + pieceDto.getCol();
}

private void printLine(final Map<Position, Piece> board, final char row) {
for (char col = 'a'; col <= 'h'; col++) {
String position = String.valueOf(col) + String.valueOf(row);
Expand Down