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

[카드 뒤집기 미션 - 2단계] 정윤서 미션 제출합니다. #9

Open
wants to merge 1 commit into
base: yunseeo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 37 additions & 0 deletions index.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,47 @@
body {
display: flex;
align-items: center;
justify-content: center;
height: 70vh;
}

h1 {
text-align: center;
}

.card { /*Card.js에서 사용*/
width: 80px;
height: 100px;
border-radius: 3px;
background-color: orange;
border: none;
box-shadow: 0px 15px 8px -10px gray;
color: white;
font-weight: bolder;
}

#cards {
display: flex;
gap: 10px;
padding: 15px;
padding-top: 20px;
padding-bottom: 20px;
border-radius: 10px;
width: 350px;
background-color: rgb(255, 200, 3);
position: relative;
}

#contents {
text-align: center;
}

#RestartBtn {
Copy link
Member

Choose a reason for hiding this comment

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

RestartBtn요소의 여부 상관없이 똑같은 레이아웃을 주면 UX 적으로 좋을 거 같아요!

position: relative;
top: -80px;
left: 163px;
border-radius: 3px;
background-color: rgb(238, 230, 216);
border: none;
height: 25px;
}
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
</head>
<body>
<div id="app">
<h1>카드 뒤집기 1단계</h1>
<h1>카드 뒤집기 2단계</h1>
<div id="cards"></div>
<div id="RestartButton"></div>
<div id="contents"></div>
</div>
</body>
</html>
31 changes: 21 additions & 10 deletions src/Card.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,41 @@
class Card {
// 필드 값은
constructor(isGoodCard) {
constructor(isGoodCard, cardClickHandler) {
this.isGoodCard = isGoodCard;
this.isClicked = false;
this.cardClickHandler = cardClickHandler;
this.alreadyClicked = false;
Copy link
Member

Choose a reason for hiding this comment

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

👍👍

}

//카드버튼 생성. 개수는?
createCardBtn() {
const btn = document.createElement('button');
btn.className = "card"; //css
btn.innerText = "카드입니다";
btn.className = "card"; //html -> css
//btn.innerText = "카드입니다";

btn.addEventListener('click', this.WhenCardClick.bind(this));
btn.addEventListener('click', () => {
if (!this.isClicked && !this.alreadyClicked) {
Copy link
Member

Choose a reason for hiding this comment

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

기회가 없는 상태에서 다른 버튼을 클릭해도 카드가 뒤집히고 있어요!
기회를 넘겨받아서 예외 사항을 처리해주면 좋겠네요

this.isClicked = true;
this.WhenCardClick(btn);
this.cardClickHandler(this);
}
});

return btn;
}

WhenCardClick() {
//'당첨입니다' 혹은 '꽝입니다' 문구 생성.
WhenCardClick(btn) {
//if (this.alreadyClicked) return; //이미 고른 카드는 고르지 말고 종료해라.
//this.alreadyClicked = true;
//this.remainingChances--; //아 여기서 계속 2->1 로 줄어들어서 문제 발생.
Copy link
Member

Choose a reason for hiding this comment

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

처음에 문제가 생기면 주석을 작성해서 커밋을 남겨놓고, 추후 해결한 이후에 주석 삭제를 습관화해주시면 좋을거같아요!
필요없는 주석을 삭제하면 파일 용량을 줄일 수 있어요


//'당첨!' 혹은 '꽝' 문구 생성.
const clickMessage = this.createClickMessage();
//alert(clickMessage);
const showMessage = document.getElementById('cards');
showMessage.innerText = clickMessage;
btn.innerText = clickMessage;
}

createClickMessage() {
return this.isGoodCard ? '당첨입니다' : '꽝입니다'; //삼항연산자 사용.
return this.isGoodCard ? '당첨!' : ''; //삼항연산자 사용.
}
}

Expand Down
93 changes: 93 additions & 0 deletions src/CardGame.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Shuffle from './Shuffle';

class CardGame {
constructor(cardCount, initialChances) {
this.cardClickHandler = this.cardClickHandler.bind(this);
this.shuffle = new Shuffle(cardCount, this.cardClickHandler);
this.initialChances = initialChances;
this.clickedCard = null;
}

startGame() {
const underRestartBtn = document.getElementById('RestartButton');
underRestartBtn.innerHTML = '';
this.remainingChances = this.initialChances;
this.shuffle.shuffleCards();
this.shuffle.displayCards();
this.displayChances();
}

//1. Card.js에서 cardClickHandler() 안에 this안주고 이 메서드 사용해도 됨.
/*cardClickHandler() {
this.shuffle.cards.forEach(card => {
if (card.isClicked) {
if (card.isGoodCard) {
this.displayResult('(성공!) 게임이 종료되었습니다.')
this.createRestartBtn();
} else if (!card.isGoodCard) {
this.giveExtraChance();
}
}
})
}*/

//2.
cardClickHandler(clickedCard) {
//console.log(this);
Copy link
Member

Choose a reason for hiding this comment

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

현재 this가 무엇인지 파악하기 위한 코드도 확인 이후에 바로 지워주시면 좋습니다

if (clickedCard.isClicked) {
if (clickedCard.isGoodCard) {
this.displayResult('(성공!) 게임이 종료되었습니다.')
this.createRestartBtn();
} else if (!clickedCard.isGoodCard) {
this.giveExtraChance();
}
}
}

displayResult(result) {
const resultDiv = document.getElementById('contents');
resultDiv.innerText = result;
}

giveExtraChance() {
this.remainingChances--;
this.displayChances();
if (this.remainingChances <= 0) {
this.displayResult('(실패!) 게임이 종료되었습니다.');
this.createRestartBtn();
} else {
this.displayChances();
}
}

displayChances() {
const chanceMessage = document.getElementById('contents');
chanceMessage.innerText = `남은 횟수: ${this.remainingChances}`;
}

createRestartBtn() {
const RestartBtn = document.createElement('button');
RestartBtn.innerText = '재시작';
RestartBtn.id = 'RestartBtn';

/*const undercards = document.getElementById('cards');
undercards.innerHTML = ''; //
undercards.appendChild(RestartBtn);*/

const undercards = document.getElementById('RestartButton');
undercards.innerHTML = ''; //
undercards.appendChild(RestartBtn);

RestartBtn.addEventListener('click', this.WhenBtnClick.bind(this, RestartBtn));
Copy link
Member

Choose a reason for hiding this comment

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

this를 바인딩하는것도 좋은 방법인데, 화살표함수를 사용하면 직관적으로 파악할 수 있어요!
정확히 말하면 화살표함수를 사용하면 호출방식을 체크하지 않아도 현재 스코프의 this를 참조할 수 있어서 코드를 읽기 쉬워져요

}

WhenBtnClick() {
this.restartGame();
}

restartGame() {
this.startGame();
}
}

export default CardGame;
66 changes: 37 additions & 29 deletions src/Shuffle.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,44 @@
import Card from './Card';

class Shuffle {
constructor(cardCount) {
this.cardCount = cardCount;
}

//카드 섞기 위한 사전작업_ 배열 생성.
generateCards() {
const cards = []; //배열 생성.
for (let i = 0; i < this.cardCount; i++) {
const isGoodCard = (i === 1);
const card = new Card(isGoodCard); //Card 클래스의 인스턴스 생성.
cards.push(card);
}
return cards;
}

shuffleCards() {
this.cards = this.generateCards();
for (let i = this.cards.length - 1; i > 0; i--) { //this.cards.length는 생성된 배열의 길이.
const j = Math.floor(Math.random() * (i + 1));
[this.cards[i], this.cards[j]] = [this.cards[j], this.cards[i]]; //배열 순서 바꾸기
}
constructor(cardCount, cardClickHandler) {
this.cardCount = cardCount;
this.cardClickHandler = cardClickHandler;
//this.initialChances = initialChances;
}

//카드 섞기 위한 사전작업_ 배열 생성.
generateCards() {
const cards = []; //배열 생성.
for (let i = 0; i < this.cardCount; i++) {
const isGoodCard = (i === 1);
const card = new Card(isGoodCard, this.cardClickHandler); //Card 클래스의 인스턴스 생성.
cards.push(card);
}

displayCards() {
const undercards = document.getElementById('cards');
this.cards.forEach(card => { //모든 배열 요소에 대해 수행.
const btn = card.createCardBtn();
undercards.appendChild(btn);
});
return cards;
}

shuffleCards() {
this.cards = this.generateCards();
for (let i = this.cards.length - 1; i > 0; i--) { //this.cards.length는 생성된 배열의 길이.
const j = Math.floor(Math.random() * (i + 1));
[this.cards[i], this.cards[j]] = [this.cards[j], this.cards[i]]; //배열 순서 바꾸기
}
}

export default Shuffle;
displayCards() {
const undercards = document.getElementById('cards');
undercards.innerHTML = '';
this.cards.forEach(card => { //모든 배열 요소에 대해 수행.
const btn = card.createCardBtn();
undercards.appendChild(btn);
});
}

/*displayInfo() {
const contents = document.getElementById('contents');
contents.innerText = `남은 횟수: ${this.initialChances}`;
}*/
}

export default Shuffle;
12 changes: 9 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import '../index.css';
import Shuffle from './Shuffle';
//import Shuffle from './Shuffle';
import CardGame from './CardGame';

const cardCount = 3;
const shuffle = new Shuffle(cardCount);
const cardCount = 4;
const initialChances = 2;
/*const shuffle = new Shuffle(cardCount, initialChances);
shuffle.shuffleCards();
shuffle.displayCards();
shuffle.displayInfo();*/
const cardGame = new CardGame(cardCount, initialChances);
cardGame.startGame();