티스토리 뷰

안드로이드용 스타포스 역계산기의 v1.1.3이 배포되었습니다. 플레이스토어 링크


이전 버전과 변경점은 다음과 같습니다.

1. 140제 무기를 계산할 수 있습니다.

2. 역계산 알고리즘을 개선했습니다.


사실 중요한건 2번인데요, v1.1.2까지는 역계산이 아닌 계산 시뮬레이션에 의한 방법이였다면

이번 업데이트를 통해 온전히 역계산이 가능하게 되었습니다.


[v1.1.2와 현재도 사용하고 있는 스타포스 강화 메소드]

    private static int enchant200(int attack, int currentStars) {
        if (currentStars < 15)
            return attack + (attack / 50) + 1;

        switch (currentStars) {
            case 15:
            case 16:
                return attack + 13;
            case 17:
            case 18:
                return attack + 14;
            case 19:
                return attack + 15;
            case 20:
                return attack + 16;
            case 21:
                return attack + 17;
            default:
                return -1;
        }
    }

지금까지는 이 메소드를 이용하여 미리 산정된 무기+예상 작을 현재 스타포스 수치까지 계산하여 비교하는 방법을 취했는데, 이로 인해 많은 연산을 필요로 했습니다.


이전 포스트에서도 올렸듯 15성 미만까지 스타포스로 강화되는 수치는 다음과 같습니다.

A n+1 = An + (An / 50) + 1

Java에서 정수계산시 결과는 소수점을 버린 정수만 나오므로 An/50은 50으로 나눈 몫만 나올 뿐 나머지가 상관없으니 좋은 방법이였습니다.


하지만 역계산의 경우 다음의 예를 들겠습니다.

무기의 5성 강화 후 공격력 = 4성 때의 공격력 + 50으로 나눈 몫 + 1

55 : 53 + 1 + 1 

54 : 52 + 1 + 1

53 : 51 + 1 + 1

52 : 50 + 1 + 1

51 : ? + ? + 1 // 존재할 수 없음

50 : 49 + 0 + 1

49 : 48 + 0 + 1

이렇게 존재할 수 없는 공격력들이 51주기로 존재합니다.

사실 이 문제는 역계산에서는 이미 나온 결과를 이용하므로 존재할 수 없는 공격력은 문제가 되지 않습니다.

강화시 존재할 수 없는 공격력은 반드시 피하게 되어있거든요.


하지만 저기서 52일 때와 50일 때, 둘 모두 나눴을 때의 몫이 1이지만 50이 되었을 때는 49에서 더해진 것이므로 50으로 나눈 몫에 대한 추가 공격력이 적용되지 않습니다. 이로 인해 경계점에 있는 공격력 수치는 한 번의 과정을 더 거쳐야합니다.

    private static int reverseCommon(int attack) {
        int decrease = attack / 50;
        int decreased = attack - decrease;
        if (decreased % 50 != 0 && decrease > decreased / 50)
            decrease--;

        return attack - decrease - 1;
    }

먼저 50으로 나눈 몫을 먼저 구하고(decrease) 현재 공격력에서 뺍니다(decreased).

이 때 뺀 값이 경계점보다 작은 값이면 그 작은 값의 50으로 나눈 몫으로 대체해야합니다 (decrease--).

일반적인 경우에서 15성 미만에서 공격력을 50으로 나눈 몫에 의한 추가 공격력은 50보다 크지 않으므로 decrease에서 1만 빼는 것으로 간단하게 구현할 수 있습니다.

하지만 한가지 문제가 더 있습니다. 뺀 값(decreased)가 50으로 나눴을 때 맞아 떨어진다면, 즉, 나머지가 0이라면 다시 경계점보다 작은 값이라고 판단할 수 있기 때문입니다.

이로 인해 50으로 나눴을 때의 나머지가 0이 아닌지 다시 한 번 확인한 다음 decrease를 1만큼 뺍니다.


이렇게 나온 decrease로 현재 공격력에서 decrease를 빼고 1만큼 뺀 방법으로 역계산을 구현할 수 있었습니다.

15성 이상에서는 정말 계산의 거꾸로면 되고요.


이를 이용한 알고리즘 개선은 다음과 같습니다.

v1.1.2 이전)

(기본 공격력 + 100% * 강화 회수)의 n성 강화 결과

(기본 공격력 + 70% * 강화 회수)의 n성 강화 결과

...

추산 후 맞아 떨어지는 조건이 있는지 비교

조건이 없다면 강화가 섞인 것이므로

{기본 공격력 + 100% * (강화 회수 - 섞인 회수) + 70% * 섞인 회수)의 n성 강화 결과

부터 비교 시작하는 방법으로 반드시 n성까지 강화 결과를 구해야만 비교할 수 있습니다.


v1.1.3 이후)

현재 무기의 스타포스 이전 값 구함

스타포스 이전 값 + 100% * 강화 회수

스타포스 이전 값 + 70% * 강화 회수

...

추산 후 맞아 떨어지는 조건이 있는지 비교

조건이 없다면 강화가 섞인 것이므로

현재 공격력 + 100% * (강화 회수 - 섞인 회수) + 70% * 섞인 회수

부터 비교를 시작합니다.

이제 n성까지의 추가 연산이 필요하지 않으므로 더 빠른 연산을 할 수 있게 되었습니다.



물론 비교는 매지컬 작도 있으므로 현실적인 결과 계산을 위하여 거꾸로 합니다.

스타포스 이전 값 + 매지컬 11 * 강화 회수

스타포스 이전 값 + 매지컬 10 * 강화 회수 and so on



??? : 솔직히 차이 모르겠는데요.


네 두 연산 결과 모두 0ms이내에 끝납니다.

아시는 분도 계시겠지만 연산 과정 중 UX에 나쁘단 이유로 Deprecated 판정까지 받은 ProgressDialog로 기다리라고 나오는 기능도 있습니다. 너무 빨리 사라질 뿐이죠.


그치만 개발자가 먹고 사는게 이런걸로 먹고사는건데, 당연히 같은 결과에 더 빠른 방법이 있다면 이 방법으로 하는 것이 맞을 것입니다. 게임하는 사람으로써도 그 중요한 최적화를 할 수 있다면 안 할 이유는 없겠죠.




이상 릴리즈 노트? 강좌?를 마치겠습니다.

이후 더 낮은 레벨 제한의 무기들을 추가할 계획입니다.



댓글
댓글쓰기 폼