티스토리 뷰

카드 배열 생성하고 무작위로 섞기

const total = 12;
const colors = ['red', 'orange', 'yellow', 'green', 'white', 'pink'];
let colorCopy = colors.concat(colors); //colors 변수를 수정하지 않고 배열 복사
//(12) ['red', 'orange', 'yellow', 'green', 'white', 'pink', 'red', 'orange', 'yellow', 'green', 'white', 'pink']
let shuffled = [];

function shuffle() { // 피셔-예이츠 셔플
  for (let i = 0; colorCopy.length > 0; i++) {
    const randomIndex = Math.floor(Math.random() * colorCopy.length);
    shuffled = shuffled.concat(colorCopy.splice(randomIndex, 1));
  }
}

// 값이 항상 바뀐다
//(12) ['orange', 'green', 'yellow', 'pink', 'green', 'red', 'yellow', 'red', 'white', 'white', 'pink', 'orange']
//(12) ['green', 'green', 'orange', 'orange', 'red', 'white', 'pink', 'red', 'white', 'yellow', 'pink', 'yellow']
 

[Js] 피셔 예이츠 셔플 알고리즘 (Fisher-Yates Shuffle)

자바스크립트에는 랜덤 정렬을 위한 2가지 방법1.sort()메소드2.Fisher-Yates shuffle 알고리즘일반적을 sort() 메소드는 오름차순 / 내림차순으로 정렬할 때 자주 사용됨.오름차순 : 양수 값을 리턴내림

velog.io

 

 

카드 생성해주는 함수

function createCard(i) {
  const card = document.createElement('div');
  card.className = 'card'; //.card 태그 생성
  const cardInner = document.createElement('div');
  cardInner.className = 'card-inner'; //.card-inner 태그 생성
  const cardFront = document.createElement('div');
  cardFront.className = 'card-front'; //.card-front 태그 생성
  const cardBack = document.createElement('div');
  cardBack.className = 'card-back'; //.card-back 태그 생성
  cardBack.style.backgroundColor = shuffled[i];
  cardInner.appendChild(cardFront);
  cardInner.appendChild(cardBack);
  card.appendChild(cardInner);
  return card;
}

위 코드의 실행 결과

 

게임을 시작하는 함수

 

전체 카드 개수 저장한 total변수,

6가지 색을 저장한 colors 변수가 있다.

colors를 2번 복사해 colorCopy 변수를 만들었다.

shuffle 함수로 카드를 섞어서 shuffled 배열을 만들었다.

function startGame() {
  shuffle();
  for (let i = 0; i < total; i++) {
    const card = createCard(i);
    $wrapper.appendChild(card);
  }
}
startGame();

12장의 카드를 생성함

 

11.3 카드 잠깐 보여 줬다 뒤집기

https://github.com/Harimad/FrontEnd/commit/3de71b99137aa11288df1cb78b600663df0628b1

 

주의할점 

class selector를 붙여 쓸때와 붙이지 않을때의 차이 이해하기

/* card와 flipped 클래스를 가진 녀석의 후손을 선택 */
.card.flipped .card-inner {
  transform: rotateY(180deg);
}

/* card클래스 후손의 flipped클래스 후손의 card-inner클래스 선택 */
.card .flipped .card-inner {
  transform: rotateY(180deg);
}

 

 

11.4 카드 클릭해 짝 맞추기

https://github.com/Harimad/FrontEnd/commit/117c0815762580c0c24d5ba8786f833b97bed210

 

11.5 효과 발생 중 카드 클릭 막기

 

버그 발생

1. 처음 카드를 잠깐 보여 줬다가 다시 뒤집는 동안 카드 클릭이 가능함

2. 이미 짝이 맞춰진 카드를 클릭해도 뒤집힘

3. 한 카드를 두 번 연이어 클릭하면 더 이상 해당 카드가 클릭 되지 않음

4. 네 카드를 연달아 클릭하면 마지막 두 카드가 앞면을 보인 채 남아있음

 

해결하려면

카드를 클릭할 수 있는 상황과 클릭할 수 없는 상황 구분해야함.

이를 위해 clickable이라는 변수 선언함.

처음에 카드를 잠깐 보여 줬다가 다시 뒤집을 때까지 클릭 막음.

또한, 클릭한 카드가 이미 짝이 맞춰진 카드이거나

조금 전에 뒤집은 카드인 경우 모두 onClickCard 함수 에서 걸러냄.

https://github.com/Harimad/FrontEnd/commit/61d057e3e2440fa09097c50ff36fbb5e445ca00a

 

 

