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

[숫자 야구 게임] 강철원 미션 제출합니다. #4

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0afb654
init
Ryan-Dia Nov 23, 2022
435457e
feat: 사용자에게 서로다른 숫자를 입력받는 기능 추가
Ryan-Dia Nov 29, 2022
a732183
refactor(Error): 에러 처리 방식 변경
Ryan-Dia Nov 29, 2022
3d602b3
feat : 올바른 숫자를 입력시 알맞은 힌트 제공하는 기능 추가
Ryan-Dia Nov 29, 2022
c890b51
feat : 3스트라이크가 아닐시 다시 숫자입력 단계로 이동
Ryan-Dia Nov 29, 2022
163f68f
refacotr(README) : 기능 목록 수정
Ryan-Dia Nov 29, 2022
39d3a88
feat : 3스트라이크를 했다면 게임 재시작 여부를 묻는다
Ryan-Dia Nov 29, 2022
665fe26
feat : 재시작 또는 게임을 종료를 할 수 있는 기능 추가
Ryan-Dia Nov 29, 2022
1549695
refactor(BaseballController): 오류처리방식 return대신 throw로 변경
Ryan-Dia Nov 29, 2022
6243011
refactor(App): 앱 구동 세팅
Ryan-Dia Nov 29, 2022
9632300
docs(gitignore) :리스트에 .template.txt 추가
Ryan-Dia Nov 29, 2022
af584c1
refactor(all) : 문자열 상수화
Ryan-Dia Nov 29, 2022
4882343
refactor: 숫자 상수화
Ryan-Dia Nov 29, 2022
4a52e7a
docs(README) 디렉토리 구조 추가
Ryan-Dia Nov 29, 2022
32210b2
refactor(Validator) input 값 확인 메서드 추가
Ryan-Dia Nov 29, 2022
e8bba78
test(Validator): validator 테스트 케이스 추가
Ryan-Dia Nov 29, 2022
d43c90e
refactor(Constants): 객체에 Object.freeze 추가
Ryan-Dia Nov 30, 2022
c1ea965
refactor: 테스트하며 사용했던 console.log 제거
Ryan-Dia Nov 30, 2022
d9a7e8d
refactor(Validator) : Validator class -> object로 변경
Ryan-Dia Dec 1, 2022
9a116b3
refactor(Controller): controller 구조 변경
Ryan-Dia Dec 4, 2022
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
.template.txt
Comment on lines 1 to +2
Copy link
Member

Choose a reason for hiding this comment

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

EOL 빼먹으셨네요..!

Choose a reason for hiding this comment

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

prettierEOL 설정이 있으니 참고해보셔도 좋을거 같아요!!

Copy link
Member Author

Choose a reason for hiding this comment

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

@turtle601 EOL 설정은 이전부터 이미 되어있습니다.
.gitignore에는 적용이 안되는 것 같은데 이유를 아시나요 ?
.prettierignore 파일을 추가하여 ignore 설정 한 것은 없습니다.
운영체제가 다른 사람과 협업하는 게 아닌 저 혼자 mac os에서 하기에 lf로 설정해 두었습니다.
"endOfLine": "lf",

Choose a reason for hiding this comment

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

@Ryan-Dia
음... 사실 .gitignore에 대한 내용은 잘 모르겠습니다 ㅜㅜ

저 같은 경우에는 npm install -D prettier 로 하고 prettierrc 파일을 따로 설정,
대신 package.jsonprettierrc 파일을 upstream에 올리지 않는 방식을 사용하고 있습니다

(추가적으로 endOfLine: auto로 두고 작업하고 있습니다.)

이렇게 할 경우 다른 레포에 적용도 안되서 다른 분들고 협업에도 지장이 없을 거 같다는 제 추측입니다!!

Choose a reason for hiding this comment

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

제가 스터디 PR인줄도 모르고 코드 리뷰를 남겼네요 ㅜㅜㅜ 죄송합니다 🙏🙏

64 changes: 64 additions & 0 deletions __tests__/Validator/validator.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const Validator = require('../../src/Validator/index');

