Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b260211
* feat : 1단계 구현
JihwanYeom Mar 12, 2025
d5a9797
* test : Car 객체 테스트 코드 작성
JihwanYeom Mar 12, 2025
92c56ec
* feat : 2단계 구현
JihwanYeom Mar 12, 2025
9e69781
* test : makeWinnerList() 테스트코드 작성
JihwanYeom Mar 12, 2025
d187dc8
* docs : README 작성
JihwanYeom Mar 12, 2025
15ed321
* docs : README 수정
JihwanYeom Mar 15, 2025
e38bd09
* fix : Car, Game 클래스 리뷰 1차 반영
JihwanYeom Mar 15, 2025
96b822e
* test : 테스트 코드 리뷰 1차 반영
JihwanYeom Mar 15, 2025
11094f8
* feat : 3단계 구현
JihwanYeom Mar 19, 2025
7b7c714
* test : 4단계 부분 구현
JihwanYeom Mar 19, 2025
a1b7358
Merge branch 'jihwanyeom' into jihwanyeom
JihwanYeom Mar 19, 2025
833a5a8
* test : Car 테스트 수정
JihwanYeom Mar 22, 2025
46cbdbf
* test : Cars 테스트 코드 작성
JihwanYeom Mar 22, 2025
1386774
* test : Game 테스트 코드 삭제 및 Racing 테스트 코드 작성
JihwanYeom Mar 22, 2025
e6e1089
* test : Controller 테스트 코드 작성
JihwanYeom Mar 22, 2025
40fd209
* test : View 테스트 코드 작성
JihwanYeom Mar 22, 2025
2943098
* refactor : Controller 인스턴스 변수 최소화
JihwanYeom Mar 22, 2025
e9de809
* refactor : 같은 거리의 자동차를 구하는 로직의 메서드 명 변경
JihwanYeom Mar 22, 2025
34995d0
* feat : 사용자 입력 안내 메세지 출력 메서드 추가
JihwanYeom Mar 22, 2025
759de06
* style : RacingApplicaion에 개행 추가
JihwanYeom Mar 22, 2025
bd2d256
* docs : README.md 업데이트
JihwanYeom Mar 22, 2025
df2090b
* chore : 생성자 중복제거
JihwanYeom Mar 22, 2025
30742b5
Merge remote-tracking branch 'origin/jihwanyeom' into jihwanyeom
JihwanYeom Mar 22, 2025
c916e39
docs : README.md 오타 변경
JihwanYeom Mar 22, 2025
2c48874
chore : 불필요해진 파일 삭제
JihwanYeom Mar 23, 2025
0c0ba23
style : 실행파일 불필요한 개행 제거
JihwanYeom Mar 23, 2025
cb2c86a
feat : 이름에 대한 예외처리 추가
JihwanYeom Mar 23, 2025
0050f0f
feat : 이름에 대한 예외처리를 입력단에 추가
JihwanYeom Mar 23, 2025
4995016
refactor : Cars 객체 생성전략 변경
JihwanYeom Mar 23, 2025
f4133eb
refactor : RandomNumberGenerator 클래스 수정
JihwanYeom Mar 23, 2025
eed3c57
refactor : OutputView 포맷 관련 메서드 수정
JihwanYeom Mar 23, 2025
1350e36
test : Cars 테스트에 Fixture 적용
JihwanYeom Mar 23, 2025
38976c5
style : 코드 서식 점검
JihwanYeom Mar 23, 2025
97bb64d
test : 입력 서식 검증 테스트 추가
JihwanYeom Mar 23, 2025
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
61 changes: 46 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,68 @@
모든 라운드가 끝난 뒤 가장 많이 이동한 자동차들이 우승하게 됩니다.

## 🎮게임 규칙
* 🚗 게임에 참가할 자동차 수와 라운드 수를 정하고 게임을 시작합니다.
* 🚗 게임에 참가할 자동차 이름을 입력합니다(자동차 이름의 길이는 5이하여야 합니다)


* 🎲 게임이 시작되면 모든 차는 매 라운드마다 랜덤으로 발생한 0부터 10까지의 숫자 중 3 이하가 나올 경우 정지해있고, 4이상의 숫자가 나올 경우 1만큼 전진합니다.
* 🏁 라운드 수를 정하고 게임을 시작합니다.


* 🎲 게임이 시작되면 모든 차는 매 라운드마다 랜덤으로 발생한 0부터 9까지의 숫자 중 3 이하가 나올 경우 정지해있고, 4이상의 숫자가 나올 경우 1만큼 전진합니다.


* 🏆 모든 라운드가 끝나고 우승한 자동차를 확인하면 됩니다.

