JS. 카드 게임(3) - 카드 셔플을 분해하자!
개요
카드 게임을 할 때, 카드가 충분히 섞이도록 하는데 그 때 쓰는 스크립트가 아래와 같다
let arr = [1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8];
let result = arr.sort(() => Math.random() > 0.5 ? 1 : -1);
let result를 분해하고자 한다.
1. sort() 분해
sort는 정렬을 해주는 함수이다
sort는 기본적으로 배열을 문자열(String) 타입으로 간주하고 비교한다고 한다
즉, [100, 2, 3]이 있고 이를 sort로 분류하자면 [100, 2, 3]으로 반환된다고 한다
왜냐하면, 1 < 2 이기 때문이다(맨 앞글자부터 차레로 비교하기 때문이다)
sort()는 여기까지만 알자.
2. math.random() > 0.5 ? 1 : -1; 분해
삼항연산자이다
랜덤으로 난수를 뽑아서 0.5보다 크면 1을 반환하고, 0.5보다 작으면 -1을 반환한다
즉, 1을 반환하면 오름차순으로 정렬하고 -1을 반환하면 내림차순으로 반환한다
(sort 메서드는 음수 값을 리턴하면 내림차순으로 정렬하고, 양수 값을 리턴하면 오름차순으로 정렬한다)
3. arr.sort(() => Math.random() > 0/5 ? 1 : -1; 분해
여기서는 sort가 어떠한 알고리즘으로 정렬되는지 알아보도록 하자.
[0]과 [n]을 모두 뺄셈을 통해 비교를 한 후 적절한 곳에 배치한다
[1]과 [n-1]을 모두 뺄셈을 통해 비교한 후 적절한 곳에 배치한다
... 계속 이렇게 정렬을 하는 것이다
여튼 랜덤 값들을 모아서 각각의 순서를 랜덤하게 배치한다!
결론
이 방법의 몇 가지 문제점이 있다
1. sort 정렬의 해결법
우리는 카드를 랜덤하게 섞는 것이 목적이라 어떻게 정렬되던 상관이 없었지만(100과 2를 비교하면 100이 작다고 한다)
만약, sort로 정렬을 하여야 한다면 어떻게 해야할까?
compare function을 사용하여야 한다
2. sort()메소드의 문제점
모든 순열의 빈도 수가 균일하게 나오지 않기 때문에 권장되지 않는다고 한다
그래서 피셔-예이츠 알고리즘을 사용한다고 한다
더 알아보고 싶은 사람들은
다른 블로그의 글을 참조하자.
나는 요즘 포트폴리오를 만든다고 시간이 없다...ㅜ