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

[차재언] Step2(RacingGame) 피드백 반영. #2204

Merged
merged 35 commits into from May 29, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2e22008
refactor: Pattern 내부에서 반복되는 코드 개선
Miot2J May 10, 2021
63d1db7
refactor: 문자열 끼리 + 연산을 StringBuilder 를 통해 속도 개선, 객체의 책임 명확화
Miot2J May 10, 2021
42f061e
refactor: TestCode 수정 및 추가 완료
Miot2J May 10, 2021
70a20da
refactor: MVC 패턴에 맞게 패키지 및 클래스 변경
Miot2J May 10, 2021
dd1a3f2
refactor: RacingGame 에 List<Car> 객체 선언, Test 구조 개선
Miot2J May 12, 2021
9ae509e
refactor: RacingGame 생성자로 List<Car> 객체 할당, 반환타입에 방어적 복사기법 적용
Miot2J May 15, 2021
6eb0e4b
refactor: 출력시 stringBuilder를 통해 한번에 문장을 완성후 한번만 sys 출력하도록 변경
Miot2J May 15, 2021
3b2b556
refactor: @MethodSource 사용해 MathSymbol검증, racing 패키지의 출력 수정
Miot2J May 15, 2021
99d47f2
refactor: MathSymbol에 abstract 메소드를 통해 각각 다른 계산결과 오버라이딩
Miot2J May 17, 2021
0f2fec4
refactor: Car 객체가 각기 다른 움직이는 조건을 가질 수 있게 전략패턴을 적용,RacingGame의 메소드들의 리…
Miot2J May 18, 2021
0f31cd8
refactor: CarTest#isWinner에 DisplayName 추가
Miot2J May 19, 2021
4e26208
refactor: Car 객체는 자동차가 움직일 조건을 알 필요가 없기에 조건을 가지고 있는 책임 제거
Miot2J May 23, 2021
e958b65
refactor: Car 객체에 MovedLog를 추가해 이동 기록을 관리하도록 함
Miot2J May 23, 2021
65a85e8
refactor: RacingGame 메소드의 불필요한 파라미터 제거
Miot2J May 23, 2021
42f7540
refactor: String.join을 사용하여 불필요한 상수, builder 제거
Miot2J May 23, 2021
e458649
refactor: StringBuilder.append() 를 메서드 체이닝형식으로 재 구성
Miot2J May 23, 2021
aa26c82
refactor: 불필요한 TestCode 제거 및 변경
Miot2J May 23, 2021
4266ffc
refactor: Output#printWinMessage() 메소드에 스트림 적용
Miot2J May 24, 2021
bbcc308
refactor: Car#move() 에 반환타입 제거
Miot2J May 24, 2021
522fdc5
refactor: 변경된 변수명 적용
Miot2J May 24, 2021
03a02f5
refactor: MovedLog에 출발지점이 다른 생성자 추가
Miot2J May 24, 2021
9087550
refactor: method 호출 순서에 따라 재배치
Miot2J May 24, 2021
d95aceb
refactor: if의 조건이 boolean 이고, 조건의 결과를 그대로 반환하는 코드의 조건문 제거
Miot2J May 24, 2021
df15861
refactor: boolean 타입의 변수명은 긍정형으로 짓기!
Miot2J May 24, 2021
7bc194d
refactor: 가독성을 위해 static import를 제거하고 Output을 명시
Miot2J May 24, 2021
903c176
refactor: Car가 movedLog의 finalDistance를 알 필요가 없어 책임 분리
Miot2J May 24, 2021
041c4fb
refactor: 종속함수의 함수 호출순서에 맞게 변경
Miot2J May 24, 2021
41892ff
refactor: 네이밍 변경
Miot2J May 24, 2021
6dabc61
refactor: 테스트 코드에 대한 피드백 반영
Miot2J May 24, 2021
c589fb5
refactor: MovedLog -> CarDistanceLog로 변경
Miot2J May 24, 2021
80a2215
refactor: ReformatCode 기능 사용
Miot2J May 24, 2021
20af7d5
refactor: Car 생성자 변경,
Miot2J May 27, 2021
4ed7d98
refactor: get 사용해서 할당하는 코드 제거
Miot2J May 27, 2021
30901e1
refactor: DistanceLog 피드백 반영
Miot2J May 27, 2021
a699d5a
refactor: RacingGame의 cars 접근 제어자 변경,메서드 오타 수정
Miot2J May 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 14 additions & 9 deletions src/main/java/calculator/Calculator.java
Expand Up @@ -2,6 +2,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static calculator.ExceptionMessage.*;
Expand All @@ -16,19 +17,23 @@ public class Calculator {
private static final String IS_NOT_MATH_EXPRESSION = "[^0-9+\\-*/]";
private static final String MAKE_EMPTY = "";
private static final int HAVE_NOT_APPENDED_NUMBER = 1;
private static final int FIRST_NUMBER_INDEX = 0;

Pattern notNumberPattern = Pattern.compile(NOT_NUMBER_PATTERN);
Pattern theEndIsNotNumberPattern = Pattern.compile(THE_END_IS_NOT_NUMBER);
Pattern isNotMathExpressionPattern = Pattern.compile(IS_NOT_MATH_EXPRESSION);

Choose a reason for hiding this comment

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

패턴을 미리 만들어주셨네요! 👍 👍 👍

Copy link

Choose a reason for hiding this comment

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

미리 만들어주신 세 패턴은 쉽게 변하지 않을거란 생각이 들어요. 그렇다면 상수로 변경해보면 어떨까요? :)
추가적으로, Calculator 내에서만 사용되고 있네요! :)

