#include <stdio.h>
#include <random>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>
#include <math.h>
#include <conio.h>
//
#define xS 1
#define xE 76
#define yS 1
#define yE 15
#define deviation 1.0/3.0
#define crlf(n) for(crlf=0;crlf<n;crlf++){ printf("\n      "); }
       int crlf;
#define cls() system("cls")
#define delay(s) Sleep(s*600)
#define half(n) floor(n+0.5)
//
int nominus (int n) { if(n<0){ n=0; } return n; }
typedef enum { NOCURSOR, SOLIDCURSOR, NORMALCURSOR } CURSOR_TYPE;
//
void setcursortype(CURSOR_TYPE c);
void gotoxy(int x, int y);
void uninput();
void printfline(int n);
void gauge_status();
void gauge_hunt();
 void gauge_hp(int n);
 void gauge_expe(int n);
 void gauge_hp_enm(int n);
void level_up ();
void move();
void event();
void slt_stat();
void slt_rest();
void hunt();
 void win();
 void lose();
 void surrender();
 void attack_me();
 void attack_anm();
void background (int b);
 void background_town();
 void background_forest();
void hunt_background(int b);
 void hunt_forest();
//
int brk;

struct tag_st { int hp; int hp_max; int att; int arm; double crt; int expe; int level; int point; };
tag_st st = { 50, 50, 10, 0, 8.0, 0, 1, 0 };

struct tag_loc {int x; int y;};
tag_loc loc = {35,10};

struct tag_anm { int hp; int hp_max; int att; int arm; int expe; int level; char name[20]; };
tag_anm anm = { 0, 0, 0, 0, 0, 0, "-" };

enum tag_func {이동, 휴식, 단련, 상점} func;

struct tag_portal {int x; int y; int loc; int xf; int yf; tag_func func;} ;
tag_portal portal[8] ;

int expe_up=15;
int expe_prev=0;
int location;
//


void main()
{
 setcursortype(NOCURSOR);
 location=1;
 
 while(1){  
     delay(1);
     cls();

        background(location);
     gauge_status();

     gotoxy(loc.x, loc.y);
     printf("®");
      
     int ran;
     while(1)
     {  move(); event(); if(brk==1){ brk=0; break; } }
    }
} //

void event()
{
  int i;
  for(i=0; i<4; i++)
  { if(portal[i].x==loc.x && portal[i].y==loc.y){ location=portal[i].loc;
                  loc.x=portal[i].xf; loc.y=portal[i].yf;

                  switch(portal[i].func){  case 이동: break;
                                   case 휴식: slt_rest(); break;
                          case 단련: slt_stat(); break;
                          case 상점: break;           
                          default   : break; }
                  brk=1; }
  }

  int ran;
     srand((unsigned)time(NULL)); ran=rand();
     if(location!=1&&ran==0) { hunt_background(location); brk=1; }
}


void background(int location)
{
 switch(location){ case 1: background_town(); break;
           case 2: background_forest(); break;
          default: break;
        }
}
 void background_town()
{
 gotoxy(1,1);
 printf("⑴");

 gotoxy(76,1);
 printf("⑵");

 gotoxy(1,15);
 printf("⑶");

 gotoxy(76,15);
 printf("⑷");

 portal[0].x = 1; portal[0].y = 1; portal[0].loc=2; portal[0].xf=74; portal[0].yf=3; portal[0].func=이동;
 portal[1].x =76; portal[1].y =1; portal[1].loc=1; portal[1].xf=74, portal[1].yf=3; portal[1].func=단련;
 portal[2].x =1; portal[2].y =15; portal[2].loc=1; portal[2].xf=3, portal[2].yf=13; portal[2].func=휴식;
 portal[3].x =76; portal[3].y =15; portal[3].loc=1; portal[3].xf=74, portal[3].yf=13; portal[3].func=상점;


 gotoxy(68,18);
 printf(" <map> ");
 gotoxy(68,20);
 printf("⑴사냥");
 gotoxy(68,21);
 printf("⑵단련");
 gotoxy(68,22);
 printf("⑶여관");
 gotoxy(68,23);
 printf("⑷상점");

}
 void background_forest()
 {

 gotoxy(1,1);
 printf("⑴");

 gotoxy(76,1);
 printf("⑵");

 gotoxy(1,15);
 printf("⑶");

 gotoxy(76,15);
 printf("⑷");

 //portal[0].x = 1; portal[0].y = 1; portal[0].loc=2; portal[0].xf=75; portal[0].yf=2; portal[0].func=이동;
 portal[1].x =76; portal[1].y =1; portal[1].loc=1; portal[1].xf=3, portal[1].yf=3; portal[1].func=이동;
 //portal[2].x =1; portal[2].y =15; portal[2].loc=1; portal[2].xf=2, portal[2].yf=14; portal[2].func=이동;
 //portal[3].x =76; portal[3].y =15; portal[3].loc=1; portal[3].xf=75, portal[3].yf=14; portal[3].func=이동;


 gotoxy(68,18);
 printf(" <map> ");
 gotoxy(68,20);
 printf("⑴숲2");
 gotoxy(68,21);
 printf("⑵마을");
 gotoxy(68,22);
 printf("⑶숲3");
 gotoxy(68,23);
 printf("⑷숲4");
 
 }

