#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <math.h>
#define PRECISION 2.82e14 /* 2**48, rounded up */
double drand48(void)
{
double x = 0;
double denom = RAND_MAX + 1.;
double need;
for (need = PRECISION; need > 1; need /= (RAND_MAX + 1.))
{
x += rand() / denom;
denom *= RAND_MAX + 1.;
}
return x;
}
class item
{
private:
int quest;
int now;
int count;
int goal;
int star;
unsigned long long *sum;
int *fail;
int *dest;
int *chance;
int temp;
int starcat;
int sale;
int nodest;
int lev;
int limit;
int initial;
public:
~item();
void reset(int);
void inputdata(int);
void starforce();
void showresult();
};
void printcm(unsigned long long i)
{
char B[20];
sprintf(B, "%llu", i);
int count = 1;
int len = strlen(B);
while (count <= len)
{
printf("%c", B[count - 1]);
if (count == len)
break;
if ((len - count) % 3 == 0)
printf(",");
count++;
}
}
void printstar(int star, int limit)
{
int i;
for (i = 0; i < limit; i++)
{
if (i < star)
printf("★");
else
printf("☆");
if ((i + 1) % 5 == 0)
printf(" ");
}
printf("\n");
}
int meso(int star, int lev)
{
int grademeso = 0;
double temp = 0;
if (star >= 15) {
temp = pow(star + 1, 2.7) / 200.0;
}
else if (star >= 10) {
temp = pow(star + 1, 2.7) / 400.0;
}
else {
temp = (star + 1) / 25.0;
}
grademeso = floor((1000 + pow(lev, 3) * temp) / 100.0 + 0.5) * 100;
return grademeso;
}
unsigned long long aver(unsigned long long *array, int count)
{
unsigned long long aver = 0, sum = 0;
for (int i = 0; i < count; i++)
sum = sum + array[i];
aver = sum / count;
return aver;
}
double aver(int *array, int count)
{
double aver = 0, sum = 0;
for (int i = 0; i < count; i++)
sum = sum + array[i];
aver = sum / count;
return aver;
}
unsigned long long stddev(unsigned long long *array, unsigned long long aver, int count)
{
unsigned long long sum = 0, stddev = 0;
for (int i = 0; i < count; i++)
sum = sum + (array[i] - aver) * (array[i] - aver);
stddev = sqrt(sum / (count - 1));
return stddev;
}
void item::starforce()
{
int pmprob[25][2] = { { 95,0 },{ 90,0 },{ 85,0 },{ 85,0 },{ 80,0 },{ 75,0 },{ 70,0 },{ 65,0 },{ 60,0 },{ 55,0 },{ 45,0 },{ 35,0 },{ 30,1 },{ 30,2 },{ 30,2 },{ 30,3 },{ 30,3 },{ 30,3 },{ 30,3 },{ 30,3 },{ 30,10 },{ 30,10 },{ 3,20 },{ 2,30 },{ 1,40 } };
//확률을 백분율 수치로 저장
int Temp = 100;
double TEMP = 1;
if (starcat == 1 || starcat == 4500)
starcat = 4.5 * 1000; //백분율->십만분율 변환
else
starcat = 0;
int sucprob = 1000 * pmprob[star][0] + starcat; //백분율->십만분율 변환
int destprob = (100000 - sucprob) * (1000 * pmprob[star][1]) / 100000; //파괴확률=조건부 확률, 백분율->십만분율 변환
if (nodest == 1)
Temp = 12;
else if (nodest == 2)
Temp = 15;
if (sale == 1) //30퍼 세일
TEMP = 0.7;
if (temp == -2) //찬스타임
{
chance[now]++;
star++;
temp = 0;
sum[now] = sum[now] + TEMP * meso(star, lev);
return;
}
if (sale == 2 && star < 20 && star % 5 == 0) //100퍼 이벤
{
star++;
temp = 0;
sum[now] = sum[now] + TEMP * meso(star, lev);
return;
}
if (star >= Temp && star <= 16) //파괴방지
{
sum[now] = sum[now] + (1 + TEMP) * meso(star, lev);
destprob = 0;
}
else //일반적인 경우
sum[now] = sum[now] + TEMP * meso(star, lev);
int count, i;
int grade[100000];
for (count = 0; count < 100000; count++)
{
if (count < sucprob)
grade[count] = 1;
else if (count < sucprob + destprob)
grade[count] = -1;
else
grade[count] = 0;
}
// i = rand() % 100000;
i = drand48() * 100000;
if (grade[i] == 1) //성공
{
star++;
temp = 0;
}
else if (grade[i] == 0) //실패
{
if (star > 5 && star % 5)
{
star--;
temp--;
}
fail[now]++;
}
else if (grade[i] == -1) //파괴
{
star = 12;
printf("DESTROYED\n");
dest[now]++;
temp = 0;
}
}
item::~item()
{
delete[]sum;
delete[]dest;
delete[]chance;
delete[]fail;
}
void item::reset(int exit)
{
if (exit != 1)
{
lev = 0;
star = 0;
goal = 0;
starcat = 0;
sale = 0;
}
fail[now] = 0;
dest[now] = 0;
chance[now] = 0;
sum[now] = 0;
temp = 0;
}
void item::inputdata(int exit)
{
int num = 0;
now = 0;
if (exit != 1)
{
quest = 0;
count = 1;
}
while (exit != 1)
{
printf("단순 강화는 1, n회 강화 후 통계는 2를 누르세요.\n");
scanf("%d", &quest);
while (getchar() != '\n');
if (quest == 1 || quest == 2)
break;
printf("사용 목적을 다시 입력해주세요.\n");
}
if (quest == 2)
{
while (exit != 1)
{
printf("통계의 표본 수 : ");
scanf("%d", &count);
while (getchar() != '\n');
if (count >= 2)
break;
printf("표본 수를 다시 입력해주세요.\n");
}
}
chance = new int[count];
fail = new int[count];
dest = new int[count];
sum = new unsigned long long[count];
reset(exit);
while (exit != 1)
{
printf("강화 아이템 레벨 제한 : ");
scanf("%d", &lev);
while (getchar() != '\n');
if (lev >= 98 && lev <= 200)
break;
printf("레벨 제한을 다시 입력해주세요.\n");
}
if (lev >= 138)
limit = 25;
else if (lev >= 128)
limit = 20;
else if (lev >= 118)
limit = 15;
else if (lev >= 108)
limit = 10;
else if (lev >= 98)
limit = 8;
while (exit != 1)
{
printf("처음 강화 수치 : ");
scanf("%d", &initial);
while (getchar() != '\n');
if (initial >= 0 && initial <= limit)
break;
printf("강화수치를 다시 입력해주세요.\n");
}
while (exit != 1)
{
printf("목표 강화 수치 : ");
scanf("%d", &goal);
while (getchar() != '\n');
if (goal >= initial && goal <= limit)
break;
printf("강화수치를 다시 입력해주세요.\n");
}
if (exit != 1 && (goal > initial))
{
printf("스타캐치 전부 성공은 1, 전부 해제는 아무 키나 누르기\n");
scanf("%d", &starcat);
while (getchar() != '\n');
printf
("강화 비용 30퍼 할인 이벤트 적용은 1\n5, 10, 15성 성공 확률 100퍼센트 이벤트 적용은 2\n스타포스 이벤트 미적용은 아무 키나 누르기\n");
scanf("%d", &sale);
while (getchar() != '\n');
if (goal > 12)
{
printf
("12~17 파방은 1\n15~17 파방은 2\n파방 미적용은 아무 키나 누르기\n");
scanf("%d", &nodest);
while (getchar() != '\n');
}
}
while (now < count)
{
star = initial;
while (star < goal)
{
printf("강화 %d회", num);
if (temp == -2)
printf(", CHANCE TIME!");
else if (sale == 2 && star > 0 && star < 20 && star % 5 == 0)
printf(", 강화 성공 확률 100퍼센트!");
printf("\n");
printstar(star, limit);
num++;
starforce();
}
if (star == goal)
{
printf("강화 %d회, %d성까지 강화완료\n", num, goal);
printstar(star, limit);
printf("<표본 %d번째 완료>\n", now + 1);
}
now++;
if (quest == 2 && now != count)
{
reset(1);
num = 0;
}
}
}
void item::showresult()
{
if (quest == 1)
{
printf("소비 메소 : ");
printcm(sum[0]);
printf("메소\n");
printf("찬스 타임 : %d회\n", chance[0]);
printf("실패 횟수 : %d회\n", fail[0]);
printf("파괴 횟수 : %d회\n", dest[0]);
}
else if (quest == 2)
{
printf("소비 메소(평균) : ");
printcm(aver(sum, count));
printf("메소\n");
printf("소비 메소(표준 편차) : ");
printcm(stddev(sum, aver(sum, count), count));
printf("메소\n");
printf("찬스 타임(평균) : %f회\n", aver(chance, count));
printf("실패 횟수(평균) : %f회\n", aver(fail, count));
printf("파괴 횟수(평균) : %f회\n", aver(dest, count));
}
}
int main()
{
int exit = 2;
item ITEM;
printf("인소야닷컴 슈리튬\n");
printf("98제~200제 아이템 스타포스 시뮬\n");
srand(time(NULL));
while (1)
{
// system("title 일반템 스타포스 시뮬레이션");
// system("color 0F");
ITEM.inputdata(exit);
ITEM.showresult();
exit = 2;
printf
("설정 초기화+재시작은 0, 동일 설정+재시작은 1, 종료하려면 아무 키나 눌러주세요\n");
scanf("%d", &exit);
while (getchar() != '\n');
if (exit == 0 || exit == 1)
continue;
else
break;
}
system("pause");
return 0;
}