## 🔧프로젝트 설계
프로젝트는 크게 자동차, 게임을 구현한 두개의 클래스로 작성되었습니다.
### 🚗자동차 클래스
* 자동차 클래스는 필드로 이름과 이동 거리를 가지고 있습니다.
프로젝트는 MVC 모델을 적용하여 controller, domain((model), view
패키지로 이루어져 있습니다. 메인 클래스를 실행하면 controller 객체의
게임 실행 메서드가 실행되어 게임이 진행됩니다.


* 생성자는 이름을 매개변수로 받아 초기화하고 이동거리를 0으로 초기화합니다.
### ⚙️Domain
* domain 패키지는 자동차, 자동차의 리스트, 레이싱, 랜덤 변수 생성 클래스로 이루어져
있습니다.


* 자동차의 이동 메서드는 매개변수로 받은 값이 4 이상일 경우 이동거리를 1 증가시킵니다.
* 자동차 클래스는 이름과 이동한 거리를 저장하고 있으며 생성된 랜덤 변수에
따라 한 칸 전진하는 메서드, 자신의 현재 위치가 주어진 값과 같은지 반환하는
메서드로 구성되어 있습니다.

### 🎮Game 클래스
* 참가하는 차들과 우승한 차를 저장하기 위해 두 개의 리스트를 가지고 있습니다.


* 게임 실행 메서드는 차 갯수와 라운드 수를 매개변수로 받아 게임 초기화, 게임 진행, 우승자 선정을 수행합니다.
* 자동차 리스트 클래스는 자동차들의 배열을 저장하고 있습니다. 또한 리스트에
저장된 자동차들을 이동시키는 메서드, 리스트에 저장된 자동차 중 가장 멀리
이동한 자동차의 이동 거리를 반환하는 메서드, 어떤 한 위치에 있는 모든 자동차
들의 리스트를 반환하는 메서드로 이루어져 있습니다.


* 레이싱 클래스는 참가한 자동차들의 리스트를 저장하고 있으며 참가한 자동차들을
전부 이동시키는 메서드와 참가한 자동차들 중 우승자들의 리스트를 반환하는
메서드를 가지고 있습니다.


* 랜덤 변수 생성 클래스는 0부터 9사이의 숫자를 생성해서 반환하는 메서드를
가지고 있습니다.

### 💻View
- view 패키지는 입력을 담당하는 클래스와 출력을 담당하는 클래스를 담당하는
클래스로 이루어져 있습니다.


- 입력을 담당하는 클래스는 자동차들의 이름을 양식에 맞게 입력받아 이를 문자열의
배열로 변환하여 반환하는 메서드와, 라운드 수를 입력받는 메서드로 이루어져 있습니다.


- 출력을 담당하는 클래스는 사용자 입력 요청을 출력하는 메서드와 게임 현황을
출력하는 메서드, 우승자 리스트를 출력하는 메서드를 가지고 있습니다.


* 게임 초기화 메서드는 게임 실행 중 가장 먼저 호출되어 차 갯수를 매개변수로 받아 갯수만큼 자동차 객체를 생성하여 리스트에 저장합니다. 현 단계에서는 차 이름이 순차적으로 자동생성됩니다.( ex)Car_1, Car_2, ... )
- 출력의 양식을 지키기 위한 포맷팅 메서드도 출력을 담당하는 클래스에
포함되어 있습니다


* 라운드 진행 메서드는 라운드 수만큼 실행되며 게임에 참여한 모든 차의 이동 메서드를 호출합니다.
이때 각 자동차마다 랜덤 변수 생성기를 통해 0부터 10까지의 숫자 중 하나를 매개변수로 줍니다
### 🎮Controller


* 우승자 선정 메서드는 모든 라운드가 끝난 후 가장 먼 거리를 이동한 차들을 우승자 리스트에 저장합니다.
* Controller 클래스는 domain과 view의 클래스들을 이용하여 게임을 진행합니다
게임 실행 메서드가 실행되면 사용자에게 자동차 이름과 라운드 수를 입력받아
레이싱을 수행합니다. 레이싱이 끝나면 우승자 리스트를 출력하고 메서드가
종료됩니다.
Comment on lines +72 to +75

Choose a reason for hiding this comment

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

추가된 요구사항에 맞게 기능 명세서도 업데이트 하셨네요!
문서화도 관리 대상입니다. 아주 좋은 습관이에요👍👍

12 changes: 12 additions & 0 deletions src/main/java/RacingApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import controller.RacingController;
import domain.RandomNumberGenerator;

