fork download
  1. # include <cmath>
  2. # include <cstdio>
  3. # include <iostream>
  4. using namespace std ;
  5. typedef double Float ;
  6. typedef long long Int ;
  7.  
  8.  
  9. // Set initial data
  10. # define Character_InitialLevel 1
  11. # define Character_InitialTotalXp 0
  12. # define Challenge_InitialExpectedXpReward 10
  13.  
  14. // Set equation to solve (find challenge relative power expoent in xp reward formula)
  15. Float Equation_LeftSide( Float XpRewardFormula_ChallengeRelativePower_Expoent ){
  16. return XpRewardFormula_ChallengeRelativePower_Expoent ;
  17. }
  18. Float Equation_RightSide( Float XpRewardFormula_ChallengeRelativePower_Expoent ){
  19. return 1 ;
  20. }
  21.  
  22. // Set character total xp rounding method
  23. # define Rounding_MinimalDigits(Character_LevelUpXp) 0 /* integer with no rounded integer digit */
  24. # define Rounding_MaximalDigits(Character_LevelUpXp) log10(Character_LevelUpXp)-1.4 /* modify less than 2% */
  25.  
  26. // Set table with cells data {
  27. // Challenge Expected Relative Power ,
  28. // Character Expected Rewards To Level Up ,
  29. // Expected Xp Reward Bonus (%)
  30. // } at Character_InitialLevel, Character_InitialLevel+1, ..., Character_FinalLevel-2 and Character_FinalLevel-1
  31. const Float LevelInputData[][3] = {
  32. { 1.00000 , 1.0 , 0.0 } ,
  33. { 2.48832 , 5.0 , 0.0 } ,
  34. { 5.37824 , 20.0 , 0.0 } ,
  35. { 10.48576 , 60.0 , 5.0 } ,
  36. { 18.89568 , 120.0 , 10.0 } ,
  37. { 32.00000 , 180.0 , 15.0 } ,
  38. { 51.53632 , 240.0 , 20.0 } ,
  39. { 79.62624 , 300.0 , 25.0 } ,
  40. { 118.81376 , 300.0 , 25.0 }
  41. } ;
  42.  
  43.  
  44.  
  45. # define LevelUps Int( sizeof(LevelInputData) / sizeof(*LevelInputData) )
  46. Float RoundLevelUp( const Float *TotalXp , Float *Factors , Int Index , Int RoundIndex=0 , Int Factor=1 ){
  47. Index = min(max(Index,0LL),LevelUps-1) ;
  48. Float Temporary1 = ( Index == RoundIndex ?
  49. Factors[ Index ]*Factor : Factors[ Index ] ) ;
  50. Temporary1 = round( TotalXp[ Index++ ]/Temporary1 )*Temporary1 ;
  51. Float Temporary2 = ( Index == RoundIndex ?
  52. Factors[ Index ]*Factor : Factors[ Index ] ) ;
  53. return round( TotalXp[ Index ]/Temporary2 )*Temporary2 - Temporary1 ;
  54. }
  55. Int Character_FinalLevel = Character_InitialLevel + LevelUps ;
  56. struct SolutionData {
  57. Float XpRewardFormula_ChallengeRelativePower_Expoent , XpRewardFormula_Factor ;
  58. Float Challenge_ExpectedXpReward[ LevelUps ] ;
  59. Float Character_LevelUpXp[ 1 + LevelUps ] , Character_TotalXp[ 1 + LevelUps ] ;
  60. SolutionData( Float Expoent ){
  61. Character_LevelUpXp[ LevelUps ] = 1e400 ;
  62. XpRewardFormula_ChallengeRelativePower_Expoent = Expoent ;
  63. XpRewardFormula_Factor = Challenge_InitialExpectedXpReward ;
  64. XpRewardFormula_Factor /= ( 100+LevelInputData[0][2] )*pow( LevelInputData[0][0] , Expoent ) ;
  65. Character_TotalXp[ 0 ] = Character_InitialTotalXp ;
  66. for( Int Index=0 ; Index < LevelUps ; Index++ ){
  67. Challenge_ExpectedXpReward[ Index ] = XpRewardFormula_Factor ;
  68. Challenge_ExpectedXpReward[ Index ] *= 100+LevelInputData[ Index ][2] ;
  69. Challenge_ExpectedXpReward[ Index ] *= pow( LevelInputData[ Index ][0] , Expoent ) ;
  70. Character_TotalXp[ Index+1 ] = LevelInputData[ Index ][1]*Challenge_ExpectedXpReward[ Index ] ;
  71. Character_TotalXp[ Index+1 ] += Character_TotalXp[ Index ] ;
  72. Character_LevelUpXp[ Index ] = Character_TotalXp[ Index+1 ]-Character_TotalXp[ Index ] ;
  73. }
  74. }
  75. } ;
  76. int main() {
  77. Float RoundingFactors[ LevelUps + 1 ] , MaximalRoundingFactors[ LevelUps + 1 ] ;
  78. for( Int Index=1 ; Index < sizeof(LevelInputData)/sizeof(*LevelInputData) ; Index++ ){
  79. if( LevelInputData[Index-1][0] > LevelInputData[Index][0] ){
  80. if( LevelInputData[Index-1][1] > LevelInputData[Index][1] ){
  81. cout << "Warning: challenge mean relative power and character" ;
  82. cout << " expected rewards to level up decreases.\n Level " ;
  83. cout << (Character_InitialLevel+Index-1) << " --> " ;
  84. cout << (Character_InitialLevel+Index) << "\n CMRPW " ;
  85. cout << LevelInputData[Index-1][0] << " --> " ;
  86. cout << LevelInputData[Index][0] << "\n CERLU " ;
  87. cout << LevelInputData[Index-1][1] << " --> " << LevelInputData[Index][1] << "\n\n" ;
  88. } else {
  89. cout << "Warning: challenge mean relative power decreases.\n Level " ;
  90. cout << (Character_InitialLevel+Index-1) << " --> " ;
  91. cout << (Character_InitialLevel+Index) << "\n CMRPW " ;
  92. cout << LevelInputData[Index-1][0] << " --> " << LevelInputData[Index][0] << "\n\n" ;
  93. }
  94. } else if( LevelInputData[Index-1][1] > LevelInputData[Index][1] ){
  95. cout << "Warning: character expected rewards to level up decreases.\n Level " ;
  96. cout << (Character_InitialLevel+Index-1) << " --> " ;
  97. cout << (Character_InitialLevel+Index) << "\n CERLU " ;
  98. cout << LevelInputData[Index-1][1] << " --> " << LevelInputData[Index][1] << "\n\n" ;
  99. }
  100. }
  101. cout << "Initial Level = " << Character_InitialLevel << "\nFinal Level = " ;
  102. cout << Character_FinalLevel << "\nExpected Xp Reward = " ;
  103.  
  104.  
  105.  
  106. // Solve Equation (continue...)
  107. SolutionData Solution=1 ;
  108.  
  109.  
  110.  
  111. if(!( abs(Solution.XpRewardFormula_Factor-1) < 1e-13 )){
  112. cout << Solution.XpRewardFormula_Factor << '*' ;
  113. }
  114. cout << "( 100 + Xp Reward Bonus Percent )*( Challenge Relative Power" ;
  115. if( Solution.XpRewardFormula_ChallengeRelativePower_Expoent != 1 ){
  116. cout << " ^ " << Solution.XpRewardFormula_ChallengeRelativePower_Expoent ;
  117. }
  118. cout << " )\nCharacter Total Xp = " ;
  119. for( Int Index=0 ; Index <= LevelUps ; Index++ ){
  120. Float Temporary1 = Solution.Character_LevelUpXp[ max(Index,1LL)-1 ] ;
  121. Temporary1 = round(pow(10, Rounding_MinimalDigits( Temporary1 ) )) ;
  122. Float Temporary2 = Solution.Character_LevelUpXp[ max(Index,1LL)-1 ] ;
  123. Temporary2 = round(pow(10, Rounding_MaximalDigits( Temporary2 ) )) ;
  124. RoundingFactors[ Index ] = ( Temporary1 > 1 ? Temporary1 : 1 ) ;
  125. MaximalRoundingFactors[ Index ] = ( Temporary2 > Temporary1 ? Temporary2 : Temporary1 ) ;
  126. }
  127. for( Float RoundingFactor_Factor=19 ; (RoundingFactor_Factor=Int(RoundingFactor_Factor*0.6)-1) ; ){
  128. bool DidRound ;
  129. do {
  130. DidRound = false ;
  131. for( Int Index=0 ; Index <= LevelUps ; Index++ ){
  132. if(!( RoundingFactors[ Index ]*RoundingFactor_Factor <= MaximalRoundingFactors[ Index ] ))
  133. continue ;
  134. Float RluXp_Pre0 = RoundLevelUp( Solution.Character_TotalXp , RoundingFactors , Index-3 ) ;
  135. Float RluXp_Pos0 = RoundLevelUp( Solution.Character_TotalXp ,
  136. RoundingFactors , Index-3 , Index , RoundingFactor_Factor ) ;
  137. if( (!(RluXp_Pos0 > 0)) && (RluXp_Pre0 > 0) ) continue ;
  138. Float RluXp_Pre1 = RoundLevelUp( Solution.Character_TotalXp , RoundingFactors , Index-2 ) ;
  139. Float RluXp_Pos1 = RoundLevelUp( Solution.Character_TotalXp ,
  140. RoundingFactors , Index-2 , Index , RoundingFactor_Factor ) ;
  141. if( (!(RluXp_Pos1 > RluXp_Pos0)) && (RluXp_Pre1 > RluXp_Pre0) ) continue ;
  142. if( (!(RluXp_Pos1 >= RluXp_Pos0)) && (RluXp_Pre1 >= RluXp_Pre0) ) continue ;
  143. Float RluXp_Pre2 = RoundLevelUp( Solution.Character_TotalXp , RoundingFactors , Index-1 ) ;
  144. Float RluXp_Pos2 = RoundLevelUp( Solution.Character_TotalXp ,
  145. RoundingFactors , Index-1 , Index , RoundingFactor_Factor ) ;
  146. if( (!(RluXp_Pos2 > RluXp_Pos1)) && (RluXp_Pre2 > RluXp_Pre1) ) continue ;
  147. if( (!(RluXp_Pos2 >= RluXp_Pos1)) && (RluXp_Pre2 >= RluXp_Pre1) ) continue ;
  148. Float RluXp_Pre3 = RoundLevelUp( Solution.Character_TotalXp , RoundingFactors , Index ) ;
  149. Float RluXp_Pos3 = RoundLevelUp( Solution.Character_TotalXp ,
  150. RoundingFactors , Index , Index , RoundingFactor_Factor ) ;
  151. if( (!(RluXp_Pos3 > RluXp_Pos2)) && (RluXp_Pre3 > RluXp_Pre2) ) continue ;
  152. if( (!(RluXp_Pos3 >= RluXp_Pos2)) && (RluXp_Pre3 >= RluXp_Pre2) ) continue ;
  153. Float RluXp_Pre4 = RoundLevelUp( Solution.Character_TotalXp , RoundingFactors , Index+1 ) ;
  154. Float RluXp_Pos4 = RoundLevelUp( Solution.Character_TotalXp ,
  155. RoundingFactors , Index+1 , Index , RoundingFactor_Factor ) ;
  156. if( (!(RluXp_Pos4 > RluXp_Pos3)) && (RluXp_Pre4 > RluXp_Pre3) ) continue ;
  157. if( (!(RluXp_Pos4 >= RluXp_Pos3)) && (RluXp_Pre4 >= RluXp_Pre3) ) continue ;
  158. Float RluXp_Pre5 = RoundLevelUp( Solution.Character_TotalXp , RoundingFactors , Index+2 ) ;
  159. Float RluXp_Pos5 = RoundLevelUp( Solution.Character_TotalXp ,
  160. RoundingFactors , Index+2 , Index , RoundingFactor_Factor ) ;
  161. if( (!(RluXp_Pos5 > RluXp_Pos4)) && (RluXp_Pre5 > RluXp_Pre4) ) continue ;
  162. if( (!(RluXp_Pos5 >= RluXp_Pos4)) && (RluXp_Pre5 >= RluXp_Pre4) ) continue ;
  163. RoundingFactors[ Index ] *= RoundingFactor_Factor ;
  164. DidRound = true ;
  165. }
  166. } while( DidRound ) ;
  167. }
  168. for( Int Index=0 ; Index <= LevelUps ; Index++ ){
  169. Solution.Character_TotalXp[ Index ] /= RoundingFactors[ Index ] ;
  170. Solution.Character_TotalXp[ Index ] = round( Solution.Character_TotalXp[ Index ] ) ;
  171. Solution.Character_TotalXp[ Index ] *= RoundingFactors[ Index ] ;
  172. }
  173. for( Int Index=0 ; Index < LevelUps ; Index++ ){
  174. printf( "%.0lf, " , Solution.Character_TotalXp[ Index ] ) ;
  175. Solution.Character_LevelUpXp[ Index ] = Solution.Character_TotalXp[ Index+1 ] ;
  176. Solution.Character_LevelUpXp[ Index ] -= Solution.Character_TotalXp[ Index ] ;
  177. }
  178. printf( "%.0lf\n\n" , Solution.Character_TotalXp[ LevelUps ] ) ;
  179. cout << "Level TotalXp LevelUpXp " ;
  180. cout << "LevelUpXpGrow ExXpRew ExRewToLvUp" ;
  181. for( Int Index=0 ; Index <= LevelUps ; Index++ ){
  182. printf( "\n%5llu %18.0lf" , Character_InitialLevel+Index , Solution.Character_TotalXp[ Index ] ) ;
  183. printf( " %18.0lf" , Solution.Character_LevelUpXp[ Index ] ) ;
  184. if( Index != LevelUps ){
  185. Float Character_LevelUpXp = Solution.Character_LevelUpXp[ Index ] ;
  186. printf( " %+17.2lf%%" , 100*Solution.Character_LevelUpXp[ Index+1 ]/Character_LevelUpXp-100 ) ;
  187. printf( " %18.2lf" , Solution.Challenge_ExpectedXpReward[ Index ] ) ;
  188. printf( " %18.2lf" , Character_LevelUpXp/Solution.Challenge_ExpectedXpReward[ Index ] ) ;
  189. }
  190. }
  191. return 0 ;
  192. }
Success #stdin #stdout 0s 4532KB
stdin
Standard input is empty
stdout
Initial Level = 1
Final Level = 10
Expected Xp Reward = 0.1*( 100 + Xp Reward Bonus Percent )*( Challenge Relative Power )
Character Total Xp = 0, 10, 135, 1200, 7800, 33000, 98000, 245000, 550000, 990000

Level            TotalXp          LevelUpXp      LevelUpXpGrow            ExXpRew        ExRewToLvUp
    1                  0                 10          +1150.00%              10.00               1.00
    2                 10                125           +752.00%              24.88               5.02
    3                135               1065           +519.72%              53.78              19.80
    4               1200               6600           +281.82%             110.10              59.95
    5               7800              25200           +157.94%             207.85             121.24
    6              33000              65000           +126.15%             368.00             176.63
    7              98000             147000           +107.48%             618.44             237.70
    8             245000             305000            +44.26%             995.33             306.43
    9             550000             440000              +inf%            1485.17             296.26
   10             990000                inf