void hunt_background(int location)
{
 switch(location) { case 1: break;
        case 2: hunt_forest(); break;
        default: break;
         }
}
 void hunt_forest()
{
 delay(1);

 int ran;
 srand((unsigned)time(NULL));
 ran=rand()%6+1;
 switch(ran){  case 1 : cls(); crlf(4); printf("사슴이 나타났습니다.");
         anm.hp_max=30; anm.hp=30; anm.att=8; anm.arm=0; anm.expe=4; anm.level=0; strcpy(anm.name,"사슴");
         hunt();

         break;
      case 2 : cls(); crlf(4); printf("살쾡이가 나타났습니다.");
         anm.hp_max=35; anm.hp=35; anm.att=10; anm.arm=1; anm.expe=6; anm.level=1; strcpy(anm.name,"살쾡이");
         hunt();
         break;
      case 3 : cls(); crlf(4); printf("원숭이가 나타났습니다.");
         anm.hp_max=35; anm.hp=35; anm.att=8; anm.arm=2; anm.expe=6; anm.level=1; strcpy(anm.name,"원숭이");
         hunt();
         break;
      case 4 : cls(); crlf(4); printf("올빼미가 나타났습니다.");
         anm.hp_max=25; anm.hp=25; anm.att=12; anm.arm=3; anm.expe=6; anm.level=1; strcpy(anm.name,"올빼미");
         hunt();
         break;
      case 5 : cls(); crlf(4); printf("매가 나타났습니다.");
           anm.hp_max=30; anm.hp=30; anm.att=16; anm.arm=3; anm.expe=7; anm.level=2; strcpy(anm.name,"매");
         hunt();
         break;
      case 6 : cls(); crlf(4); printf("들개가 나타났습니다.");
           anm.hp_max=40; anm.hp=40; anm.att=12; anm.arm=2; anm.expe=8; anm.level=2; strcpy(anm.name,"들개");
         hunt();
         break;
         default: break; 
      }  
}

void move()
{
 if(kbhit())
 {
  char key;
  key = getch();
 
  gotoxy(loc.x, loc.y);
  printf(" ");

  switch(key){ case 77: loc.x += 2; break;
        case 75: loc.x -= 2; break;
        case 80: loc.y += 1; break;
        case 72: loc.y -= 1; break;
        default: break;
        }

  if(loc.x<xS){ loc.x=xS; }
  if(loc.x>xE){ loc.x=xE; }
  if(loc.y<yS){ loc.y=yS; }
  if(loc.y>yE){ loc.y=yE; }

  gotoxy(loc.x,loc.y);
  printf("®");

  Sleep(70);
 }

} //
void level_up ()
{ if(st.expe>=expe_up){ delay(2);
            crlf(3);

         printf("레벨이 올랐습니다. <LV = %d>", ++st.level);
         st.hp += 0;
         st.hp = st.hp_max;
         st.att += 0;
         st.point += 2;

      gauge_hunt();

      expe_prev = expe_up;

           switch(st.level){ case 2: expe_up=30;   break;
                case 3: expe_up=50;   break;
               case 4: expe_up=70;   break;
               case 5: expe_up=100;   break;
            case 6: expe_up=150;  break;
            case 7: expe_up=200;   break;
            case 8: expe_up=300;   break;
            case 9: expe_up=400;   break;
               default: break;
                }
         delay(1);
       }
}  //

