#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;
}

'C,C++ 코드' 카테고리의 다른 글

간단한 iterator 적용 문제  (0) 2019.01.02
single linked list  (0) 2018.12.25
하노이 탑 코드  (0) 2018.12.23
인라인 코드 테스트  (2) 2018.12.22
진자 운동 코드  (0) 2018.12.22
Posted by Semi Developer

블로그 이미지
C++ 코드 저장용도
Semi Developer

태그목록

Yesterday
Today
Total

달력

 « |  » 2024.5
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

최근에 올라온 글

최근에 달린 댓글

글 보관함