Skip to content

Commit

Permalink
[1단계 - 웹 자동차 경주] 마코(이규성) 미션 제출합니다. (#54)
Browse files Browse the repository at this point in the history
* feat : 기존 레이싱 게임 코드 가져오기

* docs : 기능 목록 추가

* feat : 레이싱카 서비스 추가

* docs : 서비스 구현 반영

* feat : 자동차 경주 게임 웹 요청/응답 구현

* style : 코드 정렬

* feat : h2 db 설정 및 테이블 생성

* feat : 게임 결과 및 플레이어 정보 DB 저장

* refactor : repository 계층 추가

* style : 코드 정렬

* style : 코드 정렬

* refactor : 문자열 trim 처리

* test : post 테스트 추가

* style : 코드 정렬

* refactor : 피드백 반영

* refactor : RacingGame 도메인 객체 추갸

* refactor : 불필요한 코드 제거

* refactor : 불필요한 코드 제거

---------

Co-authored-by: woowabrie <[email protected]>
  • Loading branch information
aak2075 and woowabrie authored Apr 17, 2023
1 parent 07ad425 commit 73897ea
Show file tree
Hide file tree
Showing 31 changed files with 909 additions and 9 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# jwp-racingcar

## 기능 구현
- [X] 웹 요청/응답 구현하기
- [X] 서비스 계층 생성
- [X] 웹 컨트롤러 생성
- [X] Post 요청 처리
- [X] DB 구현
- [X] 플레이 횟수
- [X] 플레이어 별 최종 이동 거리
- [X] 우승자
- [X] 플레이한 날짜/시간
8 changes: 8 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

implementation 'org.springframework.boot:spring-boot-starter-jdbc'

implementation 'net.rakugakibox.spring.boot:logback-access-spring-boot-starter:2.7.1'

testImplementation 'io.rest-assured:rest-assured:4.4.0'

runtimeOnly 'com.h2database:h2'
}

tasks.named('test') {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/racingcar/RacingCarApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
@SpringBootApplication
public class RacingCarApplication {

public static void main(String[] args) {
SpringApplication.run(RacingCarApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(RacingCarApplication.class, args);
}

}
20 changes: 20 additions & 0 deletions src/main/java/racingcar/RacingCarConsoleApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package racingcar;

import racingcar.controller.RacingController;
import racingcar.service.RacingCarService;
import racingcar.util.RandomNumberGenerator;
import racingcar.view.InputView;
import racingcar.view.OutputView;

public class RacingCarConsoleApplication {

public static void main(String[] args) {
RacingController racingController = new RacingController(
new InputView(),
new OutputView(),
new RacingCarService(new RandomNumberGenerator(), (racingGame) -> racingGame)
);

racingController.play();
}
}
27 changes: 27 additions & 0 deletions src/main/java/racingcar/controller/RacingCarWebController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package racingcar.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import racingcar.dto.RacingGameRequestDto;
import racingcar.dto.ResultResponseDto;
import racingcar.service.RacingCarService;

@Controller
public class RacingCarWebController {

private final RacingCarService racingCarService;

public RacingCarWebController(RacingCarService racingCarService) {
this.racingCarService = racingCarService;
}

@PostMapping("/plays")
@ResponseBody
public ResponseEntity<ResultResponseDto> play(@RequestBody RacingGameRequestDto request) {
ResultResponseDto responseDto = racingCarService.play(request);
return ResponseEntity.ok().body(responseDto);
}
}
48 changes: 48 additions & 0 deletions src/main/java/racingcar/controller/RacingController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package racingcar.controller;

import racingcar.dto.RacingGameRequestDto;
import racingcar.dto.ResultResponseDto;
import racingcar.service.RacingCarService;
import racingcar.view.InputView;
import racingcar.view.OutputView;

import java.util.List;

public class RacingController {

private final InputView inputView;
private final OutputView outputView;
private final RacingCarService racingCarService;

public RacingController(InputView inputView, OutputView outputView, RacingCarService racingCarService) {
this.inputView = inputView;
this.outputView = outputView;
this.racingCarService = racingCarService;
}

public void play() {
List<String> carNames = inputCarNames();
int tryCount = inputTryCount();
var requestDto = new RacingGameRequestDto(carNames, tryCount);

ResultResponseDto resultResponseDto = racingCarService.play(requestDto);

outputView.printStatus(resultResponseDto);
outputView.printWinners(resultResponseDto);
}

private List<String> inputCarNames() {
try {
outputView.printStartMessage();
return inputView.inputCarName();
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
return inputCarNames();
}
}

private int inputTryCount() {
outputView.printCountMessage();
return inputView.inputCount();
}
}
47 changes: 47 additions & 0 deletions src/main/java/racingcar/dao/RacingCarGameDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package racingcar.dao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.stereotype.Component;
import racingcar.dao.entity.Game;
import racingcar.dao.entity.Player;

import java.sql.PreparedStatement;
import java.sql.Statement;

@Component
public class RacingCarGameDao {

private final JdbcTemplate jdbcTemplate;

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

public Long insertGameWithKeyHolder(Game game) {
String sql = "INSERT INTO game(play_count, winners) VALUES(?, ?)";

GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setLong(1, game.getPlayCount());
ps.setString(2, game.getWinners());
return ps;
}, keyHolder);

return Long.valueOf(String.valueOf(keyHolder.getKeys().get("game_id")));

}

public void insertPlayer(Player player) {
String sql = "INSERT INTO player(name, position, game_id) VALUES(?, ?, ?)";

jdbcTemplate.update(sql, player.getName(), player.getPosition(), player.getGameId());
}

public void updateGame(Game game) {
String sql = "UPDATE game SET play_count = ?, winners = ? WHERE game_id = ?";

jdbcTemplate.update(sql, game.getPlayCount(), game.getWinners(), game.getGameId());
}
}
27 changes: 27 additions & 0 deletions src/main/java/racingcar/dao/entity/Game.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package racingcar.dao.entity;