1분 퀴즈

다음 코드를 실행할 떄 콘솔에 어떤 순서로 알파벳이 찍히는지 호출 스택과 이벤트 루프를 통해 설명하시오.

function aaa() {
  setTimeout(() => {
    console.log('d');
  }, 0);
  console.log('c');
}

setTimeout(() => {
  console.log('a');
  aaa();
}, 0);

setTimeout(() => {
  aaa();
  console.log('b');
}, 0);

//정답 : a, c, c, b, d, d

호출스택: 함수가 실행되는 공간

백그라운드: eventListener, setTimeout가 가있는 공간

태스크 큐: 백그라운드(eventListener, setTimeout)의 콜백함수들이 들어 있는 공간

이벤트 루프: 호출스택이 비어있을 때 태스크 큐에서 하나씩 꺼내서 호출스택으로 넘겨주는 역할

 

 

마무리

1. 호출스택

 

동기 함수만 있을 떄는 호출 스택만 생각하면 된다.

함수가 호출될 때 호출 스택에 들어가고, 실행이 완료되면 호출 스택에서 빠져나간다.

기존 함수의 실행이 완료되지 않았는데 다른 함수가 호출되면 새로 호출된 함수는 기존 함수 위에 쌓인다.

처음 파일을 실행할 때는 anonymous(크롬 브라우저 기준)라는 익명 함수가 실행된다.

 

2. 이벤트 루프

 

비동기 함수가 실행될 때는 호출 스택뿐만 아니라 이벤트 루프까지 동원해서 실행 순서를 파악해야 한다.

타이머나 이벤트 리스터 같은 비동기 함수들은 콜백 함수를 백그라운드에서 태스크 큐로 보낸다.

이벤트 루프는 호출 스택이 비어 있으면 태스크 큐에서 함수를 하나씩 꺼내 호출 스택으로 보내 실행한다.

반대로 보면, 호출 스택이 비어 있지 않으면 태스크 큐에 있는 함수는 실행되지 않는다.

 

 

 

 

참고자료

 

 

(JavaScript) 이벤트 리스너와 콜백(event listener, callback)

안녕하세요. 이번 시간은 이벤트 리스너와 콜백 차례입니다. 지금까지는 이벤트 리스너를 안 다뤘습니다만 이제 다룰 때가 된 것 같습니다. 이벤트 리스너와 콜백 방식도 자바스크립트에서 많

www.zerocho.com

 

 

(JavaScript) 실행 컨텍스트 - 클로저와 호이스팅

안녕하세요. 이번 시간에는 범위에 이어 실행 컨텍스트와 클로저에 대해서 살펴보겠습니다. 제가 지난 시간에 실행 컨텍스트가 제일 중요하다고 하면서 강좌를 마쳤습니다. lexical scoping과 이것

www.zerocho.com

 

 

(JavaScript) ES2015 이후의 실행 컨텍스트

제가 자바스크립트에서 가장 중요하게 생각하는 것들(실행 컨텍스트, 이벤트 루프, 프로토타입) 중 하나인 실행 컨텍스트 2편입니다. 실행 컨텍스트와 이벤트 루프 분석만 잘 할 줄 알아도 코드

www.zerocho.com

 

 

(JavaScript) 함수의 범위(scope) - lexical scoping

안녕하세요. 이번 시간에는 함수 스코프(scope)에 대해서 설명드리겠습니다. 스코프는 범위라는 뜻입니다. 전역 변수와 지역 변수 자바스크립트에서 주로 변수를 사용해 데이터를 저장했었는데

www.zerocho.com

 

 

(JavaScript) 호출 스택과 이벤트루프

안녕하세요. 이번 시간에는 호출 스택과 이벤트루프에 대해서 알아보겠습니다! 정말 오랜만에 자바스크립트 파트 강좌를 올리네요. 사실 웬만한 것들은 다 다뤘다고 생각해서 50강으로 끝내려

www.zerocho.com

 

 

(ECMAScript) ES2015(ES6) Promise

 안녕하세요. 이번 시간에는 Promise에 대해서 알아보겠습니다. Callback Hell 그동안 자바스크립트나 Node.js에서 callback 패턴은 잘 쓰고 계셨나요? 해당 동작이 완료될 때까지  직접 기다릴 필요 없이

www.zerocho.com

호출스택공부할때 참고할 만한 곳

http://latentflip.com/loupe/

 

http://latentflip.com/loupe/

 

latentflip.com

 

댓글
다크모드
Document description javascript psychology
더보기 ,제목1 태그 호버