void gauge_status ()
{
  gotoxy(6,19);
  printf("HP  =/=", st.hp, st.hp_max);
  
  gotoxy(6 ,20);
  gauge_hp(12);

  gotoxy(36,19);
  printf("EXP  =/=       LV -", st.expe, expe_up, st.level);
  
  gotoxy(36 ,20);
  gauge_expe(12);

  gotoxy(8,23);
  printf("ATT: =", st.att);
  gotoxy(22,23);
  printf("DEF: =", st.arm);
  gotoxy(36,23);
  printf("CRI: %3.1lf", st.crt);
  gotoxy(50,23);
  printf("STAT: -",st.point);

  printfline(17);
  printfline(24);
}
void gauge_hunt()
{

  gotoxy(40,2);
  printf("<LV: ->  %-4s \t HP:M/M", st.level, "나", st.hp, st.hp_max);
  
  gotoxy(40,3);
  gauge_hp(18);
  crlf(2);
  
  gotoxy(40,5);
  printf("<LV: ->  %-4s \t HP:M/M", anm.level, anm.name, anm.hp, anm.hp_max);
  crlf(1);

  gotoxy(40,6);
  gauge_hp_enm(18);

} //
 void gauge_hp (int n)
{

 int gauge;
 gauge = half(n*(double(st.hp)/double(st.hp_max))) ;

 int i;
 for(i=0;i<gauge;i++){ printf("■"); }
 for(i=0;i<n-gauge;i++){ printf("□"); }

}
 void gauge_hp_enm (int n)
{

 int gauge;
 gauge = half(n*(double(anm.hp)/double(anm.hp_max))) ;

 int i;
 for(i=0;i<gauge;i++){ printf("■"); }
 for(i=0;i<n-gauge;i++){ printf("□"); }

}
 void gauge_expe (int n)
{

 int gauge;
 gauge = half(n*((double(st.expe)-double(expe_prev))/(double(expe_up)-double(expe_prev)))) ;

 int i;
 for(i=0;i<gauge;i++){ printf("■"); }
 for(i=0;i<n-gauge;i++){ printf("□"); }

}

void slt_stat()
{
 do{ 

  delay(1);
  cls();
  crlf(4);

  gauge_status();

  gotoxy(6,4);
  printf("무엇을 단련하시겠습니까? (1.체력 2.타격 3.방어 4.암살 5.나가기)");
  crlf(2);

  uninput();
  char slt_stat;
  slt_stat = getch();
  delay(1);
  crlf(4);

  if(slt_stat=='5') break;
  if(st.point==0){ printf("능력치가 없습니다."); delay(1); break; }

  switch(slt_stat){ case '1': printf("체력을 단련했습니다.");
          st.point -= 1;
          st.hp_max += 5;
          st.hp += 5;
          break;
          case '2': printf("타격을 단련했습니다.");
          st.point -= 1;
          st.att += 1;
          break;
        case '3': printf("방어를 단련했습니다.");
          st.point -= 1;
          st.arm += 1;
          break;
        case '4': printf("암살을 단련했습니다.");
          st.point -= 1;
          st.crt += 0.8;
          break;
        default  : break;
      }
  delay(1);
 } while(1>0);
}  // 함수 끝
void slt_rest()
{
 int exp_rest;
 exp_rest = half((1-(double(st.hp)/double(st.hp_max))) * (double(st.expe)*0.05));
 delay(1);
 crlf(4);

 gotoxy(20,15);
 printf("휴식을 취했습니다. <HP 100%%>, <경험치 -%d>", exp_rest);
 st.expe -= exp_rest ;
 st.hp = st.hp_max ;

 delay(4);
}

