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

[강원대 BE_김병수] 미션 제출합니다. #5547

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,29 @@
* 모든 피드백을 완료하면 다음 단계를 도전하고 앞의 과정을 반복한다.

## 온라인 코드 리뷰 과정
* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview)
* [텍스트와 이미지로 살펴보는 온라인 코드 리뷰 과정](https://github.com/next-step/nextstep-docs/tree/master/codereview)

# 기능 명세서
## 1. 개요
* 자동차 경주 게임의 기능과 동작을 설명한다. 이 프로그램은 사용자가 자동차를 전진시켜 경주를 진행하고, 경주 결과를 확인할 수 있는 기능을 보여준다
## 2. 주요 기능
* 1. 자동차 초기화 : 사용자는 게임을 시작할 때 자신이 원하는 자동차의 갯수 만큼 자동차를 초기화 한다.
* 2. 전진 : 각 자동차는 주어진 횟수만큼 전진한다.
* 3. 우승자 선정 : 경기가 끝난 후, 가장 멀리 전진한 자동차를 우승자로 선정한다.

## 3. 기능 설명
### 3.1 자동차 초기화
* 사용자는 게임 시작 시 초기화 할 자동차의 이름을 입력한다.
* 입력한 이름으로 자동차를 초기화하고, 자동차를 시작선에서 출발한다.
### 3.2 전진
* 사용자는 게임 진행 시 각 자동차를 이동시킬 횟수를 입력한다.
* 입력한 횟수만큼 각 자동차는 랜덤하게(60% 확률로 전진) 전진한다.
* 이동은 random을 생성하고 전진할지 여부를 결정한다.
* 전진하는 자동차는 전진한 거리만큼 출력한다.
### 3.3 우승자 선정
* 모든 자동차의 이동이 끝나면, 가장 멀리 이동한 자동차를 우승자로 선정한다.
* 우승자는 화면에 표시된다.

## 4. 제약 사항
* 개발 언어 : Java
* 테스트 환경 : JUnit을 이용한 테스트
10 changes: 10 additions & 0 deletions src/main/java/racingcar/Application.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package racingcar;

import racingcar.controller.RacingController;

public class Application {
public static void main(String[] args){
RacingController controller = new RacingController();
controller.racingStart();
}
}
29 changes: 29 additions & 0 deletions src/main/java/racingcar/controller/RacingController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package racingcar.controller;

import racingcar.model.CarRacing;
import racingcar.view.InputHandler;
import racingcar.view.OutputRenderer;

public class RacingController {

public void racingStart(){
try{
String[] carNames = InputHandler.getCarNames();
int tryCnt = InputHandler.getTryCnt();

CarRacing carRacing = new CarRacing(carNames, tryCnt);
runRaces(carRacing);

OutputRenderer.printWinners(carRacing.getWinners());
} catch(IllegalArgumentException e){
OutputRenderer.printError(e.getMessage());
}
}

private void runRaces(CarRacing carRacing){
for(int i=0; i<carRacing.getTryCnt(); i++){
carRacing.race();
OutputRenderer.printRaceStatus(carRacing.getCars());
}
}
}
32 changes: 32 additions & 0 deletions src/main/java/racingcar/model/Car.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package racingcar.model;

public class Car {
private String name;
private int position;

public Car(String name){
nameCheck(name);
this.name = name;
this.position = 0;
}

private void nameCheck(String name){
if(name==null || name.trim().isEmpty() || name.length()>=5){
throw new IllegalArgumentException("자동차 이름은 1자 이상, 5자 이하만 가능합니다.");
}
}

public void move(boolean move){
if(move){
position ++;
}
}

public String getName() {
return name;
}

public int getPosition() {
return position;
}
}
60 changes: 60 additions & 0 deletions src/main/java/racingcar/model/CarRacing.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package racingcar.model;

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

public class CarRacing {
private List<Car> cars;
private int tryCtn;
private Random random;

public CarRacing(String[] carNames, int tryCtn) {
this.cars = initCar(carNames);
this.tryCtn = tryCtn;
this.random = new Random();
}

private List<Car> initCar(String[] carNames) {
List<Car> cars = new ArrayList<>();
for (String name : carNames) {
cars.add(new Car(name));
}
return cars;
}

public void race() {
for (Car car : cars) {
car.move(random.nextInt(10) >= 4);
}
}

public List<Car> getCars(){
return cars;
}

public int getTryCnt(){
return tryCtn;
}

public String getWinners(){
int maxPosition = getMaxPosition();
List<String> winnerNames = new ArrayList<>();

for (Car car : cars) {
if (car.getPosition() == maxPosition) {
winnerNames.add(car.getName());
}
}
return String.join(", ", winnerNames);
}

private int getMaxPosition(){
int maxPosition = 0;
for(Car car : cars){
maxPosition = Math.max(maxPosition, car.getPosition());
}
return maxPosition;
}
}
25 changes: 25 additions & 0 deletions src/main/java/racingcar/utils/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package racingcar.utils;

public class Utils {
public static String[] nameAnalysis(String input){
String[] names = input.split(",");
for(String name : names){
if(name.trim().isEmpty() || name.length()>5){
throw new IllegalArgumentException("자동차 이름은 5자 이하만 가능합니다.");
}
}
return names;
}

public static int tryAnalysis(String input){
try {
int tryCnt = Integer.parseInt(input);
if (tryCnt < 1) {
throw new IllegalArgumentException("시도 횟수는 1회 이상으로 입력해야합니다.");
}
return tryCnt;
} catch(NumberFormatException e){
throw new IllegalArgumentException("유효한 입력을 해야합니다.");
}
}
}
21 changes: 21 additions & 0 deletions src/main/java/racingcar/view/InputHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package racingcar.view;

import racingcar.utils.Utils;

import java.util.Scanner;

public class InputHandler {
private static final Scanner sc = new Scanner(System.in);

public static String[] getCarNames(){
System.out.println("경주할 자동차 이름을 입력하세요.(이름은 쉽표(,) 기준으로 구분)");
String input = sc.nextLine();
return Utils.nameAnalysis(input);
}

public static int getTryCnt(){
System.out.println("시도할 회수는 몇회인가요?");
String input = sc.nextLine();
return Utils.tryAnalysis(input);
}
}
22 changes: 22 additions & 0 deletions src/main/java/racingcar/view/OutputRenderer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package racingcar.view;

import java.util.List;
import racingcar.model.Car;

public class OutputRenderer {

public static void printRaceStatus(List<Car> cars){
for(Car car : cars){
System.out.println(car.getName()+" : "+"-".repeat(car.getPosition()));
}
System.out.println();
}

public static void printWinners(String winners){
System.out.println("최종 우승자 : " + winners);
}

public static void printError(String message){
System.out.println("[ERROR]: " + message);
}
}
47 changes: 47 additions & 0 deletions src/test/java/racingcar/model/CarRacingTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package racingcar.model;

import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class CarRacingTest {

@Test
void racingTest(){
String[] names = {"pobi", "woni", "jun"};
int tryCnt = 5;

CarRacing carRacing = new CarRacing(names, tryCnt);

for(int i=0; i<tryCnt; i++){
carRacing.race();
}

List<Car> cars = carRacing.getCars();
for(Car car: cars){
assertTrue(car.getPosition() >= 0);
}
}

@Test
void WinnersTest(){
String[] names = {"pobi", "woni", "jun"};
int tryCnt = 5;

CarRacing carRacing = new CarRacing(names, tryCnt);

carRacing.getCars().get(0).move(true);
carRacing.getCars().get(0).move(true);
carRacing.getCars().get(0).move(true);

carRacing.getCars().get(1).move(true);
carRacing.getCars().get(1).move(true);

carRacing.getCars().get(2).move(true);

assertEquals("pobi", carRacing.getWinners());
}
}
31 changes: 31 additions & 0 deletions src/test/java/racingcar/model/CarTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package racingcar.model;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

public class CarTest {

@Test
void carInitTest(){
String name = "pobi";

Car car = new Car(name);

assertEquals(name, car.getName());
assertEquals(0, car.getPosition());
}

@Test
void moveTest(){

Car car = new Car("pobi");

car.move(true);
assertEquals(1, car.getPosition());

car.move(false);
assertEquals(1, car.getPosition());
}
}