Copy link
Author

Choose a reason for hiding this comment

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

상수 선언을 할때, 원시형만 이용해서 선언하는 고정관념이 있었네요 😀


public void printResult() {
Calculator calculator = new Calculator();
outputStartMessage();
resultOutput(calculator.makeResult(makeSlicedMathExpression()));
resultOutput(makeResult(makeSlicedMathExpression()));
}

public double calculate(double firstNumber, String operator, double secondNumber) {

Choose a reason for hiding this comment

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

calculate()Calculator에서만 사용되고 있어요. public으로 설정하신 이유가 있을까요? :)

return findValidatedSymbol(operator).operate(firstNumber, secondNumber);
}

private double makeResult(List<String> mathExpressions) {
double result = Double.parseDouble(mathExpressions.get(0));
double result = Double.parseDouble(mathExpressions.get(FIRST_NUMBER_INDEX));
int mathExpressionSize = mathExpressions.size();

for (int i = 1; i < mathExpressionSize; i += 2) {

Choose a reason for hiding this comment

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

반복문에서 2라는 숫자에 어떤 의미가 있을까요? 의미를 드러낼 수 있도록 해봐요 :)

Expand All @@ -54,13 +59,15 @@ private void validate(String mathExpression) {
}

private void isTheEndNotNumber(String mathExpression) {

Choose a reason for hiding this comment

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

boolean을 반환하는 기능이 아닌, 검증을 하고 예외를 발생시키는 기능을 하고 있어요. 조금 더 검증에 알맞는 이름을 지어주면 어떨까요? 다른 부분에도 같이 적용해보면 좋겠죠? 😁

if (Pattern.matches(THE_END_IS_NOT_NUMBER, mathExpression)) {
Matcher matcher = theEndIsNotNumberPattern.matcher(mathExpression);

Choose a reason for hiding this comment

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

matcher 라는 이름은 의도가 다소 약하게 드러나는 것 같아요. matcher.matches()boolean 변수로 만들어서 의미를 부여하고 사용해보면 어떨까요? :)

if (matcher.matches()) {
throw new IllegalArgumentException(THE_END_IS_NOT_NUMBER_MESSAGE);
}
}

private void isNotMathExpression(String mathExpression) {
if (Pattern.matches(IS_NOT_MATH_EXPRESSION, mathExpression)) {
Matcher matcher = isNotMathExpressionPattern.matcher(mathExpression);
if (matcher.matches()) {
throw new IllegalArgumentException(IS_NOT_MATH_EXPRESSION_MESSAGE);
}
}
Expand Down Expand Up @@ -95,10 +102,8 @@ private List<String> convertSplitExpressionArrayToList(String[] splitMathExpress
}

private boolean isNotNumberPattern(String mathSymbol) {
if (Pattern.matches(NOT_NUMBER_PATTERN, mathSymbol)) {
return true;
}
return false;
Matcher matcher = notNumberPattern.matcher(mathSymbol);
return matcher.matches();
}

private boolean haveIntegerExpression(String integerOfMathExpression) {
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/calculator/MathSymbol.java
Expand Up @@ -22,9 +22,9 @@ public String getMathSymbol() {

public static MathSymbol findValidatedSymbol(String operator) {
return Arrays.stream(MathSymbol.values())
.filter(v -> v.getMathSymbol().equals(operator))
.filter(mathSymbol -> mathSymbol.getMathSymbol().equals(operator))
Copy link

Choose a reason for hiding this comment

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

mathSymbol.getMathSymbol() 대신 바로 mathSymbol 필드에 접근해보면 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

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

ㅎㅎ 이런 실수를

.findAny()
.orElseThrow(() -> new IllegalArgumentException(String.format("잘못된 연산자 입니다.")));
.orElseThrow(() -> new IllegalArgumentException("잘못된 연산자 입니다."));
}

public double operate(double firstNumber, double secondNumber) {

Choose a reason for hiding this comment

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

operate() 내부에서 비교를 수행할 때, getXXX() 를 통해 상태를 다시 꺼내어(?) 사용하고 있어요. 이 부분은 바로 상태에 접근해서 사용해보면 어떨까요? 그렇게 하면 어떤 효과가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

음.. 메소드 호출을 한 번 줄일 수 있어서
자원? 의 낭비가 줄어들겠네요

Expand Down
8 changes: 0 additions & 8 deletions src/main/java/racing/Main.java

This file was deleted.

29 changes: 29 additions & 0 deletions src/main/java/racing/RacingController.java
@@ -0,0 +1,29 @@
package racing;

import racing.domain.Car;

Choose a reason for hiding this comment

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

사용되지 않는 import 문이네요!

Copy link
Author

Choose a reason for hiding this comment

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

매번 실수해서 자동으로 제거하는 설정을 적용했습니다 ㅎㅎ

import racing.domain.RacingGame;

import java.util.List;

import static racing.domain.RacingGame.SEPARATOR;
import static racing.view.Input.makeCarNames;
import static racing.view.Input.makeGameRepeatCount;
import static racing.view.Output.*;
import static racing.view.Output.printWinMessage;

Choose a reason for hiding this comment

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

import static을 사용하면 코드 작성은 편해질 수 있으나, 메서드가 어디에서 작성되어 있는지 파악하기가 어려울 수도 있어요. 적절히 사용하면 좋을 것 같네요! :)


public class RacingController {
public static void main(String[] args) {
RacingGame racingGame = new RacingGame();

printStartMessage();
String carNames = makeCarNames();

Choose a reason for hiding this comment

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

carNames는 선언된 곳으로부터 꽤 멀리 떨어진 곳에서 사용되고 있어요. 선언 부분과 사용 부분을 가깝게 해주면 어떨까요? 그러면 어떤 효과가 있을까요?

printInputCountMessage();
int count = makeGameRepeatCount();

Choose a reason for hiding this comment

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

입력시 메시지 출력입력은 모두 View에서 이루어지고 있어요. 그렇다면 이러한 것들을 View 에 모아놓으면 어떨까요? 그러면 어떤 효과가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

컨트롤러에서 Output, Input에 총두번 접근하는 대신
한번만 접근해도 된다??

대신 Output과 Input의 메서드가 많아지면 한번에 관리하기는 어려워진다?

printResultMessage();

Choose a reason for hiding this comment

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

static import를 하면 편리하지만, 현재 클래스의 멤버인걸로 오해할 수 있으니 가능하면 어떤 클래스에 속한 메서드인지 명시해주는게 좋을 것 같다는 생각이 드네요 :)

Copy link
Author

Choose a reason for hiding this comment

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

output을 생략하는 대신 print라는 동사를 공통적으로 붙였는데
코드가 아주 많아지면 output을 명시하는게 좀 더 가독성이 좋을 것 같기도 하네요👍

String[] carNameArray = carNames.split(SEPARATOR);
List<Car> carList = racingGame.makeCars(carNameArray);
carList = racingGame.repeatMoveCars(count, carList);
printNowDistance(carList);
printWinMessage(racingGame.findWinner(carList));
}
}
70 changes: 0 additions & 70 deletions src/main/java/racing/RacingGame.java

This file was deleted.

@@ -1,6 +1,8 @@
package racing;
package racing.domain;

public class Car {
public static final int MOVE_CHANGE_CONDITION = 4;
public static final int VALIDATED_NAME_LENGTH = 5;

Choose a reason for hiding this comment

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

두 상수 모두 Car 내부에서만 사용되고 있네요!

private String name;
private int moveCount;

Expand All @@ -10,15 +12,13 @@ public Car(String name) {
}

public void move(int randomNumber) {
if (randomNumber >= 4) {
if (randomNumber >= MOVE_CHANGE_CONDITION) {
Copy link

Choose a reason for hiding this comment

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

Car가 다양한 방법으로 움직일 수 있도록 해보면 어떨까요? :)

this.moveCount++;
}
}

private void validateLength(String name) {
if (name.length() > 5) {
throw new IllegalArgumentException("이름은 5자 이내로 입력하세요.");
}
public boolean isWinner(int winnerCount) {
return moveCount == winnerCount;
}

public String getName() {
Expand All @@ -29,4 +29,9 @@ public int getMoveCount() {
return moveCount;
}

private void validateLength(String name) {

Choose a reason for hiding this comment

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

생성자에서 사용되고 있네요. 연관성이 높을 수록 근처에 배치하는게 가독성에 더 좋지 않을까요? :)

Copy link
Author

@Miot2J Miot2J May 12, 2021

Choose a reason for hiding this comment

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

완료!

if (name.length() > VALIDATED_NAME_LENGTH) {
throw new IllegalArgumentException("이름은 5자 이내로 입력하세요.");
}
}
}
54 changes: 54 additions & 0 deletions src/main/java/racing/domain/RacingGame.java
@@ -0,0 +1,54 @@
package racing.domain;

import java.util.ArrayList;
import java.util.List;

import static racing.utils.RandomNumber.makeOneRandomNumber;

public class RacingGame {

Choose a reason for hiding this comment

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

RacingGame의 기능들을 살펴보면, List<Car>를 관리하고 있다는 것을 알 수 있어요. 그렇다면 List<Car>를 상태값으로 가져보면 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

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

List를 상태로 가졌더니 메소드 내부에서 List를 중복해서 선언하던 코드들이사라지고
리턴값도 필요없게되었으며 파라미터도 필요가 없게 되었네요
코드들이 훨씬 간결해 진거 같습니다.

또한 RacingGame 객체를 선언하고 관리하는 컨트롤러에서도 리스트를 갱신하는 일이 사라졌네요

public static String SEPARATOR = ",";
Copy link

Choose a reason for hiding this comment

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

상수로 선언할 때는 final 예약어를 사용해주세요 :)
Google Java Style Guide5.2.4 Constant names 부분을 참고하면 도움이 될 것 같아요!


public List<Car> makeCars(String[] carNameArray) {
List<Car> cars = new ArrayList<>();

for (String carName : carNameArray) {
cars.add(new Car(carName));
}
return cars;
}

public List<Car> repeatMoveCars(int count, List<Car> carList) {
for (int i = 0; i < count; i++) {
carList = moveCars(carList);
}
return carList;

Choose a reason for hiding this comment

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

자동차의 상태는 Car 가 관리하고 있어요. List<Car>를 반환할 필요가 있을까요? :)

}

public List<String> findWinner(List<Car> carList) {
List<String> winnerList = new ArrayList<>();
int winnerCondition = findWinnerCondition(carList);
for (Car car : carList) {
if (car.isWinner(winnerCondition)) {
winnerList.add(car.getName());
}
}
return winnerList;
}

private List<Car> moveCars(List<Car> carList) {

Choose a reason for hiding this comment

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

moveCars()repeatMoveCars()에서 호출되고 있어요. 배치를 가깝게 해보면 어떨까요? 그러면 어떤 효과가 있을까요? 다른 비슷한 부분들에도 적용해보면 좋을 것 같네요! :)

for (int i = 0; i < carList.size(); i++) {
carList.get(i).move(makeOneRandomNumber());
}
return carList;
}

private int findWinnerCondition(List<Car> carList) {
int winnerCondition = 0;
for (Car car : carList) {
if (car.getMoveCount() >= winnerCondition) {
winnerCondition = car.getMoveCount();
}

Choose a reason for hiding this comment

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

Math 클래스의 내장함수인 max()를 사용해보면 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

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

오 새로운 접근 방법이네요
좋습니다.👍👍

}
return winnerCondition;
}
}
2 changes: 1 addition & 1 deletion src/main/java/racing/view/Input.java
Expand Up @@ -12,4 +12,4 @@ public static String makeCarNames() {
public static int makeGameRepeatCount() {
return scanner.nextInt();
}
}
}
21 changes: 15 additions & 6 deletions src/main/java/racing/view/Output.java
@@ -1,6 +1,6 @@
package racing.view;

