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

안뇽하쇼 DB잘 모르기 때문에 날카로운 지적부탁 #13

Open
wants to merge 58 commits into
base: hanueleee
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ff4f19d
feat: remove web dependency
woowahan-neo Mar 13, 2023
1bab9ff
feat: add example for functional programming api example
woowahan-neo Mar 13, 2023
98598c0
chore: change package
woowahan-neo Mar 13, 2023
04d2e78
[1,2단계 - 체스] 오잉(이하늘) 미션 제출합니다 (#514)
hanueleee Mar 23, 2023
2be72aa
refactor: 패키지 이동
hanueleee Mar 23, 2023
be7116c
refactor(Board): 메서드 분리 (getValidSourcePiece -> validateSourcePiece &…
hanueleee Mar 23, 2023
4516783
docs: 기능목록 수정 및 추가
hanueleee Mar 23, 2023
2910b93
feat: 각 피스별 점수 매핑
hanueleee Mar 23, 2023
e0cd579
feat(Board): 각 진영의 점수를 계산하는 기능 구현
hanueleee Mar 23, 2023
bde1973
feat(OutputView): 각 팀의 현재 점수를 출력하는 기능 구현
hanueleee Mar 23, 2023
ef70ba7
feat(ChessGame): 킹이 잡혔는지 확인하는 기능 구현
hanueleee Mar 23, 2023
ba54098
feat(OutputView): 킹이 잡혀 게임이 끝난 경우 우승자를 출력하는 기능 구현
hanueleee Mar 23, 2023
405cac6
fix(Board): 같은 세로줄에 같은 색의 폰이 있는 경우 0.5점으로 계산하도록 calulatePoint 수정
hanueleee Mar 24, 2023
28a4eb7
refactor(Controller): Command 패턴 적용
hanueleee Mar 24, 2023
f838cdd
refactor: 메소드 순서 정리
hanueleee Mar 24, 2023
b233073
feat(ChessGameDao): DB 연결
hanueleee Mar 26, 2023
61b4dd3
feat(ChessGameDao): 존재하는 게임방의 Id를 모두 반환하는 기능 구현
hanueleee Mar 26, 2023
c5bd8a9
feat(ChessGameDao): 게임방 Id로 게임 기록을 불러오는 기능 구현
hanueleee Mar 26, 2023
b932638
feat(ChessGameDao): 게임 기록을 저장하는 기능 구현
hanueleee Mar 26, 2023
f704664
feat(ChessGameDao): 게임 기록을 삭제하는 기능 구현
hanueleee Mar 26, 2023
910ef7c
feat(ChessGameDao): 게임 기록을 업데이트 하는 기능 구현
hanueleee Mar 26, 2023
2a275dd
feat: 각 enum 값을 label을 통해 반환받는 기능 구현
hanueleee Mar 26, 2023
1a0a7ac
refactor: Empty 피스도 색깔을 입력받도록 생성자 수정
hanueleee Mar 26, 2023
cc06f11
feat: 입장하고자 하는 게임방의 id를 입력받는 기능 구현
hanueleee Mar 26, 2023
274c304
feat(ChessGameDao): 입장이 가능한 방을 탐색하는 기능과 입장이 불가능한 방을 탐색하는 기능 구분
hanueleee Mar 26, 2023
41754a1
feat(view): 입장이 가능한 방과 입장이 불가능한 방에 대한 정보를 출력하는 기능 구현
hanueleee Mar 26, 2023
6b996e0
feat(controller): controller 흐름 구현
hanueleee Mar 26, 2023
2fce195
feat(view): 입장하고자 하는 게임방의 id를 입력받는 기능 구현
hanueleee Mar 26, 2023
94b94b5
feat(ChessGameDao): 입장이 가능한 방을 탐색하는 기능과 입장이 불가능한 방을 탐색하는 기능 구분
hanueleee Mar 26, 2023
5f63a44
feat(view): 입장이 가능한 방과 입장이 불가능한 방에 대한 정보를 출력하는 기능 구현
hanueleee Mar 26, 2023
454b4fd
feat(controller): controller 흐름 구현
hanueleee Mar 26, 2023
a956f44
test(ChessGameDao): 테스트 작성
hanueleee Mar 26, 2023
6103b07
refactor(Board): 점수 계산 로직 수정
hanueleee Mar 26, 2023
ec29c04
fix(ChessGameDao): deleteAll 메소드 수정
hanueleee Mar 28, 2023
9f48022
refactor(ChessGameDao): db저장용 string을 만들고 탐색하는 과정에, enum의 name()과 val…
hanueleee Mar 28, 2023
37d7fd5
refactor: ChessService 도입 (controller의 역할을 분배)
hanueleee Mar 28, 2023
2bfd973
refactor: GameDao 역할분배 (GameDao & PieceDao)
hanueleee Mar 28, 2023
ffc1fdb
refactor: ConnectionProvider 분리
hanueleee Mar 28, 2023
bb8a678
refactor(Board): 기본 Board 생성 로직 수정
hanueleee Mar 28, 2023
f7e5b4a
refactor(GameDao): Dao로 ChessGame이 전달되지 않도록 수정
hanueleee Mar 28, 2023
4ed0147
refactor(PieceDao): 피스를 움직였을 경우, 전체 피스를 update하는 것이 아닌 해당 피스(2개)만 upd…
hanueleee Mar 28, 2023
ebeb8dc
refactor(PieceDao): Dao로 ChessGame이 전달되지 않도록 수정
hanueleee Mar 28, 2023
971e9e1
refactor(view): 게임 시작 안내 문구 출력 형식 수정
hanueleee Mar 28, 2023
04e132f
refactor(ChessService): 중복된 로직 메소드로 추출
hanueleee Mar 28, 2023
4081add
refactor(Board): Board 수정
hanueleee Mar 30, 2023
b654c0a
refactor(GameDao): delete&save로 이루어졌던 기존 update로직을, 실제 update쿼리를 사용하도…
hanueleee Mar 30, 2023
87d17fc
fix(BoardGenerator): 방어적 복사를 통한 generate 동작 버그 해결 (CACHE의 내부 값 변경 이슈)
hanueleee Mar 30, 2023
eb09d2e
refactor(Board): 점수 계산에 대한 책임 분리 (ScoreBoard)
hanueleee Mar 30, 2023
84bf1a0
refactor(ChessGame): 생성자 관련 구조 수정
hanueleee Mar 30, 2023
f7223bf
refactor(ChessService): 필드에 있었던 ChessGame을 ChessController로 이동
hanueleee Mar 30, 2023
c2020b2
refactor(PieceDao): 시그니처 수정
hanueleee Mar 30, 2023
08f0dfe
refactor(ChessGame): move 메소드의 반환값 삭제
hanueleee Mar 30, 2023
7299e31
refactor(ChessService): move 메소드 로직 수정
hanueleee Mar 30, 2023
ff4fffa
refactor(Dao): 메소드명 수정 (save -> create)
hanueleee Mar 30, 2023
737c6cd
test(ConnectionProvider): 연결 테스트
hanueleee Mar 30, 2023
849bea8
test(GameDao): GameInfoDto안에 gameId 넣기
hanueleee Mar 31, 2023
d409ced
test(ChessService): 서비스 테스트 코드 작성
hanueleee Mar 31, 2023
fd606fe
test: 테스트 보충
hanueleee Mar 31, 2023
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
104 changes: 101 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,105 @@
# java-chess

체스 미션 저장소
# 기능 목록

## 우아한테크코스 코드리뷰
# 🚀 도메인
## Piece
- [x] 진영을 가진다 (Color)
- [x] 타입을 가진다 (PieceType)
- [x] 종류별로 움직일 수 있는 방향을 가진다
- [x] 움직일 수 있는 방향인지 판단한다
- [x] 움직일 수 있는 거리인지 판단한다

- [온라인 코드 리뷰 과정](https://github.com/woowacourse/woowacourse-docs/blob/master/maincourse/README.md)
### 1) Rook
- [x] 점수 : 5점
- [x] 움직일 수 있는 방향 : N, E, S, W
- [x] 움직일 수 있는 거리 : 상관 x

### 2) Bishop
- [x] 점수 : 3점
- [x] 움직일 수 있는 방향 : NE, SE, SW, NW
- [x] 움직일 수 있는 거리 : 상관 x

### 3) Queen
- [x] 점수 : 9점
- [x] 움직일 수 있는 방향 : N, NE, E, SE, S, SW, W, NW
- [x] 움직일 수 있는 거리 : 상관 x

### 4) King
- [x] 점수 : 0점
- [x] 움직일 수 있는 방향 : N, NE, E, SE, S, SW, W, NW
- [x] 움직일 수 있는 거리 : 1
- [x] 잡히는 경우 경기가 끝난다

### 5) Knight
- [x] 점수 : 2.5점
- [x] 움직일 수 있는 방향 : ENE, ESE, SSW, SSE, WNW, WSW, NNW, NNE
- [x] 움직일 수 있는 거리 : 제곱의 합이 5 (ex. 2*2+1*1=5)
- [x] 경로에 다른 기물이 있어도 이동할 수 있다

### 6) Pawn
- [x] 점수
- [x] 기본 점수 : 1점
- [x] 같은 세로줄에 같은 색의 폰이 있는 경우 : 0.5점
- [x] 움직일 수 있는 방향
- [x] White 팀 : N, NE, NW
- [x] Black 팀 : S, SE, SW
- [x] 움직일 수 있는 거리
- [x] 처음 움직임 : 1 또는 2
- [x] 그 외 : 1
- [x] 대각선에 상대말이 있을 때에만 대각선으로 이동할 수 있다
- [x] 단순 이동은 위아래만 가능하다

### +) PieceFactory : 기본 세팅에 필요한 Piece들을 만든다
### +) PieceType : Piece의 종류를 나타내는 enum

## Position
- [x] file과 rank로 이루어진다
- [x] (A,1) ~ (H,8)
- [x] 다른 Position으로의 방향을 계산한다
- [x] 다른 Position으로의 거리를 계산한다
- [x] 다른 방향으로 이동할 수 있다

### +) Rank : 체스판의 가로줄을 나타내는 enum
### +) File : 체스판의 세로줄을 나타내는 enum
### +) Direction : 이동 방향을 나타내는 enum

## Board
- [x] 초기화한다 (기본 체스보드 세팅)
- [x] 특정 Position에 있는 Piece를 반환한다
- [x] 움직일 수 있는 Piece인지 확인한다
- [x] 빈 Piece인지
- [x] 같은 Color인지
- [x] 이동경로 사이에 다른 Piece가 있는지 확인한다
- [x] Piece를 교체한다
- [x] Rank에 위치한 Piece들을 반환한다
- [x] 각 진영의 점수를 계산한다

## ChessGame
- [x] 게임을 시작한다
- [x] Piece를 움직인다
- [x] King이 잡혔는지 확인한다
- [x] 각 진영의 점수를 반환한다
- [x] 게임을 끝낸다

### +) Color : Piece의 색을 나타내는 enum
### +) GameStatus : 게임의 상태를 나타내는 enum

## CommandLine
- [x] 입력을 검증한다
- [x] start
- [x] move - 2개의 추가 인자를 가져야 한다
- [x] status
- [x] end
- [x] 메인 명령 토큰을 제외한 나머지 인자들을 반환한다

# 🖋 UI
## 입력
- [x] 명령을 입력받는다

## 출력
- [x] 게임시작 메시지를 출력한다
- [x] 보드의 상태를 출력한다
- [x] 각 팀의 현재 점수를 출력한다
- [x] King이 잡혀 게임이 끝난 경우 우승자를 출력한다.
- [x] 에러를 출력한다
4 changes: 1 addition & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ repositories {
}

dependencies {
implementation 'com.sparkjava:spark-core:2.9.3'
implementation 'com.sparkjava:spark-template-handlebars:2.7.1'
implementation 'ch.qos.logback:logback-classic:1.2.10'
testImplementation 'org.assertj:assertj-core:3.22.0'
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.2'
runtimeOnly 'mysql:mysql-connector-java:8.0.28'
}

java {
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/chess/Applictaion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package chess;

import chess.controller.ChessController;

public class Applictaion {

public static void main(String[] args) {
ChessController chessController = new ChessController();
chessController.execute();
}
}
22 changes: 0 additions & 22 deletions src/main/java/chess/WebApplication.java

This file was deleted.

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

import chess.dao.JdbcGameDao;
import chess.dao.JdbcPieceDao;
import chess.domain.ChessGame;
import chess.domain.Color;
import chess.dto.BoardDto;
import chess.service.ChessService;
import chess.view.InputView;
import chess.view.OutputView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

public class ChessController {
private final ChessService chessService;
private final Map<String, GameAction> commandMapper = new HashMap<>();

public ChessController() {
chessService = new ChessService(new JdbcGameDao(), new JdbcPieceDao());
commandMapper.put("start", (gameId, ignore, chessGame) -> start(gameId, chessGame));
commandMapper.put("move", (gameId, arguments, chessGame) -> move(gameId, chessGame, arguments));
commandMapper.put("status", (ignore1, ignore2, chessGame) -> status(chessGame));
commandMapper.put("end", (gameId, ignore, chessGame) -> end(gameId, chessGame));
}

public void execute() {
List<Integer> possibleGameIds = chessService.findPossibleGameIds();
List<Integer> impossibleGameIds = chessService.findImpossibleGameIds();
OutputView.printRoomState(possibleGameIds, impossibleGameIds);

int gameId = InputView.readGameId();
ChessGame chessGame = chessService.loadChessGame(gameId);

OutputView.printGameStartMessage(gameId);
OutputView.printBoard(BoardDto.create(chessGame.getBoard()));

while (!chessGame.isEnd() && !chessGame.isCatch()) {
runGame(gameId, chessGame);
}

if (chessGame.isCatch()) {
OutputView.printResultWhenKingCatch(chessGame.getTurn().reverse());
return;
}
showStatus(chessGame);
}

private void runGame(int gameId, ChessGame chessGame) {
try {
CommandLine commandLine = new CommandLine(InputView.readCommand());
commandMapper.get(commandLine.getCommand())
.execute(gameId, commandLine.getArguments(), chessGame);
} catch (IllegalArgumentException | IllegalStateException | NoSuchElementException e) {
OutputView.printError(e.getMessage());
}
}

private void start(int gameId, ChessGame chessGame) {
chessService.start(gameId, chessGame);
OutputView.printBoard(BoardDto.create(chessGame.getBoard()));
}

private void move(int gameId, ChessGame chessGame, List<String> arguments) {
chessService.move(gameId, chessGame, arguments);
OutputView.printBoard(BoardDto.create(chessGame.getBoard()));
}

private void status(ChessGame chessGame) {
showStatus(chessGame);
}

private void end(int gameId, ChessGame chessGame) {
chessService.end(gameId, chessGame);
}

private void showStatus(ChessGame chessGame) {
Map<Color, Double> score = chessGame.status().getScore();
OutputView.printStatus(score.get(Color.WHITE), score.get(Color.BLACK));
}
}
48 changes: 48 additions & 0 deletions src/main/java/chess/controller/CommandLine.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package chess.controller;

import java.util.List;

public class CommandLine {

private static final String START = "start";
private static final String MOVE = "move";
private static final String STATUS = "status";
private static final String END = "end";
private static final int ZERO_ARGUMENT_SIZE = 1;
private static final int TWO_ARGUMENT_SIZE = 3;
private static final int SOURCE_INDEX = 1;
private static final int TARGET_INDEX = 3;
private static final int MAIN_COMMAND_INDEX = 0;
private static final List<String> VALID_COMMANDS = List.of(START, MOVE, END, STATUS);

private final List<String> tokens;

public CommandLine(final List<String> tokens) {
this.validate(tokens);
this.tokens = tokens;
}

private void validate(final List<String> tokens) {
String command = tokens.get(MAIN_COMMAND_INDEX);
if (!VALID_COMMANDS.contains(command)) {
throw new IllegalArgumentException("잘못된 명령어입니다.");
}
if (!command.equals(MOVE) && tokens.size() != ZERO_ARGUMENT_SIZE) {
throw new IllegalArgumentException(command + "는 인자를 입력할 수 없습니다.");
}
if (command.equals(MOVE) && tokens.size() != TWO_ARGUMENT_SIZE) {
throw new IllegalArgumentException(command + "는 인자를 2개만 가질 수 있습니다.");
}
}

public String getCommand() {
return this.tokens.get(MAIN_COMMAND_INDEX);
}

public List<String> getArguments() {
if (this.tokens.size() != TWO_ARGUMENT_SIZE) {
return List.of();
}
return this.tokens.subList(SOURCE_INDEX, TARGET_INDEX);
}
}
9 changes: 9 additions & 0 deletions src/main/java/chess/controller/GameAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package chess.controller;

import chess.domain.ChessGame;
import java.util.List;

@FunctionalInterface
public interface GameAction {
void execute(int gameId, List<String> arguments, ChessGame chessGame);
}
23 changes: 23 additions & 0 deletions src/main/java/chess/dao/ConnectionProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package chess.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class ConnectionProvider {
private static final String SERVER = "localhost:3306"; // MySQL 서버 주소
private static final String DATABASE = "chess"; // MySQL DATABASE 이름
private static final String OPTION = "?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
private static final String USERNAME = "username"; // MySQL 서버 아이디
private static final String PASSWORD = "password"; // MySQL 서버 비밀번호

public static Connection getConnection() {
try {
return DriverManager.getConnection("jdbc:mysql://" + SERVER + "/" + DATABASE + OPTION, USERNAME, PASSWORD);
} catch (final SQLException e) {
System.err.println("DB 연결 오류:" + e.getMessage());
e.printStackTrace();
return null;
}
}
}
14 changes: 14 additions & 0 deletions src/main/java/chess/dao/GameDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package chess.dao;

import chess.dto.GameInfoDto;
import java.util.List;

public interface GameDao {
List<Integer> findAllPossibleId();
List<Integer> findAllImpossibleId();
GameInfoDto findById(int gameId);
void create(GameInfoDto gameInfoDto);
void updateById(GameInfoDto gameInfoDto);
void deleteById(int gameId);
void deleteAll();
}
Loading