public class Game {

private final Long gameId;
private final int playCount;
private final String winners;

public Game(Long gameId, int playCount, String winners) {
this.gameId = gameId;
this.playCount = playCount;
this.winners = winners;
}

public Long getGameId() {
return gameId;
}

public int getPlayCount() {
return playCount;
}

public String getWinners() {
return winners;
}

}
39 changes: 39 additions & 0 deletions src/main/java/racingcar/dao/entity/Player.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package racingcar.dao.entity;

public class Player {

private final Long playerId;
private final String name;
private final int position;
private final Long gameId;

public Player(String name, int position, Long gameId) {
this.playerId = null;
this.name = name;
this.position = position;
this.gameId = gameId;
}

public Player(Long playerId, String name, int position, Long gameId) {
this.playerId = playerId;
this.name = name;
this.position = position;
this.gameId = gameId;
}

public Long getPlayerId() {
return playerId;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

public Long getGameId() {
return gameId;
}
}
58 changes: 58 additions & 0 deletions src/main/java/racingcar/domain/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package racingcar.domain;

import racingcar.exception.CarNameLengthException;

public class Car {

private static final int INIT_POSITION = 0;
private static final int MIN_MOVABLE_POWER = 4;
private static final int MAX_CAR_NAME_LENGTH = 5;

private final String name;
private int position;

public Car(String name) {
validateCarName(name);
this.name = name;
position = INIT_POSITION;
}

public Car(String name, int position) {
validateCarName(name);
this.name = name;
this.position = position;
}

public void move(int power) {
if (movable(power)) {
position = position + 1;
}
}

private boolean movable(int power) {
return power >= MIN_MOVABLE_POWER;
}

public void validateCarName(String name) {
if (name.length() > MAX_CAR_NAME_LENGTH) {
throw new CarNameLengthException();
}
}

public boolean equalsPosition(Car other) {
return this.position == other.position;
}

public int compareTo(Car other) {
return this.position - other.position;
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}

}
61 changes: 61 additions & 0 deletions src/main/java/racingcar/domain/Cars.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package racingcar.domain;

import racingcar.util.NumberGenerator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class Cars {

private final List<Car> cars;

public Cars() {
cars = new ArrayList<>();
}

public Cars(List<Car> cars) {
this.cars = new ArrayList<>(cars);
}

public static Cars of(List<String> carNames) {
List<Car> cars = new ArrayList<>();
for (String carName : carNames) {
cars.add(new Car(carName));
}

return new Cars(cars);
}

public void addCar(Car car) {
cars.add(car);
}

public void moveAll(NumberGenerator numberGenerator) {
for (Car car : cars) {
car.move(numberGenerator.generate());
}
}

public List<Car> getWinners() {
Car maxPositionCar = findMaxPositionCar();
return findSamePositionCar(maxPositionCar);
}

private List<Car> findSamePositionCar(Car car) {
return cars.stream()
.filter(it -> it.equalsPosition(car))
.collect(Collectors.toUnmodifiableList());
}

private Car findMaxPositionCar() {
return cars.stream()
.max(Car::compareTo)
.orElseThrow();
}

public List<Car> getCars() {
return Collections.unmodifiableList(cars);
}
}
Loading

0 comments on commit 73897ea

Please sign in to comment.