let validator;
beforeEach(() => {
validator = new Validator();
});
describe('Validator 테스트', () => {
describe('checkGameNumbers ', () => {
it('정상적으로 서로 다른 3자리 숫자를 입력하였을 경우 ', () => {
['123', '821', '781', '531'].forEach((element) => {
expect(validator.checkGameNumbers(element)).toBeUndefined();
});
});
it('[Error] 중복되는 숫자를 입력할 경우 에러 처리', () => {
['122', '633', '787', '911'].forEach((element) => {
expect(() => validator.checkGameNumbers(element)).toThrow();
});
});

it('[Error] 0을 포함할 경우 에러 처리', () => {
['012', '103', '340'].forEach((element) => {
expect(() => validator.checkGameNumbers(element)).toThrow();
});
});

it('[Error] 3자리 숫자가 아닐 경우 에러 처리 ', () => {
['12', '1', '', '1234', '2390432332849023849032', '-233'].forEach((element) => {
expect(() => validator.checkGameNumbers(element)).toThrow();
});
});

it('[Error] 숫자이외의 문자가 포함되어있을 경우 에러 처리', () => {
['안타니?', 'SSG우승축하', '', '34오', '+234', '오72'].forEach((element) => {
expect(() => validator.checkGameNumbers(element)).toThrow();
});
});
});

describe('checkGameCommand', () => {
it('정상적인 숫자 1 또는 2를 입력하였을 경우 통과', () => {
['1', '2'].forEach((element) => {
expect(validator.checkGameCommand(element)).toBeUndefined();
});
});

it('[Error] 숫자이외의 문자가 포함되었을 경우 에러 처리', () => {
['이', '일', '', '오1', '+2', '-1'].forEach((element) => {
expect(() => validator.checkGameCommand(element)).toThrow();
});
});

it('[Error] 1자리 숫자가 아닐 경우 에러 처리', () => {
['11', '12', '21', '22', '32', '0', '', '-1', '-2'].forEach((element) => {
expect(() => validator.checkGameCommand(element)).toThrow();
});
});

it('[Error] 숫자 1 또는 2가 아닌 경우 에러 처리', () => {
['3', '0', '9', '42', '32', '0', '', '-1', '-2'].forEach((element) => {
expect(() => validator.checkGameCommand(element)).toThrow();
});
});
});
});
48 changes: 48 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
## 📗 디렉토리 구조

📦src
┣ 📂Constants
┃ ┣ 📜Message.js
┃ ┗ 📜System.js
┣ 📂Controller
┃ ┗ 📜BaseballController.js
┣ 📂Error
┃ ┣ 📜DefaultError.js
┃ ┣ 📜ReadError.js
┃ ┗ 📜ValidationError.js
┣ 📂Model
┃ ┗ 📜BaseballModel.js
┣ 📂Validator
┃ ┣ 📂util
┃ ┃ ┗ 📜util.js
┃ ┣ 📜GameCommand.js
┃ ┣ 📜GameNumber.js
┃ ┗ 📜index.js
┣ 📂View
┃ ┣ 📜InputView.js
┃ ┣ 📜OutputView.js
┃ ┗ 📜index.js
┣ 📜App.js
┗ 📜RandomNumberGenerator.js

## 📕 기능 목록

1. 숫자 야구 게임 시작 멘트 출력
2. 컴퓨터에서 1~9사이의 서로다른 수 3개를 뽑은뒤 저장해 놓는다.
3. 사용자에게 숫자를 입력 받는다.
- (조건) 서로 다른 3자리 숫자를 받는다.
- (예외) 서로 다른 3자리 숫자가 아니라면 throw문을 사용해 예외 발생후 앱 종료
4. 올바른 값을 입력하면 아까 저장한 컴퓨터 숫자와 사용자 숫자를 대조해본다.
5. 컴퓨터의 숫자와 사용자의 숫자가 일치하는 정도에 따라 힌트를 출력한다 (스트라이크를 나중에 출력)
- 숫자가 하나도 일치하지 않을 때 : 낫싱
- 위치가 다르지만 숫자 1개가 일치하는 경우 : 1볼
- 위치가 다르지만 숫자 2개가 일치하는 경우 : 2볼
- 위치가 다르지만 숫자 3개가 일치하는 경우 : 3볼
- 위치가 같은 숫자 1개와 다른 1개가 일치하는 경우 : 1볼 1스트라이크
- 위치가 같은 숫자 1개와 다른 2개가 일치하는 경우 : 2볼 1스트라이크
- 위치가 같은 숫자가 2개일 경우 : 2스트라이크
- 위치가 같은 숫자가 3개일 경우 : 3스트라이크
6. 3스트라이크가 아닐시 다시 기능 3번으로 되돌아간다.
7. 3스트라이크일시 축하 멘트를 출력뒤 게임 재시작여부를 묻는다.
8. 만약 재시작을 사용자가 선택한다면 기능 2로 되돌아간다.
9. 만약 게임 종료를 사용자가 선택한다면 그 즉시 앱을 종료시킨다.
23 changes: 22 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
const BaseballController = require('./Controller/baseballController');
const BaseballModel = require('./Model/BaseballModel');
const View = require('./view');

