Advertisement
liiit

multi-generation of maps

May 26th, 2014
497
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <string.h>
  5.  
  6. int mapid, maxa, maxb, a, b;
  7. int pa, pb, paa, pbb;
  8. int over = 0;
  9. int map[35][21][20];
  10. int wall_list[21][20];
  11. int road_list[210];
  12. int road_count = 0;
  13.  
  14. // 미로 생성 관련 함수 :
  15. // int mapprnt(), int mapprnt_p(), int wall_check(int a, int b, int type)
  16. // int outer_check(int a, int b), int road(int a, int b), int mazegen(int ma, int mb)
  17. int mapprnt(int id)
  18. // map[mapid][a][b] 에 대한 전체 맵 출력.
  19. {
  20.     int a,b;
  21.     for (a = 1 ; a < sizeof(map[0]) / sizeof(map[0][0]) ; a++)
  22.     { // 헤더 부분을 출력하지 않도록 a = 1 로 설정
  23.         for (b = 0; b < sizeof(map[0][0]) / sizeof(map[0][0][0]) ; b++)
  24.         {
  25.             switch (map[id][a][b])
  26.             {
  27.                 case 0 : printf ("  "); break;
  28.                 case 1 : printf ("[]"); break;
  29.                 case 2 : printf ("M "); break;
  30.                 case 3 : printf ("UP"); break;
  31.                 case 4 : printf ("DN"); break;
  32.                 case 8 : printf ("# "); break;
  33.                 default :
  34.                 if (map[id][a][b] >= 100 && map[id][a][b] < 200)
  35.                 {
  36.                     printf ("@ ");
  37.                 }
  38.                 if (map[id][a][b] >= 1000)
  39.                 {
  40.                     printf ("%% ");
  41.                 }
  42.                 break;
  43.             }
  44.         }
  45.         printf ("\n");
  46.     }
  47.     printf ("\n");
  48.     return 0;
  49. }
  50. int mapprnt_p(int id)
  51. // map[mapid][a][b] 에 대한 전체 맵 출력. 플레이어 4방향 3칸까지만 보이게 출력.
  52. // 나머지 보이지 않는 영역은 || 로 표시한다.
  53. {
  54.     int a,b;
  55.     for (a = 1 ; a < sizeof(map[0]) / sizeof(map[0][0]) ; a++)
  56.     { // 헤더 부분을 출력하지 않도록 a = 1 로 설정
  57.         for (b = 0; b < sizeof(map[0][0]) / sizeof(map[0][0][0]) ; b++)
  58.         {
  59.             if (a >= pa-3 && a <= pa+3 && b >= pb-3 && b <= pb+3)
  60.             {
  61.                 switch (map[id][a][b])
  62.                 {
  63.                     case 0 : printf ("  "); break;
  64.                     case 1 : printf ("[]"); break;
  65.                     case 2 : printf ("M "); break;
  66.                     case 3 : printf ("UP"); break;
  67.                     case 4 : printf ("DN"); break;
  68.                     case 8 : printf ("# "); break;
  69.                     default :
  70.                     if (map[id][a][b] >= 100 && map[id][a][b] < 200)
  71.                     {
  72.                         printf ("@ ");
  73.                     }
  74.                     if (map[id][a][b] >= 1000)
  75.                     {
  76.                         printf ("%% ");
  77.                     }
  78.                     break;
  79.                 }
  80.             }
  81.             else
  82.             {
  83.                 printf ("||");
  84.             }
  85.         }
  86.         printf ("\n");
  87.     }
  88.     printf ("\n");
  89.     return 0;
  90. }
  91. int mapp (int id, int sight)
  92. {
  93.     switch (sight)
  94.     {
  95.         case 0 : mapprnt_p(id); break;
  96.         case 1 : mapprnt(id); break;
  97.     }
  98.     return 0;
  99. }
  100. int wall_check(int id, int a, int b, int type)
  101. // 선택된 좌표 a,b 의 주변 벽이 몇 개인지 세어 그 수를 반환함.
  102. // type = 1이면 주변 벽들을 벽 리스트에 저장함.
  103. // type = 2이면 외곽 벽의 개수를 반환함.
  104. {
  105.     if (type != 2)
  106.     {
  107.         int count = 0;
  108.         if (map[id][a][b+1] == 1)
  109.         {
  110.             count++;
  111.             if (type == 1 && wall_list[a][b+1] != 2)
  112.             {
  113.                 wall_list[a][b+1] = 1;
  114.             }
  115.         }
  116.         if (map[id][a][b-1] == 1)
  117.         {
  118.             count++;
  119.             if (type == 1 && wall_list[a][b-1] != 2)
  120.             {
  121.                 wall_list[a][b-1] = 1;
  122.             }
  123.         }
  124.         if (map[id][a+1][b] == 1)
  125.         {
  126.             count++;
  127.             if (type == 1 && wall_list[a+1][b] != 2)
  128.             {
  129.                 wall_list[a+1][b] = 1;
  130.             }
  131.         }
  132.         if (map[id][a-1][b] == 1)
  133.         {
  134.             count++;
  135.             if (type == 1 && wall_list[a-1][b] != 2)
  136.             {
  137.                 wall_list[a-1][b] = 1;
  138.             }
  139.         }
  140.         return count;
  141.     }
  142.     else if (type == 2)
  143.     {
  144.         int outer_count = 0;
  145.         if (wall_list[a][b+1] == 2)
  146.         {
  147.             outer_count++;
  148.         }
  149.         if (wall_list[a][b-1] == 2)
  150.         {
  151.             outer_count++;
  152.         }
  153.         if (wall_list[a+1][b] == 2)
  154.         {
  155.             outer_count++;
  156.         }
  157.         if (wall_list[a-1][b] == 2)
  158.         {
  159.             outer_count++;
  160.         }
  161.     return outer_count;
  162.     }
  163. }
  164.  
  165. int outer_check(int a, int b)
  166. // 선택된 좌표 a,b 의 주변 외곽이 몇 개인지 세어 그 수를 반환함.
  167. {
  168.     int count = 0;
  169.     if (wall_list[a][b+1] == 2)
  170.     {
  171.         count++;
  172.     }
  173.     if (wall_list[a][b-1] == 2)
  174.     {
  175.         count++;
  176.     }
  177.     if (wall_list[a+1][b] == 2)
  178.     {
  179.         count++;
  180.     }
  181.     if (wall_list[a-1][b] == 2)
  182.     {
  183.         count++;
  184.     }
  185.     return count;
  186. }
  187.  
  188. int road(int id, int a, int b)
  189. // 현 좌표가 길이면 길 리스트에 저장함.
  190. // (a, b) 를 a*100 + b 형태로 저장한다. [(2,3) 의 경우 203으로 저장됨]
  191. {
  192.     if (map[id][a][b] == 0)
  193.     {
  194.         road_list[road_count] = a*100 + b;
  195.     }
  196.     road_count++;
  197. }
  198.  
  199. int mazegen(int id, int ma, int mb)
  200. // 미로 생성 함수. Prim's Algorithm 에 의해 미로를 랜덤으로 생성한다.
  201. {
  202.     int temp_a, temp_b, done, s_i, s_j, s_k, s_l;
  203.     map[id][0][0] = 1; // 맵 헤더의 랜덤 생성 여부에 체크
  204.     do
  205.     {
  206.         done = 0;
  207.         switch (rand() % 4)
  208.         {
  209.             case 0 : temp_a = ma-1; temp_b = mb; s_i = 1; break;
  210.             case 1 : temp_a = ma; temp_b = mb+1; s_l = 1; break;
  211.             case 2 : temp_a = ma+1; temp_b = mb; s_k = 1; break;
  212.             case 3 : temp_a = ma; temp_b = mb-1; s_j = 1; break;
  213.         }
  214.         if (map[id][temp_a][temp_b] == 1 && wall_list[temp_a][temp_b] != 2)
  215.         {
  216.             if (wall_check(id, temp_a, temp_b, 0) == 3)
  217.             {
  218.                 map[id][temp_a][temp_b] = 0;
  219.                 wall_list[temp_a][temp_b] = 0;
  220.                 ma = temp_a; mb = temp_b;
  221.                 wall_check(id,ma,mb,1);
  222.                 road (id,ma,mb);
  223.                 s_i = 0; s_l = 0; s_k = 0; s_j = 0;
  224.             }
  225.         }
  226.         else if (temp_a != ma && temp_b != mb)
  227.         {
  228.             temp_a = ma; temp_b = mb;
  229.         }
  230.         else
  231.         {
  232.         }
  233.         if (s_i == 1 && s_j == 1 && s_k == 1 && s_l == 1)
  234.         {
  235.             done = 1;
  236.         }
  237.         if (wall_check(id, temp_a, temp_b, 2) != 0)
  238.         {
  239.             done = 1;
  240.         }
  241.        
  242.     } while (done == 0);
  243.     return 0;
  244. }
  245.  
  246. int move()
  247. // 플레이어 캐릭터 (@) 의 이동 관련 함수.
  248. // i : UP, j : LEFT, k : DOWN, l : RIGHT, Q : QUIT 에 대응.
  249. // 여기선 getch() 를 쓸 수 없으니 scanf("%c", &key); 로 대신한다.
  250. {
  251.     char key;
  252.     scanf("%c", &key);
  253.     switch ((int)key)
  254.     {
  255.         case 105 :
  256.             paa = pa-1; pbb = pb; break;
  257.         case 106 :
  258.             paa = pa; pbb = pb-1; break;
  259.         case 107 :
  260.             paa = pa+1; pbb = pb; break;
  261.         case 108 :
  262.             paa = pa; pbb = pb+1; break;
  263.         case 81 :
  264.             printf ("Quit\n"); over = 1; break;
  265.     }
  266.     if (map[mapid][paa][pbb] != 1 && paa >= 1 && paa < sizeof(map[0]) / sizeof(map[0][0]) && pbb >= 0 && pbb < sizeof(map[0][0]) / sizeof(map[0][0][0]))
  267.     {
  268.         if (map[mapid][paa][pbb] == 8)
  269.         {
  270.             printf ("* : That's Portal!\n");
  271.             mapid++;
  272.         }
  273.         if (pa != paa || pb != pbb)
  274.         {
  275.             map[mapid][paa][pbb] += 100;
  276.             map[mapid][pa][pb] = map[mapid][pa][pb] % 100;
  277.         }
  278.         pa = paa; pb = pbb;
  279.     }
  280.     else
  281.     {
  282.         printf ("* : can't move\n");
  283.         paa = pa; pbb = pb;
  284.     }
  285.     mapprnt(mapid);
  286.     return 0;
  287. }
  288.  
  289. int e_move(int id, int e_a, int e_b)
  290. {
  291.     int temp_a, temp_b;
  292.     switch (rand() % 4) //랜덤 이동
  293.     {
  294.         case 0 :
  295.             temp_a = e_a - 1; temp_b = e_b; break;
  296.         case 1 :
  297.             temp_a = e_a + 1; temp_b = e_b; break;
  298.         case 2 :
  299.             temp_a = e_a; temp_b = e_b + 1; break;
  300.         case 3 :
  301.             temp_a = e_a; temp_b = e_b - 1; break;
  302.     }
  303.     if (map[id][temp_a][temp_b] != 1 && temp_a >= 1 && temp_a < sizeof(map[0]) / sizeof(map[0][0]) && temp_b >= 0 && temp_b < sizeof(map[0][0]) / sizeof(map[0][0][0]))
  304.     {
  305.         if (e_a != temp_a || e_b != temp_b)
  306.         {
  307.             map[id][temp_a][temp_b] += 1000;
  308.             map[id][e_a][e_b] = map[id][e_a][e_b] % 1000;
  309.         }
  310.         e_a = temp_a; e_b = temp_b;
  311.     }
  312.     else
  313.     {
  314.         temp_a = e_a; temp_b = e_b;
  315.     }
  316.     return e_a * 100 + e_b;
  317. }
  318.  
  319. int mapgen()
  320. {
  321.     int i,j,k;
  322.     int w_i, w_k;
  323.     int m,n;
  324.     int ra, rb;
  325.     int up, dn;
  326.     int up_a, up_b, dn_a, dn_b;
  327.     int mazegen_count;
  328.    
  329.     for (i = 0 ; i < sizeof(map) / sizeof(map[0]) ; i++)
  330.     { // 한 개의 맵
  331.    
  332.         for (m = 0 ; m < sizeof(wall_list) / sizeof(wall_list[0]) ; m++)
  333.         {
  334.             for (n = 0 ; n < sizeof(wall_list[0]) / sizeof(wall_list[0][0]) ; n++)
  335.             {
  336.                 wall_list[m][n] = 0;
  337.             }
  338.         }
  339.         mazegen_count = 0;
  340.         road_count = 0;
  341.         memset(road_list, 0, sizeof(road_list) / sizeof(road_list[0]));
  342.        
  343.         if ((rand() % 100) < 70)
  344.         {
  345.             for (j = 0 ; j < sizeof(map[0]) / sizeof(map[0][0]) ; j++)
  346.             {
  347.                 for (k = 0 ; k < sizeof(map[0][0]) / sizeof(map[0][0][0]) ; k++)
  348.                 {
  349.                     if (j == 0)
  350.                     {
  351.                         map[i][j][k] = 0;
  352.                     }
  353.                     else
  354.                     {
  355.                         map[i][j][k] = 1;
  356.                     }
  357.                 }
  358.             }
  359.             map[i][0][0] = 0;
  360.             maxa = (sizeof(map[0]) / sizeof(map[0][0])) - 1;
  361.             maxb = sizeof(map[0][0]) / sizeof(map[0][0][0]);
  362.             int wmaxa = (sizeof(wall_list) / sizeof(wall_list[0]));
  363.             int wmaxb = sizeof(wall_list[0]) / sizeof(wall_list[0][0]);
  364.             // outer wall을 2로 하여 wall_list에 저장 {
  365.             for (w_k=0 ; w_k<wmaxb ; w_k++)
  366.             {
  367.                 wall_list[1][w_k] = 2;
  368.             }
  369.             for (w_i=0 ; w_i<wmaxa ; w_i++)
  370.             {
  371.                 wall_list[w_i][0] = 2;
  372.             }
  373.             for (w_k=0 ; w_k<wmaxb ; w_k++)
  374.             {
  375.                 wall_list[wmaxa-1][w_k] = 2;
  376.             }
  377.             for (w_i=0 ; w_i<wmaxa ; w_i++)
  378.             {
  379.                 wall_list[w_i][wmaxb-1] = 2;
  380.             }
  381.             //}
  382.             ra = rand() % (maxa - 4); rb = rand() % (maxb - 4);
  383.             map[i][ra+2][rb+2] = 0;
  384.             a = ra+2; b = rb+2;
  385.             wall_check(i,a,b,1);
  386.             road(i,a,b);
  387.             mazegen(i,a,b);
  388.             while (road_count < ((maxa-2) * (maxb-2) + 4) / 2 || mazegen_count < (maxa-2 * maxb-2) / 2)
  389.             {
  390.                 mazegen(i, road_list[rand() % road_count] / 100, road_list[rand() % road_count] % 100);
  391.                 mazegen_count++;
  392.             }
  393.             up = road_list[rand() % road_count];
  394.             dn = road_list[rand() % road_count];
  395.             up_a = up / 100;
  396.             up_b = up % 100;
  397.             dn_a = dn / 100;
  398.             dn_b = dn % 100;
  399.             map[i][up_a][up_b] = 3;
  400.             map[i][dn_a][dn_b] = 4;
  401.             map[i][0][1] = dn_a;
  402.             map[i][0][2] = dn_b;
  403.             map[i][0][3] = up_a;
  404.             map[i][0][4] = up_b;
  405.         }
  406.         else if ((rand() % 100) >= 70)
  407.         {
  408.             for (j = 0 ; j < sizeof(map[0]) / sizeof(map[0][0]) ; j++)
  409.             {
  410.                 for (k = 0 ; k < sizeof(map[0][0]) / sizeof(map[0][0][0]) ; k++)
  411.                 {
  412.                     map[i][j][k] = 0;
  413.                 }
  414.             }
  415.             map[i][0][0] = 1;
  416.         }
  417.         printf ("mapid : %d\n", i);
  418.         mapp(i,1);
  419.     }
  420.     return 0;
  421. }
  422.  
  423. int main(void) {
  424.     int pl;
  425.     mapgen();
  426.     mapid = 0;
  427.     srand(time(NULL));
  428.     // 플레이어 좌표 임의설정
  429.     pl = road_list[rand() % road_count];
  430.     pa = pl / 100;
  431.     pb = pl % 100;
  432.     // 플레이어 좌표를 @로 표시
  433.     map[mapid][pa][pb] += 100;
  434.     mapp(mapid,1);
  435.     printf("%d %d %d %d %d", map[mapid][0][0], map[mapid][0][1], map[mapid][0][2], map[mapid][0][3], map[mapid][0][4]);
  436.    
  437.    
  438.     return 0;
  439. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement