ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 익성비 기대값 계산기 만들기
    토이 프로젝트 2023. 6. 30. 18:43

    메이플엔 일정확률로 1에서 10레벨을 업 시켜주는 익성비란 아이템이 존재한다

    한두개 썼을떈 대충 레벨업이 잘된건지 아닌지 알 수 있지만,

    기본 10개씩 뿌려대는 요즘엔 이게 잘 된건지 아닌지 감이 잘 안온다

     

    생각해보니 익성비 메커니즘 자체는 간단하고

    간단히 10만번정도 시뮬 돌려서 통계 내면 그게 기대값이고 백분율 아닌가

    만들어보자

     

    https://www.fmkorea.com/2621079257

     

    익성비 확률표

    렙 높아 질수록 1업 확률 높아짐

    www.fmkorea.com

    일단 익성비 레벨별 확률표

    레벨에 따라 확률이 달라지는데

    딱히 규칙도 없어 이걸 어떻게 표현해야 그나마 노가다가 덜할까 고민해봤는데,

    어차피 확률은 5% 단위이니

    2차원 배열을 만들고

    각 레벨당 20개의 int를 할당하기로 했다

     

    예를 들어 190렙은 1업을 할 확률이 55퍼, 2업 확률이 35퍼, 3렙 확률이 10퍼니

    int a[190][]에 {1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3}을 넣고

    20개의 값중 하나를 뽑아 그만큼 렙업을 하도록 하였다

     

    <h1>익성비 백분율 계산기</h1>
    	<hr>
        <br>
            <img id="bbang" height="400" weight="400" src="bread.jpg"></img>
            <br>
            <pre id="err"></pre>
            <br>
            
    
            시작 레벨  <input id="one"/><br>
            최종 레벨  <input id="two"/> <br>
            먹인 익성비 개수 <input id="three"/> <br>
            <button id = 'sh' onclick = 'calulate()' type="button">실행</button>
            <button id = 'rs' onclick = 'reset()'  type="button">초기화</button>
            <br>
    
            <pre id='res'></pre>  
            <pre id='res2'></pre>

    그 다음은 html 파트

    이미지랑 input 3개 버튼 2개 넣어주고

    innerHtml을 표현할 pre 3개를 넣어주었다

    하나는 에러, 하나는 기대값, 하나는 통계

     

    <style>
      @import url('https://fonts.googleapis.com/css2?family=Gowun+Batang:wght@700&display=swap');
    </style>
    
    <style type="text/css">
            pre{
                font-family: 'Gowun Batang', serif;
            }
            #res{
                font-size: 25px;
            }
            #res2{
                font-size: 15px;
            }
            input {
                width: 50px;
                height: 32px;
                font-size: 15px;
                margin-bottom: 5px;
                border: 0;
                border-radius: 15px;
                outline: none;
                padding-left: 10px;
                background-color: rgb(233, 233, 233);
            }
        </style>

    css는 구글 폰트 하나를 import해왔고

    input 버튼이 너무 구려서 이것만 살짝 디자인 해줬다

    그 외엔 결과값 폰트 크기 조정정도

     

     

    이제 자바스크립트 파트

     const arr = [ 
                [1,2,3,4,5,6,7,7,8,8,8,8,9,9,9,9,10,10,10,10], //141
                [1,2,3,4,5,6,6,7,7,8,8,8,8,9,9,9,9,10,10,10], //142
                [1,2,3,4,5,6,6,7,7,7,7,8,8,8,9,9,9,10,10,10], //143
                [1,2,3,4,5,6,6,6,6,7,7,8,8,8,9,9,9,10,10,10], //144
                [1,2,3,4,4,5,5,6,6,7,7,8,8,8,9,9,9,10,10,10], //145
                [1,2,3,4,4,5,5,6,6,7,7,7,8,8,8,9,9,9,10,10], //146
                [1,2,3,4,4,5,5,6,6,6,7,7,7,8,8,8,9,9,10,10], //147
                [1,2,3,4,4,5,5,5,6,6,6,7,7,7,8,8,9,9,10,10], //148
                [1,2,3,3,4,4,5,5,5,6,6,6,7,7,8,8,9,9,10,10], //149
                [1,2,3,3,4,4,4,5,5,6,6,6,7,7,8,8,9,9,10,10], //150

    익성비 확률은 2차원 배열

    자바스크립트는 arr[][]와 같은 선언이 안되니 주의

     

    const result = Array.from({length: 210}, () => 0);

    결과값을 저장할 배열은 기본 값을 0으로 초기화

     

     

    <button id = 'sh' onclick = 'calulate()' type="button">실행</button>
    function calulate(){
                check();
                if(error!=0){ return; }
                document.getElementById('sh').innerHTML = '추가실행';
                document.getElementById('res').innerHTML= ' ';
                document.getElementById('res2').innerHTML = ' ';

    실행 버튼에 onclick으로 calculate() 함수를 연결하고

    calculate 함수는 일단 에러 체크 함수를 호출, innerHtml 값들을 초기화해준다

    근데 함수 오타났었네

     function check(){
                error++;
                level= parseInt(document.getElementById('one').value);
                var level2= parseInt(document.getElementById('two').value);
                isbb = parseInt(document.getElementById('three').value);
                if( !level || !isbb ){
                    if(!level && !isbb){
                        document.getElementById("bbang").src = "error.jpg";
                        document.getElementById('err').innerHTML= '입력값이 없는데용';
                    }
                    
                    ~~~~
                    
                error=0;
                document.getElementById("bbang").src = "bread.jpg";
                document.getElementById('err').innerHTML= '';
                }

    체크 함수는 일단 전역변수 error값을 올리고 

    각 input의 입력값을 parseInt()로 int 체크,

    값이 존재하는지, 범위 안의 값인지 체크하고

    문제 없으면 다시 error 값을 0으로 되돌렸다, 

     

     

    다시 calculate 함수로 되돌아와서

                sum += 100000;
                for(var i=0 ; i<100000 ; i++){
                    level= parseInt(document.getElementById('one').value);
                    isbb = parseInt(document.getElementById('three').value);
                    
                    for(var j=0 ; j<isbb ; j++){
                        level = isb(level);
                        if(level==200)
                            break;
                    }
                    result[level]++;
                }

    총 시뮬 횟수 sum 값을 10만 늘리고

    10만번 연산을 수행,

    현재 레벨과 사용한 익성비 개수를 input으로 받아 level과 isbb 변수에 저장하고

    level에 isbb번 isb() 함수를 수행한다

    최대 레벨은 200이므로 200이 되면 break,

    그렇게 최종 레벨값에 해당하는 result 배열 값을 1 증가시킨다

     

     function isb(level){
                var num = Math.floor(Math.random()*20);
                var up = arr[level-141][num];
                return level+up;
            }

    익성비 함수는

    1부터 20 사이 랜덤한 값을 뽑아 arr[레벨][랜덤값]만큼 레벨에 더해준다

     

     

     

    또 다시 calculate 함수로 되돌아와서

    for(var i=141 ; i<=200 ; i++){
                    if(result[i]>maxx){
                        maxx = result[i];
                        maxindex=i;
                    }
                    if(i==curlev){
                        ssum1+=result[i];
                    }
                    if(i>curlev){
                        ssum1+=result[i];
                        ssum2+=result[i];
                    }
                    
                    avg+=result[i]*i;
                }
                for(var i=141 ; i<=200 ; i++){
                    mid+=result[i];
                    if(mid>(sum/2)){
                        mid = i;
                        break;
                    }
                }

    result[] 값이 가장 큰 인덱스 값을 찾아 최빈값을,

    각 결과값에 개수를 곱해 총합으로 나눠 평균값을,

    시행횟수에 절반보다 처음 커지는 인덱스를 구해 중간값도 구해주고

     

    최종 레벨보다 높은 경우는 ssum2,

    최종 레벨 이상의 경우는 ssum1에 저장해 백분율을 구한다

     

                ssum1=( (ssum1*100)/sum ).toFixed(2);
                ssum2=( (ssum2*100)/sum ).toFixed(2);
                avg = (avg/sum).toFixed(1);
                document.getElementById('res').innerHTML = "평균값: "+avg+"레벨\n"
                document.getElementById('res').innerHTML += "최빈값: "+maxindex+"레벨\n"
                document.getElementById('res').innerHTML += "중간값: "+mid+"레벨\n"
                if(curlev){
                    var at = Math.floor(ssum2)
                    document.getElementById('res').innerHTML += "\n당신의 운빨은 상위 "+ssum2+"% ~ "+ssum1+"%입니다.\n";
                    document.getElementById('res').innerHTML += "("+at+"%의 사람들이 같은 개수로 "+curlev+"보다 높은 레벨을 달성했습니다.)\n";
                }

    구한 값들을 to.Fixed(2)로 소수점 2자리만 남겨주고

    평균값 최빈값 중간값 백분율을 출력

     

                for(var i=200 ; i>140 ; i--){
                    if(result[i]!=0){
                        document.getElementById('res2').innerHTML += "\n"+i+" "+result[i];
                    }
                }

    마지막으로 10만번의 통계 수치를 출력해주면 끄읕

     

     

     

    for(var j=1 ; j<100 ; j++){
        level = isb(level);
        if(level>=level2){
             result[j]++;
             break;
        }
    }

    기대값 계산기는

    특정 레벨에 도달할때까지 isb() 함수를 호출,

    도달한 레벨이 아닌 isb() 함수를 호출한 횟수를 result 배열에 저장하고

    이에 따른 기대값을 출력해주면 끝!

    에러 체크같은것도 쪼금씩 바꿔주고.

     

     

     

    https://www.inven.co.kr/board/maple/2304/28859

     

    메이플스토리 인벤 : 익성비 몇개로 200 찍을 수 있을까? (레벨 구간별 기댓값 및 확률) - 메이플스

     

    www.inven.co.kr

    최종 결과물

    누가 익성비 기대값 엑셀로 정리한것과 거의 동일한 수치가 나왔다

    왠지모르게 자바스크립트는 좀 느리지 않을까 편견을 갖고있었는데

    10만번 수행정도는 바로돼서 다행이였다

     

     

     

     

     

     

     

    깃허브 io 링크

     

    백분율 계산기
    https://gillyongs.github.io/github.io/iksunbi/backbunyul

    기대값 계산기
    https://gillyongs.github.io/github.io/iksunbi/gidatgap

     

     

     

    깃허브 링크

    https://github.com/gillyongs/github.io/tree/main/iksunbi

     

    GitHub - gillyongs/github.io

    Contribute to gillyongs/github.io development by creating an account on GitHub.

    github.com

     

     

Designed by Tistory.