class App {
play() {}
#view;

#model;

#baseballController;
Comment on lines +6 to +10
Copy link
Member

Choose a reason for hiding this comment

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

MVC 디자인패턴에서는 컨트롤러만이 모델과 뷰에 모두 접근 가능한데, 컨트롤러만 app에서 선언해주고 나머지는 컨트롤러에서 선언해주는게 더 좋지 않았을까요?


constructor() {
this.#view = new View();
this.#model = new BaseballModel();
this.#baseballController = new BaseballController(this.#view, this.#model);
}
play() {
Copy link
Contributor

Choose a reason for hiding this comment

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

한 칸 띄워주는 사소한 컨벤션~! 사소하지만 그래도 지켜줍시다~!

this.#baseballController.start();
}
}

const app = new App();

app.play();

module.exports = App;
28 changes: 28 additions & 0 deletions src/Constants/Message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const ERROR_MESSAGE = Object.freeze({
error: '[ERROR]',
length_one: '1자릿수가 아닙니다.',
length_three: '3자릿수가 아닙니다.',
only_number: '숫자이외의 다른 문자가 존재합니다.',
not_zero: '0을 포함시켜면 안됩니다. ',
not_duplication: '서로 다른 숫자를 입력하시옵소서',
one_or_two: '숫자 1 또는 2만 입력이 가능합니다.',
});

const INPUT_MESSAGE = Object.freeze({
new_line: '\n',
game_number: '숫자를 입력해주세요',
game_command: '게임을 새로 시작하려면 1, 종료하려면 2를 입력하세요',
});

const OUTPUT_MESSAGE = Object.freeze({
start: '숫자 야구 게임을 시작합니다.',
success: '3개의 숫자를 모두 맞히셨습니다! 게임 종료',
end: '잘못된 값을 입력하여 게임이 종료됩니다.',
error: (name, message, cause) => `${name} : ${message}\n[CAUSE] : ${cause}`,
noting: '낫싱',
ball_and_strike: (ball, strike) => `${ball}볼 ${strike}스트라이크`,
strike: (strike) => `${strike}스트라이크`,
ball: (ball) => `${ball}볼`,
});

module.exports = { ERROR_MESSAGE, INPUT_MESSAGE, OUTPUT_MESSAGE };
7 changes: 7 additions & 0 deletions src/Constants/System.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const GENERATOR = Object.freeze({
pick_number_end: 3,
start_number: 1,
end_number: 9,
});

module.exports = GENERATOR;
83 changes: 83 additions & 0 deletions src/Controller/BaseballController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
const ReadError = require('../Error/ReadError');
const ValidationError = require('../Error/ValidationError');
const Validator = require('../Validator');

const RESTART = '1';
Copy link
Member

Choose a reason for hiding this comment

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

간단한 상수는 위에 따로 표기하는 방법 좋은거같아요!


class BaseballController {
#view;

#model;

#validator;

constructor(view, model) {
this.#view = view;
this.#model = model;
this.#validator = new Validator();
}

start() {
this.#view.pinrtStart();
Copy link
Contributor

Choose a reason for hiding this comment

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

소소한 오타이기는 하지만.. 수정하면 좋을 것 같아요~!

Copy link
Member Author

Choose a reason for hiding this comment

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

오호!!
바로 수정했습니다!
감사합니다!

this.#setGame();
}

#setGame() {
this.#model.setGame();
return this.#inputGameNumbers();
}

#inputGameNumbers() {
this.#view.readGameNumbers((numbers) => this.#checkGameNumbers(numbers));
}

#checkGameNumbers(numbers) {
try {
this.#validator.checkGameNumbers(numbers);
} catch (error) {
throw this.#handleError(error);
}
return this.#printHint(numbers);
}

#printHint(numbers) {
this.#view.printHint(this.#model.compareUserWithComputerNumbers(numbers));
return this.#threeStrikesOrNot();
}

#threeStrikesOrNot() {
if (this.#model.isThreeStrikes()) {
this.#view.printSuccess();
return this.#inputGameCommand();
}
this.#model.resetStatus();
return this.#inputGameNumbers();
}

#inputGameCommand() {
this.#view.readGameCommand((number) => this.#checkGameCommand(number));
}