import racing.Car;
import racing.domain.Car;

import java.util.List;

Expand All @@ -12,6 +12,7 @@ public class Output {
private static final String LOAD = "-";
private static final String WINNER_SEPARATOR = ", ";
private static final String DISTANCE_SEPARATOR = " : ";
private static final int BUILDER_INIT = 0;

Choose a reason for hiding this comment

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

BUILDER_INIT 이라는 상수만 봤을 때, 어떤 역할을 하는지, 어떤 의미를 갖는지 알 수 있을까요? 😥


public static void printStartMessage() {
System.out.println(START_MESSAGE);
Expand All @@ -28,26 +29,34 @@ public static void printResultMessage() {
public static void printWinMessage(List<String> winnerList) {
System.out.print("\n" + WIN_MESSAGE);

int memberIndexOfRequiringSeparator = winnerList.size() -2;
int memberIndexOfRequiringSeparator = winnerList.size() - 2;

Choose a reason for hiding this comment

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

2라는 숫자가 갖는 의미를 해석하기가 쉽지 않은 것 같아요. 의미를 드러내도록 해보면 어떨까요?

Copy link
Author

Choose a reason for hiding this comment

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

변수명을 lastMemberIndexOfRequiringSeparator 로 변경하고 뒤에 숫자는 변경 안했습니다.
변수명반 보고 충분히 유추 가능하다고 생각하고
오히려 2를 다른 상수명으로 변경하였을때 가독성이 더 떨어질 것 같습니다.
ex ) winnerList.size() - doNotNeedSeparatorIndex

int memberIndexOfNotRequiringSeparator = memberIndexOfRequiringSeparator + 1;
StringBuilder winMessageStringBuilder = new StringBuilder();

Choose a reason for hiding this comment

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

winMessageStringBuilder라는 변수명도 좋지만, 이미 메서드 명에서 우승자 메시지를 출력한다 라는 것을 알 수 있기 때문에, 문자열을 만든다는 점에서 간단하게 builder 와 같은 변수명으로 사용하는 것도 괜찮아 보이네요 :)

Copy link
Author

Choose a reason for hiding this comment

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

그런가요..변경 후 고민해 보겠습니다.


for (int i = 0; i <= memberIndexOfRequiringSeparator; i++) {

Choose a reason for hiding this comment

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

반복문을 통해 각각의 자동차에 대한 출력을 수행하고 있어요. 여기서, 각각의 자동차에 대한 출력문 처리 로직을 각각의 Car를 인자로 받아서 수행하도록 메서드를 분리해보면 어떨까요? 그러면 어떤 효과가 있을까요?

Copy link
Author

Choose a reason for hiding this comment

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

이 부분은 잘못 이해 하신듯 합니다.
각각의 자동차에 대한 출력을 하는것 과 Car를 인자로 가져오는것이 아닌
이미 다른 클래스에서 car를 인자로 받아서
완성된 위너리스트를 형식에 맞게 변환하여 출력하도록 하는 메소드입니다.

System.out.print(winnerList.get(i) + WINNER_SEPARATOR);
winMessageStringBuilder.append(winnerList.get(i));
winMessageStringBuilder.append(WINNER_SEPARATOR);
System.out.print(winMessageStringBuilder);
winMessageStringBuilder.setLength(BUILDER_INIT);
}
System.out.println(winnerList.get(memberIndexOfNotRequiringSeparator));
}

public static void printNowDistance(List<Car> carList) {
System.out.println();
StringBuilder distanceStringBuilder = new StringBuilder();
for (int i = 0; i < carList.size(); i++) {
System.out.print(carList.get(i).getName() + DISTANCE_SEPARATOR);
distanceStringBuilder.append(carList.get(i).getName());
distanceStringBuilder.append(DISTANCE_SEPARATOR);
System.out.print(distanceStringBuilder);

Choose a reason for hiding this comment

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

출력 형식에 맞게 문자열 데이터의 가공을 완료한 뒤, 한번에 출력해보면 어떨까요? :)

printLoadConstant(carList.get(i).getMoveCount());
System.out.println();

Choose a reason for hiding this comment

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

StringBuilder를 통해 출력문을 만든 뒤, 출력을 진행하고 있어요. 하지만 그 이후에, printLoadConstant() 메서드를 호출할 때마다 System.out.print()를 호출하게 돼요. 그렇다면, moveCount가 엄청나게 커진다면 System.out.print()를 엄청나게 많이 호출해야 할거고, 리소스를 상당히 많이 잡아먹게 될 수도 있을 것 같아요. 출력문을 완성한 뒤, 한번에 출력해보는 건 어떨까요? :)

distanceStringBuilder.setLength(BUILDER_INIT);
}
}

private static void printLoadConstant(int gameRepeatCount) {
for (int j = 0; j < gameRepeatCount; j++) {
private static void printLoadConstant(int moveCount) {
for (int j = 0; j < moveCount; j++) {
System.out.print(LOAD);
}
}
Expand Down