테스트 코드와 전체 코드는 아래의 Git에서
GetWeightedRandomIndex(가중치확률메서드) 란에서 찾아볼 수 있다.
https://github.com/OfficialCaox/UnityAlgorithmCollection
본문===============================================================================
예시는 롤토체스이다.
해당 예시를 보면, 시행 1회에 5가지의 결과가 존재한다.
8레벨의 확률을 가정한다면,
각각
0.15f, 0.2f, 0.35f, 0.25f, 0.05f
의 확률로,
티어 1,2,3,4,5 가 산출되는 것을 알 수 있다.
이런 함수를 찾기가 힘들어서 직접 이러한 확률 함수를 만들어 보았다.
public static int GetWeightedRandomIndex(params float[] pers)//확률을 차례대로(합이 1이되는것을 권장) 넣었을 때 해당하는 확률이 걸리면 01234가 차례로 나옴.
{
int maxLenth = 0;
if (pers.Length == 1)//배열길이가 1이면 무조건 그 값이 나와야함으로 0을 리턴한다.
return 0;
//1.가장 소숫점이 긴 변수를 찾아낸다.
int lenth;
decimal total = 0;
for (int i = 0; i < pers.Length; i++)
{
lenth = pers[i].ToString().Substring(pers[i].ToString().IndexOf('.') + 1).Length;
total += (decimal)pers[i];
if (maxLenth < lenth)
maxLenth = lenth;
}
int correction = (int)(total * (decimal)Math.Pow(10, maxLenth)); //-> 곱해주는 수
int randomNumber = UnityEngine.Random.Range(1, correction + 1);
int tempNum = 0;
int num = 0;
for (int i = 0; i < pers.Length; i++)
{
num = (int)(correction * (decimal)pers[i]);
if (num + tempNum >= randomNumber)
{
//Debug.Log(num + tempNum + ">=" + randomNumber);
return i;
}
tempNum += num;
}
return 0;
}
사용 예시는 다음과 같다.
public void Awake()
{
for (int i = 0; i < 10000; i++)
{
int index = GetWeightedRandomIndex(0.15f, 0.2f, 0.35f, 0.25f, 0.05f);
Debug.Log((index + 1) + "티어 유닛입니다 !");
}
}
실제 게임 구현에서는,
switch문으로 나누어서, 상점에 유닛을 각각 다르게 띄워준다던지,, 이런식으로 구현하면 될 것이다.
로그 순서가 뒤죽박죽인데,
넣은 순서대로 보면 다음과 같다.
1티어 유닛은 15% 확률 => 1500회
2티어 유닛은 20% 확률 => 2000회
3티어 35% => 3500....
※해당 함수는 검증되지 않은 함수, 개선점 및 오류 발견시 댓글 부탁드립니다.
'개발일지 > 기능구현' 카테고리의 다른 글
[Unity] 투사체의 방향 전환 구현 CalculateAngle (0) | 2023.10.26 |
---|---|
[Unity] 확률 함수 구현 Random Function (1) | 2023.10.26 |
[Unity] Json 암호화 파일 Save, Load 구현 (0) | 2023.10.26 |
[Unity] Android, IOS 푸시알림 구현 (1) | 2023.05.03 |
오프라인 보상 시스템 구현(시간 검증 포함) (0) | 2023.05.01 |