#checkGameCommand(number) {
try {
this.#validator.checkGameCommand(number);
} catch (error) {
return this.#handleError(error);
}
return this.#restartOrFinish(number);
}

#restartOrFinish(number) {
if (number === RESTART) return this.#setGame();
return this.#view.finishGame();
}

#handleError(error) {
if (error instanceof ValidationError) {
return this.#view.printError(new ReadError('Validation Error', error));
}
throw error;
}

Choose a reason for hiding this comment

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

혹시 입력에 관한 에러를 다른 에러로 오버라이딩 하시는건가요? 하나 배워갑니다~!

}

module.exports = BaseballController;
8 changes: 8 additions & 0 deletions src/Error/DefaultError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class DefaultError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}

module.exports = DefaultError;
11 changes: 11 additions & 0 deletions src/Error/ReadError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const { ERROR_MESSAGE } = require('../Constants/Message');

class ReadError extends Error {
constructor(message, cause) {
super(message);
this.cause = cause.message;
this.name = `${ERROR_MESSAGE.error}`;
}
}

module.exports = ReadError;
5 changes: 5 additions & 0 deletions src/Error/ValidationError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const DefaultError = require('./DefaultError');

class ValidationError extends DefaultError {}

module.exports = ValidationError;
34 changes: 34 additions & 0 deletions src/Model/BaseballModel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const RandomNumberGenerator = require('../RandomNumberGenerator');
Copy link
Contributor

Choose a reason for hiding this comment

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

구조 분해 할당 하고 싶어지네요..ㅎㅎ
물론 이대로 사용하셔도 무방합니다..!


class BaseballModel {
#computerNumbers;

#score;
setGame() {
this.#saveComputerNumbers();
this.resetStatus();
}
#saveComputerNumbers() {
this.#computerNumbers = RandomNumberGenerator.generateRandomNumber();
}
compareUserWithComputerNumbers(input) {
input.split('').forEach((cur, index) => {

Choose a reason for hiding this comment

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

str split vs spread를 비교해보니 spread연산자가 더 빠르다고 합니다!
str split vs spread

관련된 근거를 찾아보려고했지만 자료가 있지 않아서 추가적으로 발견하게 되면 공유해드리겠습니다!!

Copy link
Member Author

Choose a reason for hiding this comment

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

오! 감사합니다
계속 까먹네요.

const isStrike =
this.#computerNumbers.includes(Number(cur)) && this.#computerNumbers.indexOf(Number(cur)) === index;
Comment on lines +16 to +17
Copy link
Member

Choose a reason for hiding this comment

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

includes는 불필요한 것 같습니다

Suggested change
const isStrike =
this.#computerNumbers.includes(Number(cur)) && this.#computerNumbers.indexOf(Number(cur)) === index;
const isStrike = this.#computerNumbers.indexOf(Number(cur)) === index;

const isBall = this.#computerNumbers.includes(Number(cur));
Comment on lines +16 to +18
Copy link

@y00eunji y00eunji Nov 30, 2022

Choose a reason for hiding this comment

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

굳이굳이굳이찝자면 isStrike, isBall 또한 구현하는 부분이기 때문에 외부로 메서드로 분리하는 것도 함수역할을 덜 수 있을 것 같습니다!

Copy link
Member Author

@Ryan-Dia Ryan-Dia Dec 6, 2022

Choose a reason for hiding this comment

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

아하 compose method 패턴적용 말씀이군요
그렇게 해도될 것 같습니다.
하지만 메서드로 만들면 함수에 인자가 두 개가 필요하고 isStrike는 두 번 필요하기에 두 번 모두 호출되어야합니다.
그래서 이렇게 설계했던 것 같습니다.

지금은 이렇게 리팩토링 되었습니다.

Suggested change
const isStrike =
this.#computerNumbers.includes(Number(cur)) && this.#computerNumbers.indexOf(Number(cur)) === index;
const isBall = this.#computerNumbers.includes(Number(cur));
compareUserWithComputerNumbers(input) {
this.#forEach(this.#spread(input));
return this.#score;
}
#spread(input) {
return [...input];
}
#forEach(input) {
input.forEach((cur, index) => {
const isStrike = this.#computerNumbers.indexOf(Number(cur)) === index;
const isBall = this.#computerNumbers.includes(Number(cur));
if (isStrike) this.#score.strike += 1;
if (!isStrike && isBall) this.#score.ball += 1;
});
}

if (isStrike) this.#score.strike += 1;
if (!isStrike && isBall) this.#score.ball += 1;
});
return this.#score;
}