public class RacingApplication {

public static void main(String[] args) {

new RacingController().run(new RandomNumberGenerator());

}
Copy link

@TaeyeonRoyce TaeyeonRoyce Mar 22, 2025

Choose a reason for hiding this comment

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

줄바꿈도 의도가 담길 수 있어요. 필요 없는 줄바꿈이라면, 오해하지 않게 깔끔하게 관리해주세요

Suggested change
public static void main(String[] args) {
new RacingController().run(new RandomNumberGenerator());
}
public static void main(String[] args) {
new RacingController().run(new RandomNumberGenerator());
}


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

import domain.Cars;
import domain.Racing;
import domain.NumberGenerator;
import java.util.List;
import view.InputView;
import view.OutputView;

public class RacingController {

private static final int NAME_LENGTH_LIMIT = 5;

public void run(NumberGenerator numberGenerator) {

OutputView.printInputCarNames();
List<String> carNames = InputView.getCarNames();
checkCarNameLengths(carNames);
Cars carList = Cars.create(carNames, numberGenerator);

OutputView.printInputRoundNumber();
int roundNumber = InputView.getRoundNumber();

Racing racing = new Racing(carList);

OutputView.printResult();
playRace(racing, carList, roundNumber);

Cars winnerList = racing.findWinners();
OutputView.printWinners(winnerList.getCars());
}

public void playRace(Racing racing, Cars carList, int roundNumber) {
for (int i = 0; i < roundNumber; i++) {
racing.playRound();
OutputView.printProcess(carList.getCars());
}
}

public void checkCarNameLengths(List<String> names) {
if (names.stream().anyMatch(name -> name.length() > NAME_LENGTH_LIMIT)) {
throw new IllegalArgumentException("이름의 길이는 " + NAME_LENGTH_LIMIT + "자 이하여야 합니다.");
}
}

Choose a reason for hiding this comment

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

검증 위치에 대해 질문 남겨주신 것도 포함하여 여기서 답변 드릴게요!
하나의 유즈케이스에서 여러 검증이 필요하다 보니 각 검증 로직을 어디에 담아야 할지에 대한 의문은 당연하게 생길 것 같아요.

"유즈케이스" ex) 참여할 자동차의 이름을 입력한다.

위 예시로 고민해보면 다음과 같은 검증들이 이루어져야 해요. (적절한 예시를 위해 몇개의 요구사항을 추가 해봤어요)

  1. 자동차 이름은 빈 값일 수 없다.
  2. 10개 이상의 자동차는 참여 할 수 없다. (추가됨)
  3. 자동차 이름은 5글자 이상일 수 없다.
  4. 중복된 이름은 입력 될 수 없다. (추가됨)

"각 검증들이 어디에서 이루어져야 할까?"에 대한 답변으로는 해당 규칙이 어느 객체(계층)의 규칙일까? 를 고민 해보시면 좋아요!
각각 하나씩 뜯어볼게요.


자동차 이름은 빈 값일 수 없다.

자동차 이름에 대한 규칙은 자동차 객체의 요구사항이에요.
해당 이름으로 자동차를 생성할 때 검증을 한다면 자동차 객체는 어디서 인스턴스화(new Car()) 를 해도 해당 규칙을 보장합니다.

  • hint) 자동차 이름을 담당하는 객체를 추가로 만들수도 있어요! 원시값 포장

빈 값에 대한 검증은 입력단에 추가할 수도 있어요. fail-fast라는 용어가 있는데요. 빈 값에 대한 검증을 입력단에서 검증하고 처리한다면, 불필요하게 new Car() 로직을 실행 하지 않아도 됩니다!

10개 이상의 자동차는 참여 할 수 없다.

설명을 위해 추가한 요구사항이에요. 이런 규칙이 있다면 어디서 검증해야 할까요?
우선, 위에서 설명드렸던 것처럼 입력 단계에서 충분히 확인 할 수 있는 규칙이라면 fail-fast관점으로 입력단에서 검증할 수 있을 것 같아요.
그리고, 자동차 경주 게임에 참여하는 자동차들이 지켜야 하는 규칙이라면 Cars를 생성하는 단계에서 검증하여 해당 규칙을 보장할 수도 있겠네요!

자동차 이름은 5글자 이상일 수 없다

이 규칙 역시 자동차 이름의 규칙이에요. 위 설명과 유사합니다!

중복된 이름은 입력 될 수 없다. (추가됨)

해당 규칙도 Cars에서 규칙을 보장할 수 있고, 입력단에서도 검증할 수 있을 것 같아요.


설명이 길었지만, 정리하자면 해당 규칙이 어느 객체(계층)의 규칙일까?를 고민하고 그 객체에서 해당 규칙을 보장할 수 있도록 구성해야 하고, fail-fast 할 수 있다면 하는게 좋습니다.