void hunt()
{  
 enum {you, anemy} turn;
 turn = you ;

 delay(3);

 while(1){
    cls();

    gauge_hunt();
    crlf(1);

    delay(3);

    win(); if(brk==1){ brk=0; break; }
    lose(); if(brk==1){ brk=0; break; }
   
 
    if(turn==you){ gotoxy(6,4);
          printf("당신의 차례입니다.");
          crlf(2);
          printf("<1.공격 2.도망> "); 
      
          uninput();

          char select;
             select = getch();
  

          if(select=='2'){  surrender();
                 if(brk==1){ brk=0; break; }
                 else { turn=anemy; continue; }
                 }
          if(select=='1'){ attack_me(); }
          else continue;


        delay(2);
       
          turn = anemy;
          continue;
          }

    if(turn==anemy){ gotoxy(6,4);
         printf("%s의 차례입니다.", anm.name); 
       
         delay(2);
        
            attack_anm();
         
            delay(2);
      
            turn = you;
            continue;
          } 
   }

}  //    
 void win ()
{
 if(anm.hp<=0){  gotoxy(6,4);
     printf("%s을(를) 잡았습니다.", anm.name);
     crlf(2);
     
     printf("<경험치 %d 획득>", anm.expe);
     st.expe += anm.expe ;

     level_up();

     delay(3);
     gotoxy(6,10);

     crlf(3);
     printf("마을로 돌아갑니다.");
     delay(2);

     brk=1;
      }
}
 void lose ()
{
 if(st.hp<=0){  gotoxy(6,4);
       printf("%s에게 죽었습니다.", anm.name );
       crlf(2);

       printf("<경험치 -%d>", int(half(double(st.expe)*0.2)));
       st.expe -= half(double(st.expe)*0.2) ;
       if(st.expe<0){ st.expe=0; }

       delay(3);
       crlf(4);

       printf("10초 후 마을에서 부활합니다.");
       st.hp=1;
       delay(10);

       brk=1;
    }
}
 void surrender ()
{
 int surren;
 srand((unsigned)time(NULL));
    surren = rand()%2 ;

 if(surren==1){ delay(2);
       cls();

       gotoxy(6,4);
       printf("도망에 성공했습니다.");
       crlf(2);

       printf("<경험치 -%d>", int(half(double(st.expe)*0.1))); 
       st.expe -= half(double(st.expe)*0.1) ;
          if(st.expe<0){ st.expe=0; }

       delay(3);
       crlf(4);

       printf("마을로 돌아갑니다.");
       delay(2);
       brk=1;
    }

 if(surren==0){ delay(2);
       cls();
       gotoxy(6,4);

       printf("도망에 실패했습니다.");
          delay(3);
              }
}
 void attack_me()
{
 
 int damage;
 srand((unsigned)time(NULL));
 damage = half((1-deviation)*st.att) + (rand()%int(half(2*deviation*st.att))) ;

 delay(0.01);

  int critical ;
  srand((unsigned)time(NULL));
  critical = rand()%int(half(100/st.crt)) ;
  if(critical==0){  damage = 2*damage ; }


 delay(1);
         
 crlf(3);
  
 printf("%d 의 데미지를 입혔습니다.", nominus(damage - anm.arm));
  if(critical==0){ printf("  <치명타>"); }
 anm.hp -= nominus(damage - anm.arm) ;

 if(anm.hp<0){ anm.hp=0; }
}
 void attack_anm()
{
 gotoxy(6,6);
 printf("%s이(가) 공격하였습니다.", anm.name);
      
    int damage;
 srand((unsigned)time(NULL));
    damage = (rand() % anm.att) + (anm.att/2) ;
      
 crlf(3);
 delay(2);
         
 printf("%d 의 데미지를 입었습니다.", nominus(damage - st.arm));
    st.hp -= nominus(damage - st.arm) ;

 if(st.hp<0){ st.hp=0; }
}

void uninput()
{
 while(true)
 {
  if(kbhit()) getch();
  else break;
 }
}
void printfline (int n)
{
 gotoxy(1,n);

 int i;
 for(i=0;i<78;i++){ printf("-"); }

}
void gotoxy (int x, int y)
{
 COORD Cur;
 Cur.X = x;
 Cur.Y = y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),Cur);
}  //
void setcursortype(CURSOR_TYPE c)

{
     CONSOLE_CURSOR_INFO CurInfo;

     switch (c) {  case NOCURSOR: CurInfo.dwSize=1;
          CurInfo.bVisible=FALSE;
          break;

          case SOLIDCURSOR: CurInfo.dwSize=100;
           CurInfo.bVisible=TRUE;
          break;
       case NORMALCURSOR: CurInfo.dwSize=20;
           CurInfo.bVisible=TRUE;
           break;
    }

     SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&CurInfo);
} //

 

 

visual studio 2012 버젼