Skip to content

Commit

Permalink
[Spring 체스 - 2단계] 레넌(조형래) 미션 제출합니다. (#473)
Browse files Browse the repository at this point in the history
* refactor: 의존성 주입 생성자 방식으로 변경

* refactor: init.sql 순서 변경

* refactor: DB 수정 및 schema.sql추가

* feat: CRUD 가능하도록 GameDao, BoardDao 작성

* feat: ChessService 로직 작성

* feat: 체스방에 참여하는 기능 구현

* chore: spark 관련 dependency 제거

* test: 가짜 객체를 통한 service test 작성

* refactor: 줄바꿈 제거 및 파일 이름 수정

* chore: 패키지 이름 dao로 변경

* chore: 사용하지 않는 클래스 제거

* refactor: RoomDto로 데이터 전달받도록 수정

* refactor: Model을 주입 받는 방식으로 수정 및 메소드 이름 & 매핑 방식 수정

* refactor: FakeDao 패키지 이동 및 누락된 테스트 코드 작성

* refactor: StatusDto scores를 파라미터로 받도록 수정

* chore: css파일 분리 및 password 타입 변경

* refactor: 방 이름 검증 로직 Dto로 변경 및 예외처리

* refactor: 테스트 코드에서만 사용되는 메소드 제거

* refactor: toString 메소드 사용 제거

* refactor: 미사용 메서드 제거

* refactor: DB Column의 길이에 맞춰 검증로직 추가

* refactor: Game Entity 추가하여 GameDao에서 반환하도록 변경

* test: 누락된 delete 메서드 테스트 추가

* refactor: 테스트 코드에서만 사용되는 메서드 제거

* refactor: 공백 제거

* refactor: 파라미터 변경 및 코드 간단하게 수정

* chore: application.yml 분리

* refactor: state, piece 상수 enum에서 관리하도록 수정

* refactor: dto 정적팩토리 메서드 작성 및 코드 수정

* refactor: RowMapper 적용 및 Dto로 책임 분리

* refactor: Game에 비밀번호가 같은지 메시지를 던지도록 수정

* refactor: 불필요 메서드 제거

* refactor: 공백 제거
  • Loading branch information
brorae authored May 4, 2022
1 parent dd5d7b1 commit d0e939a
Show file tree
Hide file tree
Showing 47 changed files with 1,269 additions and 575 deletions.
3 changes: 0 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ 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'
Expand Down
16 changes: 9 additions & 7 deletions docker/db/mysql/init/init.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
create table game
(
id int auto_increment
primary key,
title varchar(20) not null,
password varchar(20) not null,
state varchar(20) not null
);

create table board
(
position varchar(5) not null,
Expand All @@ -9,10 +18,3 @@ create table board
foreign key (game_id) references game (id)
on update cascade on delete cascade
);

create table game
(
id int auto_increment
primary key,
state varchar(20) not null
);
6 changes: 6 additions & 0 deletions src/main/java/chess/controller/ErrorController.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package chess.controller;

import org.springframework.beans.BeanInstantiationException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
Expand All @@ -8,6 +9,11 @@
@ControllerAdvice
public class ErrorController {

@ExceptionHandler(BeanInstantiationException.class)
public ResponseEntity<String> errorBeanResponse(IllegalArgumentException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}

@ExceptionHandler({IllegalStateException.class, IllegalArgumentException.class})
public ResponseEntity<String> errorResponse(Exception e) {
return ResponseEntity.badRequest().body(e.getMessage());
Expand Down
78 changes: 51 additions & 27 deletions src/main/java/chess/controller/WebController.java
Original file line number Diff line number Diff line change
@@ -1,64 +1,88 @@
package chess.controller;

import chess.domain.chessboard.ChessBoard;
import chess.domain.piece.generator.NormalPiecesGenerator;
import chess.dto.BoardDto;
import chess.dto.GameDto;
import chess.dto.MoveDto;
import chess.dto.RoomDto;
import chess.dto.StatusDto;
import chess.service.ChessService;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class WebController {

private final ChessService chessService;

@Autowired
public WebController(ChessService chessService) {
this.chessService = chessService;
}

@GetMapping("/")
public ModelAndView selectGame() {
BoardDto boardDto = chessService.selectBoard();
String winner = chessService.selectWinner();
public String selectGame(Model model) {
List<GameDto> games = chessService.findGame();
model.addAttribute("game", games);
return "index";
}

@PostMapping("/game")
public String insertGame(RoomDto roomDto) {
chessService.insertGame(roomDto, new ChessBoard(new NormalPiecesGenerator()));
return "redirect:/";
}

Map<String, Object> model = new HashMap<>();
model.put("board", boardDto);
model.put("winner", winner);
@GetMapping("/game/{gameId}")
public String startGame(@PathVariable int gameId, Model model) {
BoardDto boardDto = chessService.selectBoard(gameId);
String winner = chessService.selectWinner(gameId);
String state = chessService.selectState(gameId);

return new ModelAndView("index", model);
model.addAttribute("board", boardDto);
model.addAttribute("id", gameId);
model.addAttribute("winner", winner);
model.addAttribute("state", state);

return "game";
}

@GetMapping("/game")
public ModelAndView insertGame() {
chessService.insertGame();
return new ModelAndView("redirect:/");
@PutMapping("/game/board/{gameId}")
public String movePiece(@PathVariable int gameId, MoveDto moveDto) {
chessService.movePiece(gameId, moveDto.getFrom(), moveDto.getTo());
return "redirect:/game/" + gameId;
}

@PutMapping("/game/board")
public ModelAndView updateBoard(MoveDto moveDto) {
chessService.updateBoard(moveDto.getFrom(), moveDto.getTo());
return new ModelAndView("redirect:/");
@PutMapping("/game/{gameId}")
public String restartGame(@PathVariable int gameId) {
chessService.restartGame(gameId);
return "redirect:/game/" + gameId;
}

@GetMapping("/game/status")
@GetMapping("/game/status/{gameId}")
@ResponseBody
public ResponseEntity<StatusDto> selectStatus() {
StatusDto statusDto = chessService.selectStatus();
public ResponseEntity<StatusDto> selectStatus(@PathVariable int gameId) {
StatusDto statusDto = chessService.selectStatus(gameId);
return ResponseEntity.ok().body(statusDto);
}

@DeleteMapping("/game")
public ModelAndView deleteGame() {
chessService.deleteGame();
return new ModelAndView("redirect:/");
@PutMapping("/game/end/{gameId}")
public String endGame(@PathVariable int gameId) {
chessService.endGame(gameId);
return "redirect:/";
}

@DeleteMapping("/game/{gameId}")
public String deleteGame(@PathVariable int gameId, String password) {
chessService.deleteGame(gameId, password);
return "redirect:/";
}
}
15 changes: 15 additions & 0 deletions src/main/java/chess/dao/BoardDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package chess.dao;

import chess.entity.Square;
import java.util.List;

public interface BoardDao {

void save(List<Square> squares);

List<Square> findById(int id);

int update(Square square);

void delete(int gameId);
}
59 changes: 59 additions & 0 deletions src/main/java/chess/dao/BoardDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package chess.dao;

import chess.entity.Square;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

@Repository
public class BoardDaoImpl implements BoardDao {

private JdbcTemplate jdbcTemplate;

private RowMapper<Square> rowMapper = (rs, rowNum) ->
new Square(
rs.getString("position"),
rs.getString("symbol"),
rs.getString("color")
);

public BoardDaoImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public void save(List<Square> squares) {
String sql = "insert into board (position, symbol, color, game_id) values (?, ?, ?, ?)";

List<Object[]> board = squares.stream()
.map(square -> new Object[]{
square.getPosition(),
square.getSymbol(),
square.getColor(),
square.getGameId()})
.collect(Collectors.toList());

jdbcTemplate.batchUpdate(sql, board);
}

@Override
public List<Square> findById(int id) {
String sql = "select position, symbol, color from board where game_id = ?";
return jdbcTemplate.query(sql, rowMapper, id);
}

@Override
public int update(Square square) {
String sql = "update board set symbol = ?, color = ? where game_id = ? and position = ?";
return jdbcTemplate.update(sql, square.getSymbol(), square.getColor(), square.getGameId(),
square.getPosition());
}

@Override
public void delete(int gameId) {
String sql = "delete from board where game_id = ?";
jdbcTemplate.update(sql, gameId);
}
}
17 changes: 17 additions & 0 deletions src/main/java/chess/dao/GameDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package chess.dao;

import chess.entity.Game;
import java.util.List;

public interface GameDao {

int save(Game game);

List<Game> findAll();

Game findById(int id);

int update(Game game);

int delete(int id);
}
65 changes: 65 additions & 0 deletions src/main/java/chess/dao/GameDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package chess.dao;

import chess.entity.Game;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;

@Repository
public class GameDaoImpl implements GameDao {

private JdbcTemplate jdbcTemplate;

private RowMapper<Game> rowMapper = (rs, rowNum) ->
new Game(
rs.getInt("id"),
rs.getString("title"),
rs.getString("password"),
rs.getString("state")
);

public GameDaoImpl(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

@Override
public int save(Game game) {
SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate).withTableName("game")
.usingGeneratedKeyColumns("id");
Map<String, String> params = new HashMap<>();
params.put("title", game.getTitle());
params.put("password", game.getPassword());
params.put("state", game.getState());

return simpleJdbcInsert.executeAndReturnKey(params).intValue();
}

@Override
public List<Game> findAll() {
String sql = "select * from game";
return jdbcTemplate.query(sql, rowMapper);
}

@Override
public Game findById(int id) {
String sql = "select * from game where id = ?";
return jdbcTemplate.queryForObject(sql, rowMapper, id);
}

@Override
public int update(Game game) {
String sql = "update game set state=? where id = ?";
jdbcTemplate.update(sql, game.getState(), game.getId());
return game.getId();
}

@Override
public int delete(int id) {
String sql = "delete from game where id = ?";
return jdbcTemplate.update(sql, id);
}
}
6 changes: 0 additions & 6 deletions src/main/java/chess/domain/chessboard/ChessBoard.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,4 @@ public Color getWinner() {
public Map<Position, Piece> getPieces() {
return Collections.unmodifiableMap(pieces);
}

public Map<String, Piece> toMap() {
return pieces.entrySet()
.stream()
.collect(Collectors.toMap(m -> m.getKey().toString(), Map.Entry::getValue));
}
}
16 changes: 3 additions & 13 deletions src/main/java/chess/domain/piece/Piece.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import chess.domain.position.Direction;
import chess.domain.position.Position;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -11,19 +12,8 @@ public abstract class Piece {
private static final Map<String, Piece> cache = new HashMap<>();

static {
cache.put("WHITEKING", new King(Color.WHITE));
cache.put("BLACKKING", new King(Color.BLACK));
cache.put("WHITEQUEEN", new Queen(Color.WHITE));
cache.put("BLACKQUEEN", new Queen(Color.BLACK));
cache.put("WHITEROOK", new Rook(Color.WHITE));
cache.put("BLACKROOK", new Rook(Color.BLACK));
cache.put("WHITEKNIGHT", new Knight(Color.WHITE));
cache.put("BLACKKNIGHT", new Knight(Color.BLACK));
cache.put("WHITEBISHOP", new Bishop(Color.WHITE));
cache.put("BLACKBISHOP", new Bishop(Color.BLACK));
cache.put("WHITEPAWN", new Pawn(Color.WHITE));
cache.put("BLACKPAWN", new Pawn(Color.BLACK));
cache.put("EMPTYEMPTY", EmptyPiece.getInstance());
Arrays.stream(PieceName.values()).forEach(
gamePiece -> cache.put(gamePiece.getValue(), gamePiece.getPiece()));
}

protected final Symbol symbol;
Expand Down
Loading

0 comments on commit d0e939a

Please sign in to comment.