개발일지/기능구현

[Unity] 확률 함수 구현 Random Function

OfficialCaox 2023. 10. 26. 01:48

테스트 코드와 전체 코드는 아래의 Git에서

 

Probability_Method(확률메서드) 란에서 찾아볼 수 있다.

 

https://github.com/OfficialCaox/UnityAlgorithmCollection

 

GitHub - OfficialCaox/UnityAlgorithmCollection: 손수 제작한 유니티 알고리즘 모음 리포지토리(Handcrafted Unity

손수 제작한 유니티 알고리즘 모음 리포지토리(Handcrafted Unity Toolkit)UnityAlgorithmCollection) - GitHub - OfficialCaox/UnityAlgorithmCollection: 손수 제작한 유니티 알고리즘 모음 리포지토리(Handcrafted Unity Toolkit)Un

github.com

 

본문===============================================================================

 

 게임에서 확률을 사용할 일은 매우 많다.

 

 메이플스토리와 같은 게임에서 주문서등은 N%, 1-N 확률로 성공과 실패를 반복한다.

 

 내가 원했던 기능은 다음과 같다.

 

매개변수로 확률을 입력 받으면, 그 확률에 맞게끔 true, 혹은 false가 반환되는 것.

 

확률은 기본적으로, 0~1사이의 값이기 때문에, 매개변수로 소수값을 넘겨받는다.

 

Ex) 50%를 구현하고 싶으면, 0.5 입력.

 for(int i = 0; i < 10000; i++)
 {
     Debug.Log("Chance :" + Probability(0.5));
 }

이러면 통계적으로 true가 5000번, false가 5000번 정도 나오는 것이 내 함수의 목적이다.

 

구현을 보자.

 

 public static bool Probability(double chance)
    {
        return (UnityEngine.Random.value <= chance);
    }
    public static bool Probability(float chance)
    {
        return (UnityEngine.Random.value <= chance);
    }

생각보다 엄청 간단하지 않은가 ,,? 

 

 알고리즘도 엄청 쉽다. UnityEngine.Random.value는 0에서 1 사이의 무작위 float 값을 반환한다.

 

예를들면  Input이 0.75라고 치면 이진수로는 0.110000....(2) 이런식일텐데

 

UnityEngine.Random.value는 무작위로 0.51231... 0.13322..... 이런식으로 값을 내뿜을 것이다.

 

인풋이 0.75이라고 가정한다면, 75% 확률로 true가 반환되고, 25% 확률로 false가 반환되어야한다.

 

굳이 논리적으로 갈 필요도 없이, 0부터 1까지 랜덤으로 산출되는 소숫값이 

0~ 0.75사이에 들어갈 확률은 75%에 근사하다는 것은 자명한 사실이다.

 

(물론 깊게 들어가면, 부동소수점 형식 특성상 10진법에서의 소수를 정확하게 표기하지 못하는 경우가 많기 때문에 정확하게 0.75%라는 확률에 나오지는 않을 것이다.

 

그렇지만, 그 정도의 정확도를 요구하는 함수는 나의 목표가 아니다. 뭐 리니지 만들 것도 아니고.. 

 

 

아래는 테스트 코드이다.

    public void Awake()
    {
        for(int i = 0; i < 100000; i++)
        {
            Debug.Log("90% Chance :" + Probability(0.9f));
        }
    }

 

이 경우, 통계적으로 10만의 시행 횟수중 true가 9만회, false가 1만회가 나오는 것이 알맞은 값일 것이다.

 

.

표준 편차를 감안한다면, 아주 만족스러운 값이다.

 

 

 

private Long calculateTotalScore(String studentId) {
    Long totalScore = 0L;

    totalScore += competitionRepository.findByStudentId(studentId).stream().mapToInt(S_W_ContestEntity::getCompetitionScore).sum();
    totalScore += counselingRepository.findByStudentId(studentId).stream().mapToInt(CounselingEntity::getCounselingScore).sum();
    totalScore += employmentRepository.findByStudentId(studentId).stream().mapToInt(EmploymentEntity::getEmploymentScore).sum();
    totalScore += eventsRepository.findByStudentId(studentId).stream().mapToInt(DepartmentEventsEntity::getEventsScore).sum();
    totalScore += graduationProjectRepository.findByStudentId(studentId).stream().mapToInt(GraduationExhibitionEntity::getGraduationProjectScore).sum();
    totalScore += internshipRepository.findByStudentId(studentId).stream().mapToInt(InternshipEntity::getInternshipScore).sum();
    totalScore += languageSkillsRepository.findByStudentId(studentId).stream().mapToInt(LanguageSkillsEntity::getLanguageScore).sum();
    totalScore += overseasStudyRepository.findByStudentId(studentId).stream().mapToInt(OverseasTrainingEntity::getOverseasStudyScore).sum();
    totalScore += qualificationRepository.findByStudentId(studentId).stream().mapToInt(CertificateMajorEntity::getQualificationScore).sum();
    totalScore += trainingRepository.findByStudentId(studentId).stream().mapToInt(EmploymentTrainingEntity::getTrainingScore).sum();

    return totalScore;
}