resetStatus() {
this.#score = { ball: 0, strike: 0 };
}

isThreeStrikes() {
return this.#score.strike === 3;
}
}

module.exports = BaseballModel;
15 changes: 15 additions & 0 deletions src/RandomNumberGenerator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const { Random } = require('@woowacourse/mission-utils');
const GENERATOR = require('./Constants/System');

const RandomNumberGenerator = {
generateRandomNumber() {
const computer = [];
while (computer.length < GENERATOR.pick_number_end) {
const number = Random.pickNumberInRange(GENERATOR.start_number, GENERATOR.end_number);
if (!computer.includes(number)) computer.push(number);
}
return computer;
Comment on lines +6 to +11
Copy link
Member

Choose a reason for hiding this comment

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

set을 사용하신다면 if (!computer.includes(number))를 확인하지 않아도 될 것 같아요!

},
Comment on lines +5 to +12
Copy link
Contributor

Choose a reason for hiding this comment

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

다음과 같이 집합 Set을 사용하면 includes사용을 없애 시간 복잡도를 낮출 수 있고 if문을 사용하지 않아도 됩니다!

Suggested change
generateRandomNumber() {
const computer = [];
while (computer.length < GENERATOR.pick_number_end) {
const number = Random.pickNumberInRange(GENERATOR.start_number, GENERATOR.end_number);
if (!computer.includes(number)) computer.push(number);
}
return computer;
},
generateRandomNumber() {
const computer = new Set();
while (computer.length < GENERATOR.pick_number_end) {
const { start_number, end_number } = GENERATOR;
const number = Random.pickNumberInRange(start_number, end_number);
computer.add(number);
}
return computer;
},

Copy link
Member Author

Choose a reason for hiding this comment

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

const RandomNumberGenerator = {
  generateRandomNumber() {
    const computer = new Set();
    while (computer.size < GENERATOR.pick_number_end) {
      const number = Random.pickNumberInRange(GENERATOR.start_number, GENERATOR.end_number);
      computer.add(number);
    }
    return computer;
  },
};

오 감사합니다. 이 경우에는 set이 훨씬 좋군요
해당사항은 반영하였습니다.
set은 고려해보지 않았는데 다음번에는 set도 고려해보겠습니다.

};

module.exports = RandomNumberGenerator;
32 changes: 32 additions & 0 deletions src/Validator/GameCommand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const ValidationError = require('../Error/ValidationError');
const checkNumber = require('./util/util');
const { ERROR_MESSAGE } = require('../Constants/Message');

class GameCommand {
#input;

checkGameCommand(input) {

Choose a reason for hiding this comment

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

메서드 체이닝을 통해서 코드를 더 이쁘게 만들어볼 수 있을 거 같아요!!

Copy link
Member Author

@Ryan-Dia Ryan-Dia Dec 6, 2022

Choose a reason for hiding this comment

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

혹시 예를 들어 어떤식으로 하는지 알려주실 수 있나요 ?

this.#input = input;
this.#checkNumber();
this.#checkLength();
this.#checkOneOrTwo();
}

#checkNumber() {
checkNumber(this.#input);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

checkNumber만 왜 외부에서 만든 함수를 가지고 오는 건가요?

Copy link
Member Author

@Ryan-Dia Ryan-Dia Dec 6, 2022

Choose a reason for hiding this comment

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

상속대신 조합을 사용하였는데
지금 다시 생각해보니 굳이 하나의 함수를 가져오는 데는 필요없을 것 같아 각각 원래 코드로 바꾸었습니다.

Copy link

@y00eunji y00eunji Nov 30, 2022

Choose a reason for hiding this comment

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

굳이굳이굳이찝자면 공통된 부분을 무조건 추리는 것보단 .,,하나만 utils로 빼기위해 utils를 만드는 것보다는 공통된 index에서 하거나 그냥 빼지 않고 각각 유효성 검증하는 코드를 넣어 작성하는 것이 가독성에 좋을 것 같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

네 이 부분은 너무 억지로 조합을 사용한 것 같습니다.
해당 부분은 수정하였습니다 감사합니다!


#checkLength() {
if (this.#input.length !== 1) {
throw new ValidationError(ERROR_MESSAGE.length_one);
}
}

#checkOneOrTwo() {
if (!/1|2/.test(this.#input)) {
throw new ValidationError(ERROR_MESSAGE.one_or_two);
}
}
}

module.exports = GameCommand;
Loading