"입력단에서 검증을 하는데, 객체에서도 검증해야 할까?" 라는 의문이 들 수도 있을 것 같아요.
입력단에서의 검증은 있으면 좋은거지, 객체의 규칙을 보장할 수 없기 때문에 신뢰할 순 없습니다.
자동차 이름의 길이에 대한 검증을 InputView.class에서만 이루어진다면, test 코드나 다른 view에서 new Car()를 실행 했을 때 자동차 이름의 길이를 보장하지 못하기 때문이에요.

천천히 읽어보시고, controller에서 이루어지고 있는 검증에 대해 다시 한번 생각해보시죠!

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

public class Car {

private static final int CRITICAL_NUMBER_TO_MOVE = 4;

private final String name;
private int distance;
private final NumberGenerator numberGenerator;

public Car(String name, NumberGenerator numberGenerator) {
this.name = name;
this.distance = 0;
this.numberGenerator = numberGenerator;
}

public void move() {
if (numberGenerator.generateNumber() >= CRITICAL_NUMBER_TO_MOVE) {
distance++;
}
}

public boolean hasSamePosition(int position) {
return distance == position;
}

public String getName() {
return name;
}

public int getDistance() {
return distance;
}

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

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

public class Cars {

private final List<Car> cars;

private Cars(List<Car> cars) {
this.cars = cars;
}

public static Cars create(List<String> carNames, NumberGenerator numberGenerator) {
List<Car> newCars = new ArrayList<>();
for (String carName : carNames) {
newCars.add(new Car(carName, numberGenerator));
}
return new Cars(newCars);
}

Choose a reason for hiding this comment

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

남겨주신 질문

현재 Cars 와 Car 두 객체를 생성할 때 전부 NumberGenerator를 매개변수로 받도록 하였는데 Cars를 생성할 때 RandomNumberGenerator 외에 다른 NumberGenerator를 넣을 일이 없었습니다. 이런 경우에는 Cars에 NumberGenerator 객체를 매개변수로 받을 필요가 없을까요? 혹은 추후 기능 확장을 대비해 남겨두는게 좋을까요?

전략 패턴을 도입한건 온전히 Car 때문이에요. 다른 전략을 선택하는 것 역시 Car 객체를 생성할 때만 존재합니다.
그렇기 때문에 Cars를 생성할 때는 굳이 필요한 매개변수는 아닙니다.

Cars에 대해 다시 고민해볼까요?
현재 create라는 팩토리 메서드에서 Car가 아닌 자동차 이름과 생성 전략을 매개변수로 받고 있습니다.
이게 과연 Cars라는 자동차 집단의 역할일까요?

각각의 이름과 생성전략을 가지고 있는, 이미 만들어진 List<Car>를 통해 생성하는 건 어떨까요?
Car의 생성은 책임지지 않고, Car의 집합인 Cars만의 책임을 유지해보는 겁니다!
단독으로 존재하는 Car에서는 담아낼 수 없는 책임(요구사항)들, 예를 들면 자동차 이름은 중복 될 수 없다, 자동차들을 전진 시킨다, 현재 자동차들의 최대 위치를 찾는다 등등이요!


public static Cars of(List<Car> cars) {
return new Cars(new ArrayList<>(cars));
}

Choose a reason for hiding this comment

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

새롭게 선언해서 외부와의 참조를 끊어냈네요👍
생성할 때 뿐만아니라, 현재 필드를 제공할 때(getter)도 방어적 복사를 사용할 수 있어요.


public void move() {
for (Car car : cars) {
car.move();
}
}

public int getMaxDistance() {
int maxDistance = 0;
for (Car car : cars) {
maxDistance = Math.max(maxDistance, car.getDistance());
}
return maxDistance;
}

public Cars findCarsHasSamePosition(int position) {
List<Car> carsHasSamePosition = cars.stream()
.filter(car -> car.hasSamePosition(position))
.collect(Collectors.toList());

return new Cars(carsHasSamePosition);
}

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

Choose a reason for hiding this comment

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


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

public interface NumberGenerator {

int generateNumber();

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

public class Racing {

private final Cars carList;

Choose a reason for hiding this comment

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

사소하지만, 변수이름에 Collection 구현체 담지 마세요!
나중에 Set으로 수정하면 이름도 같이 바꿔야 해서요...!

Suggested change
private final Cars carList;
private final Cars cars;


public Racing(Cars carList) {
this.carList = carList;
}

public void playRound() {
carList.move();
}

public Cars findWinners() {
return carList.findCarsHasSamePosition(carList.getMaxDistance());
}

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

import java.util.Random;

public class RandomNumberGenerator implements NumberGenerator {

@Override
public int generateNumber() {
return new Random().nextInt(10);

Choose a reason for hiding this comment

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

new Random()을 매번 선언하면 불필요한 자원 낭비가 될 수 있어요.
상수로 선언하여 한번만 생성해서 성능을 좀 더 높일 수 있답니다!

Scanner를 선언 하신 것 처럼요!

}

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

import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class InputView {

private static final Scanner scanner = new Scanner(System.in);

public static List<String> getCarNames() {
return Arrays.asList(scanner.nextLine().split(","));
}

public static int getRoundNumber() {
return Integer.parseInt(scanner.nextLine());
}

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

import domain.Car;
import java.util.ArrayList;
import java.util.List;

public class OutputView {

public static void printInputCarNames() {
System.out.println("경주할 자동차 이름을 입력하세요(이름은 쉼표(,)를 기준으로 구분).");
}

public static void printInputRoundNumber() {
System.out.println("시도할 회수는 몇회인가요?");
}

public static void printResult() {
System.out.println("실행 결과");
}

public static void printProcess(List<Car> cars) {
for (Car car : cars) {
System.out.println(formatCarInfo(car));
}
System.out.println();
}

public static String formatCarInfo(Car car) {
StringBuilder formatted;
formatted = new StringBuilder(car.getName() + " : ");
for (int i = 0; i < car.getDistance(); i++) {
formatted.append("-");
}
return formatted.toString();

Choose a reason for hiding this comment

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

String의 함수를 잘 활용하면 이렇게도 줄여볼 수 있어요

Suggested change
StringBuilder formatted;
formatted = new StringBuilder(car.getName() + " : ");
for (int i = 0; i < car.getDistance(); i++) {
formatted.append("-");
}
return formatted.toString();
return car.getName() + " : " + "-".repeat(car.getDistance());

}

public static void printWinners(List<Car> winners) {
List<String> winnerNames = new ArrayList<>();
for (Car winner : winners) {
winnerNames.add(winner.getName());
}
System.out.println(formatWinnerNames(winnerNames) + "가 최종 우승했습니다.");
}

public static String formatWinnerNames(List<String> cars) {
return cars.toString().replace("[", "").replace("]", "");
}

Choose a reason for hiding this comment

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

이렇게도 줄여 볼 수 있어요!
stream을 잘 활용하면 굉장히 강력해 보이지 않나요?

Suggested change
public static void printWinners(List<Car> winners) {
List<String> winnerNames = new ArrayList<>();
for (Car winner : winners) {
winnerNames.add(winner.getName());
}
System.out.println(formatWinnerNames(winnerNames) + "가 최종 우승했습니다.");
}
public static String formatWinnerNames(List<String> cars) {
return cars.toString().replace("[", "").replace("]", "");
}
public static void printWinners(List<Car> winners) {
String winnerNames = winners.stream()
.map(Car::getName)
.collect(Collectors.joining(", "));
System.out.println(winnerNames + "가 최종 우승했습니다.");
}


}
31 changes: 22 additions & 9 deletions src/test/java/CarTest.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
import domain.Car;
import org.junit.jupiter.api.Test;

Choose a reason for hiding this comment

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

import 다시 돌려주세요...ㅠ


import static org.assertj.core.api.Assertions.*;

public class CarTest {

private static final int MOVE_FORWARD = 4;
private static final int NOT_MOVE = 3;

@Test
void testCarName() {
Car car = new Car("KIA");
assertThat(car.getName()).isEqualTo("KIA");
Car car = new Car("TestCar", new MovableNumberGenerator());
assertThat(car.getName()).isEqualTo("TestCar");
}

@Test
void testCarMove() {
Car car = new Car("TestCar");
car.move(MOVE_FORWARD);
Car car = new Car("TestCar", new MovableNumberGenerator());
car.move();
assertThat(car.getDistance()).isEqualTo(1);
}

@Test
void testCarNotMove() {
Car car = new Car("TestCar");
car.move(NOT_MOVE - 1);
Car car = new Car("TestCar", new NotMovableNumberGenerator());
car.move();
assertThat(car.getDistance()).isEqualTo(0);
}

@Test
void testCarHasSamePosition() {
Car car = new Car("TestCar", new MovableNumberGenerator());
car.move();
assertThat(car.hasSamePosition(1)).isEqualTo(true);
}

@Test
void testCarIsNotInPosition() {
Car car = new Car("TestCar", new MovableNumberGenerator());
car.move();
assertThat(car.hasSamePosition(0)).isEqualTo(false);
}

}
Loading