https://jdy0120.github.io/divisionTeam/
위 링크에서 사용하실 수 있습니다.
이번 글에선 리그오브레전드 팀 나누기 프로젝트에 대해 소개해 드리겠습니다.
완벽하지 않은 프로젝트였지만 개인적으로 잘 사용한 프로젝트였는데요.
개발하면 나는 반드시 사용할 것 같다는 실용성 때문에 개발하게 되었습니다.
친구들이 10명모여 게임을 진행하려고하면 할상 밸런스가 문제였습니다. 5:5로 나누는데 단순히 감에 의존하여 팀을 나누기 때문에 본격적인 게임을 시작하기 위해선 3판에서 4판정도의 밸런스 조정게임이 필요했습니다.
시간으로 따지면 한판당 30분 3판이면 90분
10명이 모이면 900분의 낭비가 있었고 모두들 모여 즐거운 스포츠를 하기 위해 사전투자시간이 너무 길었습니다.
mmr에 맞춰 팀을 나누주면 밸런스를 맞추는데 많은 도움이 되지 않을까 생각했고 프로젝트를 진행하게 됐습니다.
5가지의 요구조건에 맞춰 개발을 진행했습니다.
1. 5:5로 팀을 나누며 밸런스가 가장 좋아야한다.
2. 리그오브레전드에는 라인(탑,정글,미드,원딜,서폿)이라는 개념이 있다. 같은 팀에 같은라인을 가는 팀원이 최대한 없도록 설계해야한다.
3. 같이 팀하고 싶은 유저들이 있다. 이 유저는 같은 팀으로 배치해야한다.
4. 멀티서치가 가능해야한다.
5. 게임안에서 블루팀이 유리한 점이 많다.(챔피언 선택 우선권, 챔피언 벤 우선권, *7시방향에서 시작) 나눈 팀중에 평균mmr이 낮은 팀은 블루팀으로 배정하고 만약 두 팀의 mmr이 똑같다면 검색순서가 빠른 팀이 브르루팀으로 간다.
* 7시방향에서 시작이 유리한 이유는 다음 링크를 참조해주세요 : https://www.youtube.com/watch?v=-gUSxnXClgc
1. 5:5로 팀을 나누며 밸런스가 가장 좋아야한다.
각 선수의 mmr을 측정하기로 했습니다.
리그오브레전드는 2015년 이후로 랭크게임mmr을 제공해주지 않고 있습니다. 그렇기에 직접 계산해야했습니다. 처음 생각한 mmr측정방법은 많은 게임에서 사용하고 있는 Elo rating이었습니다.
하지만 Elo rating을 사용하기 위해선 각 선수의 모든 전적을 활용해야했고 그 선수와 게임했던 모든 선수의 전적이 필요했습니다. (정확한 레이팅 측정을 위해) 계산이 복잡하고 연산이 많다는 것은 정확성에서 좋을 수 있지만 연산 시간이 많이 걸리고 무엇보다 자원이 많이 필요하다는 것이었습니다.
그렇기에 2014년도에 한 유저가 계산한 정확도 높은 mmr계산법을 이용해 간단한 mmr계산을 했습니다. 계산법은 이렇습니다.
각 티어의 기본 mmr
아이언 : 450 ~ 750
브론즈 : 800 ~ 1100
실버 : 1150 ~ 1450
골드 : 1500 ~ 1800
플레티넘 : 1850 ~ 2150
다이아몬드 : 2200 ~ 2500
마스터 : 2550 ~ 3050
그랜드마스터,챌린저 : 3100 ~ +point
리그오브레전드에서 받아올 수 있는 사용자 정보를 사용했습니다. 승리수,패배수,유저의 티어
MMR = (유저의 티어에 해당하는 기본 MMR) + (승률-50)*(판수에 따른 가산점)
판수에 따른 가산점 : 판수가 많을수록 mmr이 조금 오르고 판수가 적을수록 mmr이 많이 오릅니다. (이는 리그오브 레전드에서 판수가 적을수록 승리에 따른 점수가 높게 책정되는 시스템을 보고 만들었습니다.)
5:5로 나누기 많은 알고리즘을 생각했지만 지금 만드는 프로젝트에는 '선수가 선호하는 라인이 있다.', '같은 팀을 해야만하는 유저가 있다.' 요구조건이 있기 때문에 2^10=1024인 모든 경우의 수를 생각하기로 했습니다.
비트마스크를 이용해 range를 0이상 1<<10미만 까지로 정하였고 모든 경우의 선수총합MMR을 저장했습니다.
기본적인 mmr계산은 이렇습니다. [기본 티어 mmr점수 + (승률*100-50)*(x)]
x는 임의로 정한 변수입니다.
위 티어계산은 2015년 라이엇이 공개했던 티어 계산을 기반으로 만들었습니다. 현재는 제공하지 않고 있습니다.
코드가 굉장히 클린하지 못합니다.
설명드리자면
비트마스크를 통해 10명의 유저가 1팀2팀으로 가는 경우의수를 모두 계산합니다.
2^10이므로 약 1024가지의 경우의수가 생깁니다.
브라우저에서 충분히 계산할 수 있는 연산이라고 생각해 모든 경우를 계산하도록 했습니다.
만약 1팀2팀의 각 인원수가 5명이 아니면 return하는 백트래킹을 넣어 연산에 조금 도움이 되도록 설계했습니다.
divisionPosition()에선 각 플레이어가 선택한 포지션이 겹칠경우 1팀2팀에 골고루 포지션이 나눠지지 않으면 백트래킹해주는 함수입니다.
2. 리그오브레전드에는 라인(탑,정글,미드,원딜,서폿)이라는 개념이 있다. 같은 팀에 같은라인을 가는 팀원이 최대한 없도록 설계해야한다.
총 6개의 포지션으로 나눴습니다. 탑,정글,미드,원딜,서폿,상관없음
우선 가장선호하는 라인을 모든 선수가 입력했다고 했을 경우 같은 라인을 가는 유저가 3명이상 있을 수 있습니다. 이 경우 2명을 제외하고 모두 '상관없음'으로 포지션을 설정했습니다.
5:5로 나누는 연산에 백트래킹을 집어 넣었습니다. 같은 팀에 같은 라인을 선호하는 유저가 있다면 return false를 해줬습니다.
두 팀에 포지션이 골고루 분포되어 있어야 합니다. 그러기위해 선호하는 포지션에 맞게 팀을 나눌 수 있도록 함수를 만들었습니다.
3. 같이 팀하고 싶은 유저들이 있다. 이 유저는 같은 팀으로 배치해야한다.
같이 팀하고 싶어하는 유저의 고유아이디를 묶어서 한 배열에 저장했습니다. 배열에 있는 유저의 고유아디이를 발견하면 같은 배열에 있는 유저또한 같은 팀에 있는지 확인하고 하나라도 없다면 return false를 해줬습니다.
4. 멀티서치가 가능해야한다.
promise.all()을 사용해 비동기 병렬처리를 진행했습니다. 단순히 비동기 처리를 했을 때보다 지연시간이 줄었습니다.
5. 게임안에서 블루팀이 유리한 점이 많다.(챔피언 선택 우선권, 챔피언 벤 우선권, *7시방향에서 시작) 나눈 팀중에 평균mmr이 낮은 팀은 블루팀으로 배정하고 만약 두 팀의 mmr이 똑같다면 검색순서가 빠른 팀이 블루팀으로 간다.
1,2번 조건으로 나눴던 두 팀 중 MMR이 낮은 팀을 블루팀, MMR이 높은 팀을 레드팀으로 배정했습니다.
위 프로젝트로 밸런스를 맞추기 위한 연습게임을 안할 수 있게 되었습니다.
'프로젝트' 카테고리의 다른 글
Figma -> React 프로젝트 원페이지 사이트 홈 퍼블리싱 (0) | 2022.12.12 |
---|---|
[리액트 따라하며 배우기] 간단한 투두리스트2 Redux 적용하기 React+typescript (0) | 2022.12.12 |
포트폴리오 웹사이트 프로젝트 (0) | 2022.12.10 |
[리액트 따라하며 배우기] 달력 프로젝트2 달력에 공휴일 표시하기 React+typescript, axios (0) | 2022.12.08 |
[리액트 따라하며 배우기] 사이드바 프로젝트 React+typescript, styled-components,react-router-dom (0) | 2022.12.05 |