const $ = (selector) => document.querySelector(selector);
const $All = (selector) => document.querySelectorAll(selector);
const [carButtonDom, tryButtonDom] = $All(".btn-cyan");
const [carNameDom, tryNumberDom] = $All(".w-100");
const progressTitle = $(".mt-4");
const resultDom = $All(".mt-5")[2];
const sectionRaceTimes = $("#section-race-times");
const setting = (carName) => ` <div class="mr-2">
<div class="car-player">${carName}</div>
<div class="d-flex justify-center mt-3">
<div class="relative spinner-container">
<span class="material spinner"></span>
</div>
</div>
</div>`;
const moving = `<div class="forward-icon mt-2">⬇️️</div>`;
const Message = {
success: "🎇🎇🎇🎇축하합니다!🎇🎇🎇🎇",
overFiveError:
"유효하지 않은 이름 길이입니다. 자동차의 이름은 1자이상, 5자 이하만 가능합니다",
countError:
"입력한 레이싱 횟수가 너무 적습니다. 레이싱 횟수는 1이상이어야 합니다.",
};
const result = (winnerName) => `
<div>
<h2>🏆 최종 우승자: <span id="winners">${winnerName}</span> 🏆</h2>
<div class="d-flex justify-center">
<button type="button" class="btn btn-cyan" id="restart">다시 시작하기</button>
</div>
</div>
`;
const carButtonHandler = () => {
carNameArray = splitCarName(carNameDom.value);
carNameArray.map((val) => {
checkOverFiveError(val);
});
applyOverFiveError();
};
const tryButtonHandler = () => {
tryNumber = tryNumberDom.value;
if (tryNumber < 1) return alert(Message.countError);
startRacing(tryNumber, carNameArray);
tryButtonDom.disabled = true;
};
const carButtonEvent = carButtonDom.addEventListener("click", carButtonHandler);
const tryButtonEvent = tryButtonDom.addEventListener("click", tryButtonHandler);
let carNameArray, tryNumber;
let isSmallerFive = true;
const splitCarName = (val) => val.split(",");
const checkOverFiveError = (val) => {
if (val.length > 5 || val.length < 1) {
alert(Message.overFiveError);
isSmallerFive = false;
}
};
const applyOverFiveError = () => {
if (isSmallerFive) {
carButtonDom.disabled = true;
sectionRaceTimes.hidden = false;
} else {
isSmallerFive = true;
}
};
const startRacing = (tryNumber, carName) => {
let count = 0;
carName.map((val) => (progressTitle.innerHTML += setting(val)));
const carMovingDom = $All(".car-player");
timerCheck(count, carName, tryNumber, carMovingDom);
};
let isGo = [];
let tryObject = {};
const timerCheck = (count, carNameArray, tryNumber, carMovingDom) => {
tryObject.count = count;
tryObject.tryNumber = tryNumber;
tryObject.timer = setInterval(() => {
isGo = carNameArray.map(() =>
Math.floor(Math.random() * 10) >= 4 ? true : false
);
goCarMove(carNameArray, isGo, carMovingDom);
tryObject.count++;
compareCountAndTryNumber(tryObject);
}, 1000);
};
let maxCarName = [];
let countArray = {};
let max = -Infinity;
const compareCountAndTryNumber = (tryObject) => {
if (tryObject.count === Number(tryObject.tryNumber)) {
clearInterval(tryObject.timer);
$All(".relative").forEach((x) => x.remove());
checkWinner();
resultDom.innerHTML = result(maxCarName);
$All(".btn-cyan")[2].addEventListener("click", returnToOriginalHandler);
setTimeout(() => {
alert(Message.success);
}, 2000);
}
};
const returnToOriginalHandler = () => {
initializeDom();
initializeValue();
initializeAttr();
};
const initializeDom = () => {
while (progressTitle.hasChildNodes()) progressTitle.firstChild.remove();
while (resultDom.hasChildNodes()) resultDom.firstChild.remove();
};
const initializeValue = () => {
countArray = {};
max = -Infinity;
maxCarName = [];
$("#inputCarName").value = "";
$("#inputTryNumber").value = "";
};
const initializeAttr = () => {
sectionRaceTimes.hidden = true;
carButtonDom.disabled = false;
tryButtonDom.disabled = false;
};
const goCarMove = (carNameArray, isGo, carMovingDom) => {
carNameArray.map((val, idx) => {
if (countArray[val] !== undefined)
countArray[val] = isGo[idx] ? ++countArray[val] : countArray[val];
else countArray[val] = isGo[idx] ? 1 : 0;
addMovingDom(isGo, idx, carMovingDom);
});
};
const addMovingDom = (isGo, idx, carMovingDom) => {
if (isGo[idx]) carMovingDom[idx].insertAdjacentHTML("afterend", moving);
};
const checkWinner = () => {
for (const idx in countArray) {
if (max < countArray[idx]) {
maxCarName = [];
maxCarName.push(idx);
max = countArray[idx];
} else if (max === countArray[idx]) {
maxCarName.push(idx);
max = countArray[idx];
}
}
};
const $ = (selector) => document.querySelector(selector);
const $All = (selector) => document.querySelectorAll(selector);
const [carButtonDom, tryButtonDom] = $All(".btn-cyan");
const [carNameDom, tryNumberDom] = $All(".w-100");
const progressTitle = $(".mt-4");
const resultDom = $All(".mt-5")[2];
const sectionRaceTimes = $("#section-race-times");
const setting = (carName) => ` <div class="mr-2">
<div class="car-player">${carName}</div>
<div class="d-flex justify-center mt-3">
<div class="relative spinner-container">
<span class="material spinner"></span>
</div>
</div>
</div>`;
const moving = `<div class="forward-icon mt-2">⬇️️</div>`;
const Message = {
success: "🎇🎇🎇🎇축하합니다!🎇🎇🎇🎇",
overFiveError:
"유효하지 않은 이름 길이입니다. 자동차의 이름은 1자이상, 5자 이하만 가능합니다",
countError:
"입력한 레이싱 횟수가 너무 적습니다. 레이싱 횟수는 1이상이어야 합니다.",
};
const result = (winnerName) => `
<div>
<h2>🏆 최종 우승자: <span id="winners">${winnerName}</span> 🏆</h2>
<div class="d-flex justify-center">
<button type="button" class="btn btn-cyan" id="restart">다시 시작하기</button>
</div>
</div>
`;
const carButtonHandler = () => {
carNameArray = splitCarName(carNameDom.value);
carNameArray.map((val) => {
checkOverFiveError(val);
});
applyOverFiveError();
};
const tryButtonHandler = () => {
tryNumber = tryNumberDom.value;
if (tryNumber < 1) return alert(Message.countError);
let car = new Car();
car.startRacing(tryNumber, carNameArray);
tryButtonDom.disabled = true;
};
const carButtonEvent = carButtonDom.addEventListener("click", carButtonHandler);
const tryButtonEvent = tryButtonDom.addEventListener("click", tryButtonHandler);
let carNameArray, tryNumber;
let isSmallerFive = true;
const splitCarName = (val) => val.split(",");
const checkOverFiveError = (val) => {
if (val.length > 5 || val.length < 1) {
alert(Message.overFiveError);
isSmallerFive = false;
}
};
const applyOverFiveError = () => {
if (isSmallerFive) {
carButtonDom.disabled = true;
sectionRaceTimes.hidden = false;
} else {
isSmallerFive = true;
}
};
let isGo = [];
let tryObject = {};
class Car {
constructor() {}
startRacing = (tryNumber, carName) => {
let count = 0;
carName.map((val) => (progressTitle.innerHTML += setting(val)));
const carMovingDom = $All(".car-player");
this.timerCheck(count, carName, tryNumber, carMovingDom);
};
timerCheck = (count, carNameArray, tryNumber, carMovingDom) => {
tryObject.count = count;
tryObject.tryNumber = tryNumber;
tryObject.timer = setInterval(() => {
isGo = carNameArray.map(() =>
Math.floor(Math.random() * 10) >= 4 ? true : false
);
this.goCarMove(carNameArray, isGo, carMovingDom);
tryObject.count++;
this.compareCountAndTryNumber(tryObject);
}, 1000);
};
compareCountAndTryNumber = (tryObject) => {
if (tryObject.count === Number(tryObject.tryNumber)) {
clearInterval(tryObject.timer);
$All(".relative").forEach((x) => x.remove());
this.checkWinner();
resultDom.innerHTML = result(maxCarName);
$All(".btn-cyan")[2].addEventListener(
"click",
this.returnToOriginalHandler
);
setTimeout(() => {
alert(Message.success);
}, 2000);
}
};
returnToOriginalHandler = () => {
this.initializeDom();
this.initializeValue();
this.initializeAttr();
};
initializeDom = () => {
while (progressTitle.hasChildNodes()) progressTitle.firstChild.remove();
while (resultDom.hasChildNodes()) resultDom.firstChild.remove();
};
initializeValue = () => {
countArray = {};
max = -Infinity;
maxCarName = [];
$("#inputCarName").value = "";
$("#inputTryNumber").value = "";
};
initializeAttr = () => {
sectionRaceTimes.hidden = true;
carButtonDom.disabled = false;
tryButtonDom.disabled = false;
};
goCarMove = (carNameArray, isGo, carMovingDom) => {
carNameArray.map((val, idx) => {
if (countArray[val] !== undefined)
countArray[val] = isGo[idx] ? ++countArray[val] : countArray[val];
else countArray[val] = isGo[idx] ? 1 : 0;
this.addMovingDom(isGo, idx, carMovingDom);
});
};
addMovingDom = (isGo, idx, carMovingDom) => {
if (isGo[idx]) carMovingDom[idx].insertAdjacentHTML("afterend", moving);
};
checkWinner = () => {
for (const idx in countArray) {
if (max < countArray[idx]) {
maxCarName = [];
maxCarName.push(idx);
max = countArray[idx];
} else if (max === countArray[idx]) {
maxCarName.push(idx);
max = countArray[idx];
}
}
};
}
let maxCarName = [];
let countArray = {};
let max = -Infinity;
class Car를 통해 함수들을 넣었다.
const $ = (selector) => document.querySelector(selector);
const $All = (selector) => document.querySelectorAll(selector);
const [carButtonDom, tryButtonDom] = $All(".btn-cyan");
const [carNameDom, tryNumberDom] = $All(".w-100");
const progressTitle = $(".mt-4");
const resultDom = $All(".mt-5")[2];
const sectionRaceTimes = $("#section-race-times");
const setting = (carName) => ` <div class="mr-2">
<div class="car-player">${carName}</div>
<div class="d-flex justify-center mt-3">
<div class="relative spinner-container">
<span class="material spinner"></span>
</div>
</div>
</div>`;
const moving = `<div class="forward-icon mt-2">⬇️️</div>`;
const Message = {
success: "🎇🎇🎇🎇축하합니다!🎇🎇🎇🎇",
overFiveError:
"유효하지 않은 이름 길이입니다. 자동차의 이름은 1자이상, 5자 이하만 가능합니다",
countError:
"입력한 레이싱 횟수가 너무 적습니다. 레이싱 횟수는 1이상이어야 합니다.",
};
const result = (winnerName) => `
<div>
<h2>🏆 최종 우승자: <span id="winners">${winnerName}</span> 🏆</h2>
<div class="d-flex justify-center">
<button type="button" class="btn btn-cyan" id="restart">다시 시작하기</button>
</div>
</div>
`;
const carButtonHandler = () => {
carNameArray = splitCarName(carNameDom.value);
carNameArray.map((val) => {
checkOverFiveError(val);
});
applyOverFiveError();
};
const tryButtonHandler = () => {
tryNumber = tryNumberDom.value;
if (tryNumber < 1) return alert(Message.countError);
let car = new Car();
car.startRacing(tryNumber, carNameArray);
tryButtonDom.disabled = true;
};
const carButtonEvent = carButtonDom.addEventListener("click", carButtonHandler);
const tryButtonEvent = tryButtonDom.addEventListener("click", tryButtonHandler);
let carNameArray, tryNumber;
let isSmallerFive = true;
const splitCarName = (val) => val.split(",");
const checkOverFiveError = (val) => {
if (val.length > 5 || val.length < 1) {
alert(Message.overFiveError);
isSmallerFive = false;
}
};
const applyOverFiveError = () => {
if (isSmallerFive) {
carButtonDom.disabled = true;
sectionRaceTimes.hidden = false;
} else {
isSmallerFive = true;
}
};
let isGo = [];
let tryObject = {};
class ReturnInitialize {
returnToOriginalHandler = () => {
this.initializeDom();
this.initializeValue();
this.initializeAttr();
};
initializeDom = () => {
while (progressTitle.hasChildNodes()) progressTitle.firstChild.remove();
while (resultDom.hasChildNodes()) resultDom.firstChild.remove();
};
initializeValue = () => {
countArray = {};
max = -Infinity;
maxCarName = [];
$("#inputCarName").value = "";
$("#inputTryNumber").value = "";
};
initializeAttr = () => {
sectionRaceTimes.hidden = true;
carButtonDom.disabled = false;
tryButtonDom.disabled = false;
};
}
class Compare extends ReturnInitialize {
constructor() {
super();
}
compareCountAndTryNumber = (tryObject) => {
if (tryObject.count === Number(tryObject.tryNumber)) {
clearInterval(tryObject.timer);
$All(".relative").forEach((x) => x.remove());
this.checkWinner();
resultDom.innerHTML = result(maxCarName);
$All(".btn-cyan")[2].addEventListener(
"click",
this.returnToOriginalHandler
);
setTimeout(() => {
alert(Message.success);
}, 2000);
}
};
checkWinner = () => {
for (const idx in countArray) {
if (max < countArray[idx]) {
maxCarName = [];
maxCarName.push(idx);
max = countArray[idx];
} else if (max === countArray[idx]) {
maxCarName.push(idx);
max = countArray[idx];
}
}
};
}
class Timer extends Compare {
constructor() {
super();
}
timerCheck = (count, carNameArray, tryNumber, carMovingDom) => {
tryObject.count = count;
tryObject.tryNumber = tryNumber;
tryObject.timer = setInterval(() => {
isGo = carNameArray.map(() =>
Math.floor(Math.random() * 10) >= 4 ? true : false
);
this.goCarMove(carNameArray, isGo, carMovingDom);
tryObject.count++;
this.compareCountAndTryNumber(tryObject);
}, 1000);
};
goCarMove = (carNameArray, isGo, carMovingDom) => {
carNameArray.map((val, idx) => {
if (countArray[val] !== undefined)
countArray[val] = isGo[idx] ? ++countArray[val] : countArray[val];
else countArray[val] = isGo[idx] ? 1 : 0;
this.addMovingDom(isGo, idx, carMovingDom);
});
};
addMovingDom = (isGo, idx, carMovingDom) => {
if (isGo[idx]) carMovingDom[idx].insertAdjacentHTML("afterend", moving);
};
}
class Car extends Timer {
constructor() {
super();
}
startRacing = (tryNumber, carName) => {
let count = 0;
carName.map((val) => (progressTitle.innerHTML += setting(val)));
const carMovingDom = $All(".car-player");
this.timerCheck(count, carName, tryNumber, carMovingDom);
};
}
let maxCarName = [];
let countArray = {};
let max = -Infinity;
class를
ReturnInitialize -> Compare -> Timer -> Car 형태로 나누어 처리한다.
class 상속을 처리할때 순서에 주의한다. (아니면 에러가 뜬다.)
부모클래스가 먼저 작성되고 그것을 자식클래스가 이해하고 처리해야한다.
위의 코드도 순서가 ReturnInitialize -> Compare -> Timer -> Car로 작성된다.
자식클래스에서 부모의 상속을 받는다면
constructor로 super()
추가해야한다.
└── ReturnInitialize ( returnToOriginalHandler, initializeDom,initializeValue, initializeAttr)
└── Compare (compareCountAndTryNumber, checkWinner)
└── Timer (timerCheck, goCarMove, addMovingDom)
└── Car (startRacing)
기존에 인스턴스.startRacing(매개변수) 대신 new Car(매개변수)를 넣어서 한다.
기존
let car = new Car();
car.startRacing(tryNumber, carNameArray);
....
class Car extends Timer {
constructor() {
super();
}
startRacing = (tryNumber, carName) => {
let count = 0;
carName.map((val) => (progressTitle.innerHTML += setting(val)));
const carMovingDom = $All(".car-player");
this.timerCheck(count, carName, tryNumber, carMovingDom);
};
}
수정 : new Car() 에서 new Car(tryNumber, carNameArray)로 처리
this.tryNumber = tryNumber;
this.carName = carName;
코드 추가 필요
let car = new Car(tryNumber, carNameArray);
car.startRacing();
....
class Car extends Timer {
constructor(tryNumber, carName) {
super();
this.tryNumber = tryNumber;
this.carName = carName;
}
startRacing = () => {
let count = 0;
this.carName.map((val) => (progressTitle.innerHTML += setting(val)));
const carMovingDom = $All(".car-player");
this.timerCheck(count, this.carName, tryNumber, carMovingDom);
};
}