뽑기에 사용되는 가중치 알고리즘

gunggme·2024년 10월 4일

유니티(unity)

목록 보기
9/9

테잌 마 머니!

뽑기 하는 게임은 한국에서는 잘 팔리는 중이다. 왜냐? 뽑기에서 나오는 도파민이 터짐과 동시에, 다른사람은 없는 무언가를 얻어 좋은 기분을 받을 수 있기 때문이다. 오늘은 그 도파민을 터트려줄 수 있는 랜덤 알고리즘을 알아볼거다.

가중치란?

우선 가중치를 어떻게 활용할 건지 한번 알아보자

내용확률
노말50%
희귀30%
......

이런식으로 게임에 확률표가 있는 것을 많이 봤을 것이다. 이 아이템을 뽑게 하는 알고리즘을 보통 가중치 알고리즘을 많이 사용하게 되는데, 작동하는 원리를 알아보도록 하자

작동 원리?

미리 정해져있는 가중치와 아이템을 기준으로 먼저 확률의 합계를 가져온 뒤, 그 안에서 랜덤으로 값을 생성 후, 아이템 마다의 가중치를 누적, 그 후 누적된 가중치가 랜덤생성 된 수보다 클 경우 작동하는 알고리즘이다, 예를 들어 설명을 해보자면

먼저 미리 정해져있는 표를 만들어보자, 확률의 합은 총합 1이 나오게 하는 것이 가장 좋다.

아이템확률
일반0.7
희귀0.278
고급0. 22

이런식으로 간단하게 만들어도 사용이 되는데, 작동방식은 아래와 같이 작동하게 된다.

작동 방식

변수 0 을 지정
표에서 만든 전체 확률 값을 가져온다 (위에 있는 표를 기준으로 1)
전체 확률에서 랜덤으로 값을 정한다 (임의의 수 0.4)
그 후 확률을 누적한다 (임의 변수 a += (일반 확률, ....))
순차적으로 누적중에, 해당 값이 넘지 않는다면? 해당 값을 리턴한다(0.4 < 0.7 ==> true => 일반 아이템 리턴)

위에 작성한 원리 대로 작동하게 되는데, 가중치 알고리즘은 뽑기 뿐만이 아니라, 여러 상황에서도 작동이 되는 신기한 알고리즘이다.

코드 공유

여기는 내가 만든 가중치 알고리즘의 코드다, C#에서 제네릭 클래스를 이용해서 작성화였으며, 다른 코드와 연동이 되도록 제작해놓아, 여러 프로젝트에서 사용이 가능한 용의한 코드로 준비를 하였다.

using System;
using System.Collections.Generic;

[Serializable]
public class ProbabilityItem<T>
{
    public T item;
    public float value;
}

public class Random
{

    // 확률에 따라 랜덤으로 선택하는 함수
    public static T GetRandomEnum<T>(List<ProbabilityItem<T>> probabilities)
    {
        float total = 0f;
        foreach (var entry in probabilities)
        {
            total += entry.value; // 전체 확률 합계
        }

        float randomValue = UnityEngine.Random.Range(0f, total); // 0과 total 사이의 랜덤 값 생성
        float cumulative = 0f;

        foreach (var entry in probabilities)
        {
            cumulative += entry.value; // 확률을 누적
            if (randomValue < cumulative)
            {
                return entry.item; // 랜덤 값이 누적 확률을 넘지 않으면 해당 값을 선택
            }
        }

        return probabilities[0].item; // 기본값 (예외처리로 사용 가능)
    }
}

사용하는 방법은 대체로 간단하다.

사용방법

using System;

public class RandomPro{
	public string itemName
}

public class RandomExam{
	public List<ProbabilityItem<RandomPro>> items = new List(); // 이미 확률은 정해놨다는 가정하에
    
    public void UseRandom(){
    	RandomPro ran = Random.GetRandomEnum<RandomPro>(items);//랜덤으로 정해짐
        print("랜덤 값 출력" + ran.itemName);
    }

}

이런식으로 사용할 수 있게된다.

profile
안녕하세요!

0개의 댓글