์ด๋ฒ์ฃผ ์ฃผ์ ๋ ๋ค๋ฆฌ ๊ฑด๋๊ธฐ ๊ฒ์์ด์๋ค. ๋ค๋ฆฌ ๊ธธ์ด๋ฅผ ์ ๋ ฅ๋ฐ์ ๋ค๋ฆฌ๋ฅผ ์์ฑํ๊ณ , ์ ์๋ ์ค ํ๋๋ฅผ ์ ํํ์ฌ ๋ค๋ฆฌ ๋๊น์ง ๋๋ฌํ๋ฉด ์ข ๋ฃ๋๋ ๊ฒ์์ด์๋ค. ์๋ ์ ๋ณด์๋ ์ค์ง์ด ๊ฒ์์ ๋์จ ๋ค๋ฆฌ ๊ฑด๋๊ธฐ์ ์ ์ฌํ ๊ฒ์์ด๋ผ ๋ง๋ค๋ฉด์๋ ์ ๋ง ์ฌ๋ฐ์๋ ์ฃผ์ ์๋ค.
์ด๋ฒ์ฃผ์๋ ๋ง์ ์ ์ฝ ์ฌํญ๋ค์ด ๊ฑธ๋ ค์๋ ์ํ๋ก ๋ฏธ์
์ ์ํํ๋ค.
4์ฃผ์ฐจ ๋ฏธ์ ๊ณต์ง ๋ฉ์ผ ์ค ์ผ๋ถ์ด๋ค. ๋ฉ์ผ์ ์ฝ์ผ๋ฉฐ ์ด๋ฒ์ ์ง์ง ์ ํํ๋ ํ ์์์ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์ ๋ค์งํ๋ค. ํ ์ฐธ๊ฐ์๋ถ๋ค์ 3์ฃผ์ฐจ ์ฝ๋๋ฅผ ์ฝ์ด๋ณด๋ฉฐ MVC ํจํด์ ๊ณต๋ถํ๊ณ ์ ํ๊ณ , js์ class์ ๋ํ ๊น์ด์๋ ๊ณต๋ถ๋ ์งํํด๋ณด๊ณ ์ ํ๋ค. ๋ค์์ ํ์ต ๋ด์ฉ์ ๋ด์ ๋งํฌ์ด๋ค.
3์ฃผ์ฐจ ํผ๋๋ฐฑ ์ฌํญ์ ํฌํจ๋ ๋ด์ฉ์ด๋ค. ๋ด๊ฐ ์๊ฐํ์ ๋ 4์ฃผ์ฐจ๋ฅผ ์์ํ ๋์ ๋ด๊ฒ ๊ฐ์ฅ ๋ถ์กฑํ๋ ๋ถ๋ถ์ด ์๋๊น ์ถ๋ค. ์ฐธ๊ณ ์ฉ์ผ๋ก ๋จ๊ฒจ์ค ๋งํฌ๋ฅผ ๋ณด๋ฉฐ ์ ๋ง ๋ง์ด ๊ณ ๋ฏผํ๋ ๊ฒ ๊ฐ๋ค.
๊ฐ์ฒด๋ ์บก์ํ๋ ์ํ์ ์ธ๋ถ์ ๋ ธ์ถ๋์ด ์๋ ํ๋์ ๊ฐ๊ณ ์์ผ๋ฉฐ, ๋ค๋ฅธ ๊ฐ์ฒด์ ๋ฉ์์ง๋ฅผ ์ฃผ๊ณ ๋ฐ์ผ๋ฉด์ ํ๋ ฅํ๋ค. ๊ฐ์ฒด๋ ๋ฉ์์ง๋ฅผ ๋ฐ์ผ๋ฉด ๊ฐ์ฒด ๊ทธ์ ๋ฐ๋ฅธ ๋ก์ง(ํ๋)์ ์ํํ๊ฒ ๋๊ณ , ํ์ํ๋ค๋ฉด ๊ฐ์ฒด ์ค์ค๋ก ๋ด๋ถ์ ์ํ๊ฐ๋ ๋ณ๊ฒฝํ๋ค. ๊ฐ๋จํ ๋งํด์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ๊ฐ์ฒด๊ฐ ์ค์ค๋ก ์ผ์ ํ๋๋ก ํ๋ ํ๋ก๊ทธ๋๋ฐ์ด๋ค.
getter๋ฅผ ์ฌ์ฉํ๋ ๋์ ๊ฐ์ฒด์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด์์ ์ผ๋ถ์ด๋ค. ๋๋ ์ด๋ฒ ๋ฏธ์ ์ ์ํํ๋ฉฐ ์ ๋ฌธ๊ตฌ๋ฅผ ๊ณ์ ์๊ฐํ๋ฉฐ ์ฝ๋๋ฅผ ์์ฑํ๋ค. ์ด์ ๊ณผ ์ด๋ป๊ฒ ๋ฌ๋ผ์ก๋์ง ์ค์ ์์ฑํ๋ ์ฝ๋๋ฅผ ๋ณด๋ฉฐ ์์๋ณด์.
class Lotto {
#numbers;
constructor(numbers) {
this.validate(numbers);
this.#numbers = numbers;
}
validate(numbers) {
if (numbers.length !== 6) throw new Error(ErrorMsg.INVALID_LOTTO_COUNT);
if (new Set(numbers).size !== numbers.length)
throw new Error(ErrorMsg.INVALID_LOTTO_DUPLICATE);
if (numbers.join("").replace(/[0-9]/g, "").length > 0)
throw new Error(ErrorMsg.INVALID_LOTTO_NOT_NUM);
}
printNumbers() {
Console.print(`[${this.#numbers.join(", ")}]`);
}
getNumbers() {
return this.#numbers.map((number) => String(number));
}
}
3์ฃผ์ฐจ์ ์์ฑํ๋ ๋ก๋ ๊ฐ์ฒด์ด๋ค. ๊ฐ์ฒด๋ฅผ ๊ฐ์ฒด์ค๋ฝ๊ฒ ์ฐ์ง ๋ชปํ๊ณ ์์๋ค. ๋ก๋ ๊ฐ์ฒด๋ ๊ทธ์ ๋ก๋ ๋ฒํธ๋ฅผ ์ ์ฅํ๊ณ ์๋ค๊ฐ ๋ฒํธ๋ฅผ ์ถ๋ ฅํด์ฃผ๊ฑฐ๋ ์ ์ฅํ ๋ฒํธ๋ฅผ ๋ฐํํ๋ ์ผ ๋ง์ ์ํํ๋ค.
class BridgeGame {
#answer;
#currentPosition;
#totalTrial;
constructor(bridge) {
this.#answer = bridge;
this.#currentPosition = 0;
this.#totalTrial = 1;
}
move() {
if (this.#currentPosition < this.#answer.length) this.#currentPosition += 1;
}
retry() {
this.#totalTrial += 1;
this.#currentPosition = 0;
}
get totalTrial() {
return this.#totalTrial;
}
get currentPosition() {
return this.#currentPosition;
}
getCorrectDirection() {
return this.#answer[this.#currentPosition];
}
getIsLastPosition() {
return this.#currentPosition === this.#answer.length;
}
getCrossState(state) {
if (state === "failed")
return [
...this.#answer.filter((v, i) => i < this.#currentPosition),
`X${this.#answer[this.#currentPosition]}`,
];
return this.#answer.filter((v, i) => i < this.#currentPosition);
}
}
4์ฃผ์ฐจ ๋ฏธ์
์ ์์ฑํ๋ ๋ค๋ฆฌ ๊ฒ์ ๊ฐ์ฒด์ด๋ค. ์๋ฒฝํ์ง ์์ง๋ง ๊ฐ์ฒด๋ฅผ ๊ฐ์ฒด์ค๋ฝ๊ฒ ์ฌ์ฉํด๋ณด๋ ค๋ ๋
ธ๋ ฅ์ ํ ๊ฒ์ด ๋ณด์ธ๋ค. ๋ค๋ฆฌ๊ฒ์ ๊ฐ์ฒด๋ ์ ๋ต๋ค๋ฆฌ, ํ์ฌ ์ฌ์ฉ์์ ์์น, ์ด ์๋ ํ์๋ฅผ ํ๋์ ์ ์ฅํ๋ค. move
๋ฉ์๋๋ฅผ ํตํด ํ์ฌ ์ฌ์ฉ์์ ์์น๋ฅผ ์ด๋์ํค๊ณ , retry
๋ฉ์๋๋ฅผ ํตํด ๊ฒ์์ ์ฌ์์ ์ํจ๋ค. ๋ ํ์ฌ๊น์ง์ ๊ฒ์ ์งํ์ํฉ์ ๊ฐ์ฒด ๋ด๋ถ์ ๊ฐ์ ํตํด ๊ตฌํ๊ณ , getCrossState
๋ฉ์๋๋ฅผ ํตํด ๊ฐ์ฒด ์ธ๋ถ๋ก ๊ทธ ๊ฐ์ ์ ๋ฌํ๋ค.
๋จ์ํ ๊ฐ์ ์ ์ฅํ๊ณ ์ด๋ฅผ ๋ฐํํ๊ธฐ๋ง ํ๋ ๋ก๋ ๊ฐ์ฒด์๋ ๋ฌ๋ฆฌ ๊ฐ์ฒด ๋ด๋ถ์ ๊ฐ์ ์ปจํธ๋กค ํ๋ ๋ฉ์๋๋ฅผ ์์ฑํ์๊ณ , ์ธ๋ถ์์ ๊ฐ์ ๋ํ ์ง์ ์ ์ธ ์ ๊ทผ ์์ด ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๋ฅผ ๋ณ๊ฒฝํ ์ ์๋๋ก ํ๋ค.
3์ฃผ์ฐจ ํผ๋๋ฐฑ ์ฌํญ์ ํฌํจ๋ ๋ด์ฉ์ด๋ค. ๋น์ฆ๋์ค ๋ก์ง...? UI ๋ก์ง...? ์ด๋ฉด์ ์ฒ์ ๋ค์ด๋ณธ ๋ง์ด์๋ค. ๋ถ๋๋ฝ์ง๋ง ์ด ์๊ตฌ ์กฐ๊ฑด์ด ์ด๋ค ๊ฒ์ ๋ํ๋ด๋์ง ํ๋จํ๋๋ฐ ๊ฝค ์ค๋ ์๊ฐ์ด ๊ฑธ๋ ธ๋ค. ๋ด๊ฐ ํด์ํ UI ๋ก์ง๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ๊ตฌ๋ถ์ ๋ค์๊ณผ ๊ฐ์๋ค.
- UI ๋ก์ง
์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ง๋ ๋ถ๋ถ, ์ฌ์ฉ์์ ์ํธ์์ฉํ๋ ๋ถ๋ถ์ ๋ด๋นํ๋ ๋ก์ง
- ๋น์ฆ๋์ค ๋ก์ง
UI ๋ก์ง ์ด์ธ์ ๋ชจ๋ ๋ก์ง
์ด๋ฒ์ฃผ ๋ฏธ์
์๋ ์ฃผ์ด์ง ๊ฐ์ฒด์ ํด๋์ค๊ฐ ์ ๋ง ๋ง์๋ค. InputView
, OutputView
, BridgeGame
, BridgeMaker
, BridgeRandomNumberGenerator
์ด๋ ๊ฒ 5๊ฐ๋ ์ฃผ์ด์ก๋ค. ์ด์ค View๊ฐ ๋ถ์ ๋ ๊ฐ์ฒด๊ฐ UI๋ก์ง์ ๋ด๋นํ๋ ๊ฐ์ฒด๋ค์ด์๊ณ , ๋๋จธ์ง ๊ฐ์ฒด๋ค๊ณผ ํด๋์ค๋ ๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ๋ค.
๋๋ UI๋ก์ง์ ๋ด๋นํ๋ ๊ฐ์ฒด๋ค์ ์ ๋ง ์ ์คํ ์ฌ์ฉํ๋ค. ๋น์ฆ๋์ค ๋ก์ง์ UI๋ฅผ ์ ์ธํ ๋ชจ๋ ๋ก์ง์ด๋ผ ์๊ฐํด์ UI ๋ก์ง๋ง ์ ์์ฑํ๋ฉด ๋๋จธ์ง ํธํ๊ฒ ์์ฑํ ์ ์์๊ฑฐ๋ผ ํ๋จํ๊ธฐ ๋๋ฌธ์ด์๋ค.
const InputView = {
readBridgeSize(callback) {
this.getUserInput(
Question.BRIDGE_SIZE,
callback,
this.readBridgeSize.bind(this)
);
},
readMoving(callback) {
this.getUserInput(
Question.MOVE_DIRECTION,
callback,
this.readMoving.bind(this)
);
},
readGameCommand(callback) {
this.getUserInput(
Question.RESTART,
callback,
this.readGameCommand.bind(this)
);
},
getUserInput(question, callback, redirect) {
Console.readLine(question, (input) => {
try {
callback(input);
} catch (error) {
Console.print(error.message);
redirect(callback);
}
});
},
};
์ด๋ฒ์ฃผ ๋ฏธ์
์ ์ค์ ๋ก ์์ฑํ๋ InputView
์ฝ๋์ด๋ค. ์ ๋ง ์
๋ ฅ๊ฐ์ ๋ค๋ฃจ๋ ๋ถ๋ถ๋ง์ ์์ฑํ๊ณ ์ ๋
ธ๋ ฅํ๊ณ , ํ์ํ ๋น์ฆ๋์ค ๋ก์ง์ ์ฝ๋ฐฑํจ์๋ฅผ ์ด์ฉํ๋ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
์ด๋ฒ์๋ ์ญ์ 3์ฃผ์ฐจ ํผ๋๋ฐฑ์ ํฌํจ๋ ๋ด์ฉ์ด๋ค. ์ด ๋ถ๋ถ์ ์ด๋ฒ ๋ฏธ์ ์์ ์ ๋ง ๋ง์ด ๊ณ ๋ฏผํ์๊ณ ๊ทธ ๊ฒฐ๊ณผ ๋๋ฆ ํ๊ธฐ์ (?)์ธ ์์ด๋์ด๋ฅผ ๋ธ ๋ถ๋ถ์ด์๋ค. ๋ค๋ฅธ ๋ถ๋ค์ ์ฝ๋๋ฅผ ์ฝ์ด๋ณด์ง ๋ชปํด ๋ด ์๊ฐ์ด ์ผ๋ง๋ ํจ๊ณผ์ ์ธ์ง๋ ๋น๊ตํด๋ณด์ง ๋ชปํ์ผ๋ ๋๋ฆ ํผ์์๋ ๋ฟ๋ฏํ๋ ๋ถ๋ถ์ด๋ผ ๊ณต์ ํ๊ณ ์ ํ๋ค.
๋ค๋ฆฌ ๊ฑด๋๊ธฐ ๊ฒ์์ ์์ํฉ๋๋ค.
๋ค๋ฆฌ์ ๊ธธ์ด๋ฅผ ์
๋ ฅํด์ฃผ์ธ์.
3
์ด๋ํ ์นธ์ ์ ํํด์ฃผ์ธ์. (์: U, ์๋: D)
U
[ O ]
[ ]
์ด๋ํ ์นธ์ ์ ํํด์ฃผ์ธ์. (์: U, ์๋: D)
U
[ O | X ]
[ | ]
๊ฒ์์ ๋ค์ ์๋ํ ์ง ์ฌ๋ถ๋ฅผ ์
๋ ฅํด์ฃผ์ธ์. (์ฌ์๋: R, ์ข
๋ฃ: Q)
Q
์ต์ข
๊ฒ์ ๊ฒฐ๊ณผ
[ O | X ]
[ | ]
๊ฒ์ ์ฑ๊ณต ์ฌ๋ถ: ์คํจ
์ด ์๋ํ ํ์: 1
๋ค๋ฆฌ ๊ฑด๋๊ธฐ ๊ฒ์์ ์์์ด๋ค. ๋ค๋ฆฌ ๊ฑด๋๊ธฐ ๊ฒ์์ ์ฌ์ฉ์๊ฐ ๋ฐฉํฅ์ ์ ํํ๋ฉด ๊ทธ์ ๋ฐ๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ฃผ๊ฒ ๋๋ค. ์ด ๋ฌธ์์ด์ ์ด๋ป๊ฒ ๋ง๋ค์ง ๊ณ ๋ฏผํ๋ค.
์ต์ข
์ ์ผ๋ก ์๊ฐํด๋ธ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด์๋ค. ์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ ๋ต ๋ค๋ฆฌ์ ์ ์ฅ๋ ์ฌ์ฉ์ ์
๋ ฅ ๋ฐฐ์ด์ ๋น๊ตํ์ฌ ๋ฌธ์์ด์ ์์ฑํ๋ ๋ฐฉ์์ด๋ค. ์ด ๋ฐฉ์์ด ๊ฐ์ฅ ๋จผ์ ๋ ์ฌ๋ผ ์ด๋ฅผ ์ ์ฉํด๋ณด๊ณ ์ ํ์ง๋ง ์ด๋ฏธ BridgeGame
ํด๋์ค์๋ ์ธ๊ฐ์ ํ๋๊ฐ ์กด์ฌํ์ผ๋ฏ๋ก ํ๋๋ฅผ ์ถ๊ฐํ์ง ์๋ ๋ฐฉ์์ ์์๊น ๊ณ ๋ฏผํด๋ณด์๋ค.
๋ ๋ฒ์งธ ๋ฐฉ๋ฒ์ด ๋ด๊ฐ ์ด์ผ๊ธฐํ ๋๋ฆ์ ํ๊ธฐ์ (?)์ธ ๋ฐฉ์์ด๋ค. ๋ด BridgeGame
์ ๋ก์ง์ ์ ๊น ์ค๋ช
ํ์๋ฉด bridge
ํ๋์ ์ ๋ต ๋ค๋ฆฌ๋ฅผ ๋ฐฐ์ด์ ํํ๋ก ์ ์ฅํ๊ณ , currentPostion
ํ๋์ ์ฌ์ฉ์์ ์์น ๊ฐ์ ์ซ์๋ก ์ ์ฅํ์ฌ ์ด๋ฅผ ์ธ๋ฑ์ค์ฒ๋ผ ํ์ฉํ๋ค. ๋ด๊ฐ ์๊ฐํ ๋ฌธ์์ด์ ์์ฑ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ๋ค.
์กฐ๊ฑด
- ํ์ฌ ์์น๊น์ง์ ์ ๋ต ๋ฐฐ์ด๋ง์ ๊ณ ๋ คํ์ฌ ๋ฌธ์์ด์ ์์ฑํ๋ค.
- ์ฌ์ฉ์๊ฐ ์ ๋ต์ ๋ง์ท๋์ง, ํ๋ ธ๋์ง์ ๋ฐ๋ผ ๋ฌธ์์ด์ ํํ๊ฐ ๋ฐ๋๋ค.
- ์ฌ์ฉ๋๋ ๋ฌธ์๋ 'O', 'X', ' '(๊ณต๋ฐฑ) ๋ฟ์ด๋ค.
๋ฐฉ๋ฒ
์ ๋ต ๋ฐฐ์ด์ ์์๋ถ๋ถ์์ ํ์ฌ ์์น๊น์ง๋ก ์๋ฅธ๋ค.
์ ๋ฌธ์์ด(Up), ์๋ซ ๋ฌธ์์ด(Down)์ ์์ฑํ ๋ ๋ฐฐ์ด์ ๋ง๋ ๋ค.
์ฌ์ฉ์๊ฐ ์ ๋ต์ ๋ง์ท๋์ง, ํ๋ ธ๋์ง ์ ๋ ฅ๋ฐ๋๋ค.
๋ง์ท๋ค๋ฉด ์๋ฆฐ ์ ๋ต ๋ฐฐ์ด์ ๊ทธ๋๋ก ๋ฐํํ๋ค. ํ๋ ธ๋ค๋ฉด ๋ง์ง๋ง ์์์ X๋ฅผ ์ถ๊ฐํ์ฌ ๋ฐํํ๋ค.
- ex) ๋ฐํ ๋ฐฐ์ด ์์
๋ง์ท์ ๋: ["U", "D", "U"]
ํ๋ ธ์ ๋: ["U", "D", "XU"]์ ๋ ฅ ๋ฐ์ ์๋ฆฐ ์ ๋ต ๋ฐฐ์ด์ ์ด์ฉํด Up, Down์ ์ฑ์ด๋ค.
- ex) ๋ง์ท์ ๋
์๋ฆฐ ์ ๋ต ๋ฐฐ์ด: ["U", "D", "U"]
Up: [" O ", " ", " O "]
Down: [" ", " O ", " "]-> U๋ฉด Up์ " O ", Down์ " "
-> D๋ฉด Up์ " ", Down์ " O "
- ex) ํ๋ ธ์ ๋
์๋ฆฐ ์ ๋ต ๋ฐฐ์ด: ["U", "D", "XU"]
Up: [" O ", " ", " "]
Down: [" ", " O ", " X "]-> XU๋ฉด Up์ " ", Down์ " X "
-> XD๋ฉด Up์ " X ", Down์ " "join ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ Up, Down์ ๋ฌธ์์ด๋ก ๋ฐ๊ฟ ์ถ๋ ฅํ๋ค.
์ ๊ณผ์ ์ ๊ฑฐ์น ๋ ์ ๋ต ๋ฐฐ์ด์ ์๋ผ ๋ฐํํ๋ ๋ถ๋ถ๊น์ง๋ฅผ BridgeGame
์ด, ์ดํ ๋ฌธ์์ด์ ๋ง๋ค์ด๋ด๋ ๋ถ๋ถ์ OutputView
๊ฐ ๋ด๋นํ๋๋ก ์ฝ๋๋ฅผ ์์ฑํด ์ถ๊ฐ์ ์ธ ํ๋ ์์ด ๋ฌธ์์ด์ ์์ฑํด๋๋ค.
์ ๋ด์ฉ์ ํฌํจ๋์ง ์์ ์ถ๊ฐ์ ์ธ ๋ถ๋ถ์ ์ฐํ ์ฝ 5๊ธฐ ํ๋ฆฌ์ฝ์ค 4์ฃผ์ฐจ ๋ฏธ์ MVC ์ ์ฉ๊ธฐ์ ์์ธํ ์ ์ด๋์์ผ๋ ์ฐธ๊ณ ํ๋ฉด ์ข์ ๊ฒ์ด๋ค.
์ ์ฒด ์ฝ๋๋ https://github.com/kyw0716/javascript-bridge์์ ํ์ธํ ์ ์๋ค.