Advertisement
Guest User

asthmatic_thematic

a guest
Feb 16th, 2011
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 23.59 KB | None | 0 0
  1. // RELEASED UNDER GNU LICENSE
  2. //   see www.gnu.org/licenses/gpl.html
  3.  
  4. //include <cstdlib>
  5. #include <time.h>
  6. //include <iostream>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include "math.h"
  10.  
  11. // compiling and running
  12. //   gcc worldgen.c ; ./a.out
  13. // plotting data: use eg gnuplot
  14. //   cd to correct directory:
  15. //     cd 'dir'
  16. //   set views:
  17. //     set pm3d map
  18. //     set zrange [0:10000]
  19. //   map data
  20. //     splot 't.txt' matrix
  21. //     (or e.txt, or w.txt, ...)
  22. // selecting types of data
  23. //   either use gnuplot data ranges,
  24. //   or go to "output" section below:
  25. //     choose a structure to examine,
  26. //     and set it to a high value
  27. //       (for reproducibility, set
  28. //       time now defn to a constant)
  29. //
  30. // there's a weird but nice rotational
  31. //   asymmetry in the dmd-sq routine...
  32.  
  33. #define TIMENOW (unsigned)time(0)
  34.  
  35. #define SIZE 256
  36.  
  37. // RANDOM NUMBER FUNCTIONS
  38. #define R_SZ (int)(rndmf(SIZE))
  39. #define R_ONE rndmf(1.0)
  40. #define R_1F1 (1.0-2.0*rndmf(1.0))
  41. #define R_1I1 (1-(int)(rndmf(2.999999999999)))
  42.  
  43. // LENGTH SCALES
  44. #define H_SCALE 2.0
  45. // roughness goes up as scale below goes down
  46. #define SCALE 0.55
  47. #define DOWNSLOPE 0.005
  48. #define DOWNVAR 1.0
  49. #define WET_SCALE 1.8
  50.  
  51. // MOUNTAINS
  52. #define N_MTN_RANGES 7
  53. #define MTN_JIGGLE 0.4
  54. #define MTN_WANDER 4.0
  55. #define MTN_JUMP 0.07
  56. #define MTN_WIDTH 0.04
  57. #define MTN_ADD .015
  58.  
  59. // RIVERS AND SPRINGS
  60. #define RIV_STEP 3
  61. #define RIV_WIDTH 3
  62. #define SM_WIDTH 5
  63. #define N_SPRINGS 3
  64. #define H_SPRING_MIN 0.4
  65. #define H_SPRING_MAX 0.9
  66. #define N_ANTI_SPRINGS 6
  67. #define H_ANTI_MIN -0.3
  68. #define H_ANTI_MAX -0.001
  69. #define RIV_MAXL SIZE/4
  70. #define LAKE_REPEAT 10
  71. #define LAKE_WALKS 10
  72.  
  73. // FORESTS
  74. #define N_FORESTS 15
  75. #define N_FOR_JUMPS 20
  76. #define N_FOR_WALKS 30
  77. #define N_FOR_FAR 5
  78. #define FOREST_WIDTH 1
  79. #define H_FOREST_MIN 0.05
  80. #define H_FOREST_MAX 0.7
  81.  
  82. // DESERTS
  83. #define N_DESERTS 5
  84. #define DESERT_WIDTH 8
  85. #define N_DES_JUMPS 10
  86. #define N_DES_WALKS 20
  87. #define N_DES_FAR 4
  88. #define SCORCH_J 0.1
  89.  
  90. // TUNDRA, GLACIERS
  91. #define TUNDRA_J 0.85
  92. #define N_GLACIER_WALKS 10
  93. #define GLACIER_WIDTH 2
  94.  
  95. // TOPOGRAPHY
  96. #define N_CONE 5
  97. #define H_CONE 2.0
  98. #define SCALE_CONE 0.01
  99. #define H_HILLS 0.2
  100. #define H_MTN   0.5
  101. #define H_PEAK  0.9
  102.  
  103. // TERRAINS
  104. //   including shallow and deep water
  105. #define PLAIN     1
  106. #define DESERT    2
  107. #define WOODS     3
  108. #define HILLS     4
  109. #define TUNDRA    5
  110. #define SHALLOW   6
  111.  
  112. #define SCORCH    12
  113. #define FOREST    13
  114. #define MOUNTAIN  14
  115. #define GLACIER   15
  116. #define DEEP      16
  117.  
  118. #define PEAK      24
  119.  
  120. #define DIFFIMPASS 10
  121.  
  122. // TOWNS AND SITES
  123.  
  124. #define T_START   50
  125. #define T_HUMAN   51
  126. #define T_SANDM   52
  127. #define T_ELF     53
  128. #define T_DWARF   54
  129. #define T_SNOWM   55
  130. #define T_RIVM    56
  131.  
  132. #define T_BURNM   62
  133. #define T_TREEM   63
  134. #define T_MTNM    64
  135. #define T_ICEM    65
  136. #define T_OCEANM  66
  137.  
  138. /*
  139. later: ease of moving for races
  140.  
  141. hum  1  2   3  4  5  6 12  13  14  15
  142. elf  3  1  13  2  4  5  6  12  14  15
  143. dwf  4  1  14  2  3  5  6  12  13  15
  144. sno  5 15  14 ...
  145. */
  146.  
  147. void fill1DFractArray (float *, int, int, float, float);
  148. void fill2DFractArray (float *, int, int, float, float);
  149.  
  150. #include "dmnd_square.c"
  151.  
  152. int main() {
  153.  
  154.   srand(TIMENOW);
  155.  
  156.   float * ffaa;
  157.   int hsize=SIZE/2;
  158.   float h1 = 1.0;
  159.   float h2 = 0.4;
  160.   float h_main = 0.5;
  161.   float h_polar = 1.5;
  162.  
  163.   float dist, angle;
  164.   int i, j;
  165.   int t;
  166.   int i1,j1,i2,j2;
  167.   float divs;
  168.   int ii,jj;
  169.   int k, kk;
  170.   int irndrad, jrndrad;
  171.  
  172.   float elev[SIZE][SIZE];
  173.   int terr[SIZE][SIZE];
  174.   float wet[SIZE][SIZE];
  175.  
  176.   //================================================================
  177.   // set basic topography
  178.   ffaa = alloc2DFractArray(SIZE);
  179.   fill2DFractArray (ffaa, SIZE, TIMENOW, H_SCALE, SCALE);
  180.  
  181.   for (i=0; i<SIZE; i++) {
  182.     for (j=0; j<SIZE; j++) {
  183.       elev[i][j] = ffaa[(i*SIZE)+j] + h_main;
  184.     }
  185.   }
  186.  
  187.   //================================================================
  188.   // make fault lines re continents
  189.   // (use built-in rotational asymmetry for now)
  190.  
  191.   //================================================================
  192.   // scale down radially from center
  193.   int igeo, jgeo;
  194.   float set_dist, set_slop;
  195.   float * fdist, * fslop;
  196.   float angle_norm, angle_rem;
  197.   float leave_pole;
  198.  
  199.   fdist = alloc1DFractArray(16); //17 //distance to geo center
  200.   fslop = alloc1DFractArray(16); //17 //slope to use
  201.  
  202.   for (k=0; k<2; k++) {
  203.     fill1DFractArray(fdist, 16, TIMENOW, SIZE/3.0, .1);
  204.     fill1DFractArray(fslop, 16, TIMENOW, DOWNSLOPE, .2);
  205.    
  206.     igeo = R_SZ/3. + SIZE/3.;
  207.     jgeo = R_SZ/3. + SIZE/3;
  208.  
  209.     for (i=0; i<SIZE; i++) {
  210.       for (j=0; j<SIZE; j++) {
  211.         dist = distance(i,igeo,j,jgeo);
  212.         angle = 360./(2.*3.14159)*atan2(i-igeo, j-jgeo)+180.;
  213.         angle_norm = angle*16./360.;
  214.         angle_rem = angle_norm-(int)angle_norm;
  215.  
  216.         // interpolate
  217.         set_dist = (1-angle_rem)*fdist[(int)angle_norm] +
  218.           angle_rem*fdist[(int)angle_norm+1];
  219.         set_dist += SIZE/3;
  220.  
  221.         set_slop = -DOWNSLOPE * (1+ DOWNVAR*fslop[(int)(angle*16./360.)]);
  222.  
  223.         // ARCTIC: adjust scale down to get more land up north
  224.         if (j>3.*SIZE/4.) set_slop *= (1 - h_polar*0.5*4.*(j-3.*SIZE/4.)/SIZE);
  225.  
  226.         if (dist > set_dist) elev[i][j] += set_slop*(dist-set_dist);
  227.       }
  228.     }
  229.   }
  230.  
  231.   //================================================================
  232.   // raise and lower topographic random cones
  233.   float loci, locj, cone_height, cone_rad;
  234.  
  235.   for (k=0; k<N_CONE; k++) {
  236.     loci = R_SZ;
  237.     locj = R_SZ;
  238.     cone_height = H_CONE    * (1.25 - 2*R_ONE);
  239.     cone_rad =    SIZE/6.0  * (1.5 -    R_ONE);
  240.     fill1DFractArray(fdist, 16, TIMENOW, cone_rad, SCALE_CONE);
  241.     for (i=0; i<SIZE; i++) {
  242.       for (j=0; j<SIZE; j++) {
  243.         //  if (distance(loci,i,locj,j) < radcone) elev[i][j] -= h_cone;
  244.         dist = distance(i,loci,j,locj);
  245.         angle = 360/(2*3.14159)*atan2(i-loci, j-locj)+180.;
  246.         angle_norm = angle*16./360.;
  247.         angle_rem = angle_norm-(int)angle_norm;
  248.  
  249.         // interpolate
  250.         set_dist = (1-angle_rem)*fdist[(int)angle_norm] +
  251.           angle_rem*fdist[(int)angle_norm+1];
  252.         set_dist += cone_rad;
  253.  
  254.         if (dist < set_dist)
  255.           elev[i][j] -=
  256.             cone_height * pow((set_dist-dist)/set_dist,2);
  257.       }
  258.     }
  259.   }
  260.  
  261.   //================================================================
  262.   // could raise arctic arctic a bit more
  263.   //  for (i=0; i<SIZE; i++)
  264.   //    for (j=3.*SIZE/4.; j<SIZE; j++)
  265.   //      elev[i][j] += h_polar * R_ONE * 4.*(j-3.*SIZE/4.)/SIZE;
  266.  
  267.   //================================================================
  268.   // add mountain ranges
  269.   float * fi;
  270.   float * fj;
  271.   float mtn_wid;
  272.   int kkk, l1, l2;
  273.   int mtn_width;
  274.   int n, kkkmax;
  275.   fi = ((float *) malloc (sizeof(float) * 7)); //alloc1DFractArray(6); //7
  276.   fj = ((float *) malloc (sizeof(float) * 7)); //alloc1DFractArray(6); //7
  277.  
  278.   for (n=0; n<N_MTN_RANGES; n++) {
  279.   i1 = R_SZ;
  280.   j1 = R_SZ;
  281.   i2 = R_SZ;
  282.   j2 = R_SZ;
  283.  
  284.   segment(fi, i1, i2, 6); //fi[6] = i2;
  285.   segment(fj, j1, j2, 6); //fj[6] = j2;
  286.  
  287.   for (kkk=0; kkk<6; kkk++) {
  288.     divs = distance(fi[kkk],fi[kkk+1],fj[kkk],fj[kkk+1]);
  289.     i1 = fi[kkk]   + MTN_JIGGLE * (R_SZ/80. + 1);
  290.     i2 = fi[kkk+1] + MTN_JIGGLE * (R_SZ/80. + 1);
  291.     j1 = fj[kkk]   + MTN_JIGGLE * (R_SZ/80. + 1);
  292.     j2 = fj[kkk+1] + MTN_JIGGLE * (R_SZ/80. + 1);
  293.  
  294.     divs = distance(i1,i2,j1,j2);
  295.     for (k=0; k <= divs; k++) {
  296.       ii = k*(i2-i1)/divs + i1;
  297.       jj = k*(j2-j1)/divs + j1;
  298.  
  299.       for (kk=0; kk<MTN_WANDER*SIZE/15.; kk++) {
  300.         irndrad = MTN_JUMP * 3*R_ONE * SIZE/20.;
  301.         ii+=irndrad;
  302.         jrndrad = MTN_JUMP * 3*R_ONE * SIZE/20.;
  303.         jj+=jrndrad;
  304.         mtn_wid = MTN_WIDTH * 5*R_ONE * SIZE/10.;
  305.  
  306.         for (l1=-mtn_wid; l1<mtn_wid; l1++) {
  307.           for (l2=-mtn_wid; l2<mtn_wid; l2++) {
  308.             if ((ii+l1)>=0 && (ii+l1)<SIZE && (jj+l2)>=0 && (jj+l2)<SIZE) {
  309.                 elev[ii+l1][jj+l2] += MTN_ADD * R_ONE;
  310.             }
  311.           }
  312.         }
  313.       }
  314.     }
  315.   }
  316.   }
  317.  
  318.   //================================================================
  319.   // raise map so there is 70% land: quick and dirty version
  320.   //   (should use quicksort; choose 70% item; add constant so it's zero)
  321.   int num_above = 0;
  322.   float correction = 0.0;
  323.   float h_corr = 0.3;
  324.  
  325.   for (i=0; i<SIZE; i++)
  326.     for (j=0; j<SIZE; j++)
  327.       if (elev[i][j] > 0) num_above++;
  328.   if (num_above > 0.85*SIZE*SIZE) correction=-h_corr;
  329.   if (num_above < 0.60*SIZE*SIZE) correction=+h_corr;
  330.   if (correction != 0.0)
  331.     for (i=0; i<SIZE; i++)
  332.       for (j=0; j<SIZE; j++)
  333.         elev[i][j] += correction;
  334.  
  335.   //================================================================
  336.   // ERODE SHORELINES (to make a bit smoother edges)
  337.  
  338.   //================================================================
  339.   // SMALL DECREASE TO EDGES (to minimize need for borders, below)
  340.  
  341.   //================================================================
  342.   // SCALE ABOVEGROUND TO ONE
  343.   float maxval = -100.0;
  344.   for (i=0; i<SIZE; i++) for (j=0; j<SIZE; j++)
  345.     if (elev[i][j]>maxval) maxval=elev[i][j];
  346.   for (i=0; i<SIZE; i++) for (j=0; j<SIZE; j++)
  347.     if (elev[i][j]>0) elev[i][j] /= maxval;  
  348.  
  349.   //================================================================================
  350.   // END OF TOPOGRAPHY==============================================================
  351.   // START TERRAIN==================================================================
  352.   //================================================================================
  353.  
  354.   //================================================================
  355.   // FORM TERRAIN MAP
  356.  
  357.   // convert to initial terrain
  358.   for (i=0; i<SIZE; i++) {
  359.     for (j=0; j<SIZE; j++) {
  360.       t = DEEP;
  361.       if (elev[i][j] > 0 && elev[i][j] < H_HILLS) t = PLAIN; //plain
  362.       if (elev[i][j] > H_HILLS && elev[i][j] < H_MTN) t = HILLS; //hill
  363.       if (elev[i][j] > H_MTN && elev[i][j] < H_PEAK) t = MOUNTAIN;  //mtn
  364.       if (elev[i][j] > H_PEAK) t = PEAK; // peak
  365.       terr[i][j] = t;
  366.     }
  367.   }
  368.  
  369.   //================================================================
  370.   // ADD SPRINGS
  371.  
  372.   int notmid;
  373.   int spr_x[N_SPRINGS];
  374.   int spr_y[N_SPRINGS];
  375.   int x, y;
  376.   int antispr_x[N_ANTI_SPRINGS];
  377.   int antispr_y[N_ANTI_SPRINGS];
  378.  
  379.   // i guess this could loop infinitely in tiny maps: careful
  380.   for (i=0; i<N_SPRINGS; i++) {
  381.     notmid = 1;
  382.     while (notmid) {
  383.       x = R_SZ;
  384.       y = R_SZ;
  385.       if (elev[x][y]>H_SPRING_MIN && elev[x][y]<H_SPRING_MAX && y>SIZE/5.) notmid=0;
  386.     }
  387.     spr_x[i] = x;
  388.     spr_y[i] = y;
  389.   }
  390.   for (i=0; i<N_ANTI_SPRINGS; i++) {
  391.     notmid = 1;
  392.     while (notmid) {
  393.       x = R_SZ;
  394.       y = R_SZ;
  395.       if (elev[x][y]>H_ANTI_MIN && elev[x][y]<H_ANTI_MAX && y>SIZE/5.) notmid=0;
  396.     }
  397.     antispr_x[i] = x;
  398.     antispr_y[i] = y;
  399.   }
  400.  
  401.   //================================================================
  402.   // RUN RIVERS & LAKES
  403.   // could use nelder mead or something better here
  404.  
  405.   float minval = 1000000.0;
  406.   int mindex=0;
  407.   int notsea, notlake, nsteps;
  408.   // these are dangerous definitions: floats vs ints
  409.   float spring_elev, lastelev, angle_down, new_x, new_y, xx, yy;
  410.   float i_grad, j_grad, old_i, old_j;
  411.   int orig_x, orig_y;
  412.  
  413.   for (kkk=0; kkk<N_SPRINGS; kkk++) {
  414.     xx = spr_x[kkk]; yy = spr_y[kkk];
  415.     notsea = notlake = 1;
  416.     nsteps = 0;
  417.     while (1) {
  418.       nsteps++;
  419.  
  420.       i_grad = 0.0;
  421.       for (i=-SM_WIDTH; i<=SM_WIDTH; i++)
  422.         for (j=-SM_WIDTH; j<=SM_WIDTH; j++)
  423.           if ((xx+i)<SIZE && (xx+i)>=0 && (yy+j)<SIZE && (yy+j)>=0)
  424.             i_grad += i*elev[(int)xx+i][(int)yy+j];
  425.       j_grad = 0.0;
  426.       for (i=-SM_WIDTH; i<=SM_WIDTH; i++)
  427.         for (j=-SM_WIDTH; j<=SM_WIDTH; j++)
  428.           if ((xx+i)<SIZE && (xx+i)>=0 && (yy+j)<SIZE && (yy+j)>=0)
  429.             j_grad += j*elev[(int)xx+i][(int)yy+j];
  430.       angle = atan2(j_grad,i_grad);
  431.  
  432.       new_x = xx - cos(angle)*RIV_STEP;
  433.       new_y = yy - sin(angle)*RIV_STEP;
  434.  
  435.       if ((new_x>=SIZE-1) || (new_x<1) || (new_y>=SIZE-1) || (new_y<1))
  436.         {printf(" -escape- "); break;}
  437.  
  438.       // fill in river
  439.       divs = distance(xx,new_x,yy,new_y);
  440.       for (k=0; k<divs; k++) {
  441.         ii = k*(new_x-xx)/divs + xx;
  442.         jj = k*(new_y-yy)/divs + yy;
  443.         for (i=0; i<RIV_WIDTH; i++) for (j=0; j<RIV_WIDTH; j++) terr[ii+i][jj+j] = SHALLOW;
  444.       }
  445.       xx = new_x; yy = new_y;
  446.  
  447.       if (nsteps > 100) {printf(" -deadlooplake- "); notlake=0; break;}
  448.  
  449.       if (distance(spr_x[kkk],xx,spr_y[kkk],yy)>2*RIV_MAXL) {printf(" -long- "); break;}
  450.  
  451.       // if ocean, quit
  452.       if (elev[(int)new_x][(int)new_y] < 0) {notsea=0; printf(" -ocean- "); break;}
  453.     }
  454.     // lake fill: any easy way to fill topographically?
  455.     // also: do we want to avoid lakes right near shore?
  456.     // bigger issue: dont change immed; make linked list;
  457.     //   if river doesn't make it far, dont bother changing to shallow
  458.     if (notlake==0 && elev[(int)new_x][(int)new_y]>0.15) {
  459.       orig_x = xx; orig_y = yy;
  460.       for (i1=0; i1<LAKE_REPEAT; i1++) {
  461.         i = orig_x; j = orig_y;
  462.         for (i2=0; i2<LAKE_WALKS; i2++) {
  463.           terr[i][j] = terr[i+1][j] = terr[i][j+1] = terr[i+1][j+1] = SHALLOW;
  464.           i += R_1I1; j += R_1I1;
  465.         }
  466.       }
  467.     }
  468.   }
  469.  
  470.   //anti-springs
  471.   for (kkk=0; kkk<N_ANTI_SPRINGS; kkk++) {
  472.     xx = antispr_x[kkk]; yy = antispr_y[kkk];
  473.     notsea = notlake = 1;
  474.     nsteps = 0;
  475.     while (1) {
  476.       nsteps++;
  477.  
  478.       i_grad = 0.0;
  479.       for (i=-SM_WIDTH; i<=SM_WIDTH; i++)
  480.         for (j=-SM_WIDTH; j<=SM_WIDTH; j++)
  481.           if ((xx+i)<SIZE && (xx+i)>=0 && (yy+j)<SIZE && (yy+j)>=0)
  482.             i_grad += i*elev[(int)xx+i][(int)yy+j];
  483.       j_grad = 0.0;
  484.       for (i=-SM_WIDTH; i<=SM_WIDTH; i++)
  485.         for (j=-SM_WIDTH; j<=SM_WIDTH; j++)
  486.           if ((xx+i)<SIZE && (xx+i)>=0 && (yy+j)<SIZE && (yy+j)>=0)
  487.             j_grad += j*elev[(int)xx+i][(int)yy+j];
  488.       angle = atan2(j_grad,i_grad);
  489.  
  490.       new_x = xx + cos(angle)*RIV_STEP;
  491.       new_y = yy + sin(angle)*RIV_STEP;
  492.  
  493.       if ((new_x>=SIZE-1) || (new_x<1) || (new_y>=SIZE-1) || (new_y<1))
  494.         {printf(" -escape- "); break;}
  495.  
  496.       // fill in river
  497.       divs = distance(xx,new_x,yy,new_y);
  498.       for (k=0; k<divs; k++) {
  499.         ii = k*(new_x-xx)/divs + xx;
  500.         jj = k*(new_y-yy)/divs + yy;
  501.         if (elev[ii][jj]>0)
  502.           for (i=0; i<RIV_WIDTH; i++) for (j=0; j<RIV_WIDTH; j++) terr[ii+i][jj+j] = SHALLOW;
  503.       }
  504.       xx = new_x; yy = new_y;
  505.  
  506.       if (nsteps > 100) {printf(" -deadlooplake- "); notlake=0; break;}
  507.       if (distance(antispr_x[kkk],xx,antispr_y[kkk],yy)>RIV_MAXL) {printf(" -long- "); break;}
  508.  
  509.     }
  510.     if (notlake==0 && elev[(int)new_x][(int)new_y]>0.15) {
  511.       orig_x = xx; orig_y = yy;
  512.       for (i1=0; i1<LAKE_REPEAT; i1++) {
  513.         i = orig_x; j = orig_y;
  514.         for (i2=0; i2<LAKE_WALKS; i2++) {
  515.           terr[i][j] = terr[i+1][j] = terr[i][j+1] = terr[i+1][j+1] = SHALLOW;
  516.           i += R_1I1; j += R_1I1;
  517.         }
  518.       }
  519.     }
  520.   }
  521.  
  522.   //================================================================
  523.   // DETERMINE RANDOM WETNESS MAP
  524.   fill2DFractArray (ffaa, SIZE, TIMENOW, 1, WET_SCALE);
  525.  
  526.   minval =  100000.0;
  527.   maxval = -100000.0;
  528.   for (i=0; i<SIZE; i++) {
  529.     for (j=0; j<SIZE; j++) {
  530.       wet[i][j] = ffaa[(i*SIZE)+j];
  531.       if (wet[i][j]>maxval) maxval=wet[i][j];
  532.       if (wet[i][j]<minval) minval=wet[i][j];
  533.     }
  534.   }
  535.  
  536.   // normalize to 0-1
  537.   for (i=0; i<SIZE; i++) {
  538.     for (j=0; j<SIZE; j++) {
  539.       wet[i][j] -= minval;
  540.       wet[i][j] /= (maxval-minval);
  541.     }
  542.   }
  543.  
  544.   // make river areas humid
  545.   for (i=0; i<SIZE; i++)
  546.     for (j=0; j<SIZE; j++)
  547.       if (terr[i][j] == SHALLOW)
  548.         for (ii=i-8; ii<i+8; ii++)
  549.           for (jj=j-8; jj<j+8; jj++) wet[ii][jj] += 0.1;
  550.  
  551.   // make south more arid
  552.   for (i=0; i<SIZE; i++)
  553.     for (j=0; j<SIZE/4.; j++)
  554.       wet[i][j] *= j/(SIZE/4.);
  555.  
  556.   //================================================================
  557.   // RUN FORESTS
  558.  
  559.   int for_x[N_FORESTS], for_y[N_FORESTS];
  560.  
  561.   // locations of forest seeds
  562.   for (i=0; i<N_FORESTS; i++) {
  563.     notmid = 1;
  564.     while (notmid) {
  565.       x = R_SZ;
  566.       y = R_SZ;
  567.       //      printf("(%i %i)\n", x, y);
  568.       if (elev[x][y]>H_FOREST_MIN && elev[x][y]<H_FOREST_MAX && wet[x][y]>0.5) notmid=0;
  569.     }
  570.     for_x[i] = x;
  571.     for_y[i] = y;
  572.     //    printf("F(%i %i);[%.2f]. ",x,y,wet[x][y]);
  573.   }
  574.  
  575.   int nfj;
  576.   //multiple random walks from same point; jump to new point, repeat
  577.   //check for success by humidity
  578.   for (kkk=0; kkk<N_FORESTS; kkk++) {
  579.     x = for_x[kkk];
  580.     y = for_y[kkk];
  581.     nfj = N_FOR_JUMPS * R_ONE;
  582.     for (i=0; i<nfj; i++) {
  583.       for (j=0; j<N_FOR_WALKS; j++) {
  584.         for (ii=-FOREST_WIDTH; ii<=FOREST_WIDTH; ii++) {
  585.           for (jj=-FOREST_WIDTH; jj<=FOREST_WIDTH; jj++)
  586.             if (terr[x+ii][y+jj] <= TUNDRA && wet[x+ii][y+jj]>(R_ONE+0.1)
  587.                 && elev[x+ii][y+jj]>0 && elev[x+ii][y+jj]<H_MTN)
  588.               terr[x+ii][y+jj] = WOODS;
  589.         }
  590.         x += R_1I1; y += R_1I1;
  591.       }
  592.       // jump to new point; forests spread along latitudes
  593.       x += 1.5 * R_1I1 * R_ONE * N_FOR_FAR;
  594.       y += .75 * R_1I1 * R_ONE * N_FOR_FAR;
  595.       // more forests if humid
  596.       if (wet[x][y]>0.75 && R_ONE>0.1) i--;
  597.     }
  598.   }
  599.  
  600.   //================================================================
  601.   // PLACE DESERTS
  602.  
  603.   int des_x[N_DESERTS], des_y[N_DESERTS];
  604.  
  605.   // desert seeds
  606.   for (i=0; i<N_DESERTS; i++) {
  607.     notmid = 1;
  608.     while (notmid) {
  609.       x = R_SZ;
  610.       y = R_SZ;
  611.       //      printf("(%i %i)\n", x, y);
  612.       if (wet[x][y]<0.55 && elev[x][y]>0 && y/SIZE<0.9) notmid=0;
  613.     }
  614.     des_x[i] = x;
  615.     des_y[i] = y;
  616.     //    printf("D(%i %i);[%.2f]. ",x,y,wet[x][y]);
  617.   }
  618.  
  619.   //multiple random walks from same point; jump to new point, repeat
  620.   for (kkk=0; kkk<N_DESERTS; kkk++) {
  621.     x = des_x[kkk];
  622.     y = des_y[kkk];
  623.     nfj = N_DES_JUMPS * R_ONE;
  624.     for (i=0; i<nfj; i++) {
  625.       for (j=0; j<N_DES_WALKS; j++) {
  626.         for (ii=-DESERT_WIDTH; ii<=DESERT_WIDTH; ii++)
  627.           for (jj=-DESERT_WIDTH; jj<=DESERT_WIDTH; jj++)
  628.             if (terr[x+ii][y+jj] <= TUNDRA &&
  629.                 wet[x+ii][y+jj]<.5 || wet[x+ii][y+jj]<(R_ONE*R_ONE) &&
  630.                 abs(ii)+abs(jj)<=DESERT_WIDTH && elev[x+ii][y+jj]>0 &&
  631.                 elev[x+ii][y+jj] < H_MTN)
  632.               terr[x+ii][y+jj] = DESERT;
  633.         x += R_1I1; y += R_1I1;
  634.       }
  635.       x += R_1I1 * R_ONE * N_DES_FAR;
  636.       y += R_1I1 * R_ONE * N_DES_FAR;
  637.       // deserts in dry areas and along shores and low elevations
  638.       if ((wet[x][y]<0.25 || elev[x][y]<0.04) && R_ONE>0.1) i--;
  639.     }
  640.   }
  641.  
  642.   //================================================================
  643.   // PLACE TUNDRA
  644.   //  note: this turns some mountains (but not peaks) into glaciers
  645.   for (j=SIZE-1; j>TUNDRA_J*SIZE; j--)
  646.     for (i=0; i<SIZE; i++)
  647.       if ((j-TUNDRA_J*SIZE)/(SIZE*(1-TUNDRA_J))*pow(elev[i][j]+0.6,3.0)>R_ONE
  648.            && elev[i][j]>0 && terr[i][j]!=PEAK)
  649.         if (terr[i][j]==MOUNTAIN) terr[i][j]=GLACIER; else terr[i][j] = TUNDRA;
  650.  
  651.   //================================================================
  652.   // SET BOUNDARIES
  653.   // glacier in north;
  654.   // scorching sands in south
  655.   // future boundaries: mountains in east or west; forests in west or east;
  656.   //   (place forest on wetter edge, mountain on higher)
  657.  
  658.   // glacier
  659.   // multiple random walks from top
  660.   for (i=0; i<SIZE; i++) {
  661.     j = SIZE-1;
  662.     x = i; y = j;
  663.     if (elev[x][y]>0 || R_ONE>0.9) {
  664.       for (k=0; k<N_GLACIER_WALKS; k++) {
  665.         for (ii=-GLACIER_WIDTH; ii<=GLACIER_WIDTH; ii++) {
  666.           for (jj=-GLACIER_WIDTH; jj<=GLACIER_WIDTH; jj++) {
  667.             if ((abs(ii)+abs(jj))<=GLACIER_WIDTH
  668.                 && (y+jj)<SIZE && (x+ii)>=0 && (x+ii)<SIZE)
  669.               terr[x+ii][y+jj] = GLACIER;
  670.           }
  671.         }
  672.         if (pow(elev[i][j]+0.6,3.0)>R_ONE
  673.             && (y)<SIZE && (x)>=0 && (x)<SIZE && R_ONE>0.25)
  674.           k--;
  675.         x += R_1I1; y-= (int)(rndmf(2)); // y += R_1I1;
  676.       }
  677.     }
  678.   }
  679.  
  680.   // scorching sands
  681.   float * jdist;
  682.   int jmax;
  683.   float jpow;
  684.   jdist = alloc1DFractArray(SIZE);
  685.   fill1DFractArray(jdist, SIZE, TIMENOW, 1, .05);
  686.  
  687.   for (i=0; i<SIZE; i++) {
  688.     jmax = SIZE*SCORCH_J*(jdist[i]+1.0)*(1+0.2*(R_1F1));
  689.     for (j=0; j<jmax; j++) {
  690.       jpow = pow((jmax-j)/jmax+0.7,5.0);
  691.       if (elev[i][j]>0 && terr[i][j]!=PEAK &&
  692.           (jpow>R_ONE || (elev[i][j]<0.075 && R_ONE>0.1) ||
  693.            (j<jmax*0.1 && R_ONE>0.3)))
  694.         terr[i][j] = SCORCH;
  695.     }
  696.   }
  697.  
  698.   //================================================================================
  699.   // END OF TERRAIN=================================================================
  700.   // START CIVILIZATIONS============================================================
  701.   //================================================================================
  702.  
  703.   //================================================================
  704.   // place home towns
  705.  
  706.   int town_x[SHALLOW+1], town_y[SHALLOW+1];
  707.  
  708.   // starting town
  709.   while (1) {
  710.     x = R_SZ/2. + SIZE/4.;
  711.     y = R_SZ/2. + SIZE/4.;
  712.     if (elev[x][y] < 0.5) break;
  713.   }
  714.   town_x[0] = x; town_y[0] = y;
  715.   terr[x][y] = T_START;
  716.  
  717.   // normal towns
  718.   for (i=PLAIN; i <= SHALLOW; i++) {
  719.     while (1) {
  720.       x = R_SZ;
  721.       y = R_SZ;
  722.       if (terr[x][y]==i) break;
  723.     }
  724.     town_x[i] = x; town_y[i] = y;
  725.     terr[x][y] = T_START+i;
  726.   }
  727.  
  728.   // extreme towns        
  729.  
  730.   // report
  731.   printf("\nTOWNS\n");
  732.   for (i=0; i <= SHALLOW; i++)
  733.     printf("%i: (%i %i)[%i].\n", i,town_x[i],town_y[i], terr[town_x[i]][town_y[i]]);
  734.  
  735.   /*
  736.   // check accessibility to normal towns
  737.   for (i=1; i <= SHALLOW; i++) {
  738.   if (!exist_path(town_x[0],town_y[0], town_x[i],town_y[i]))
  739.   printf("!!!NO PATH!!! (%i)", i);
  740.   */
  741.  
  742.   // place other dungeons, etc., and check accessibility
  743.  
  744.   //================================================================================
  745.   //================================================================================
  746.   //================================================================================
  747.   // FINISHED: JUST OUTPUT
  748.  
  749.   // J, THEN I, to make map look correct
  750.   FILE *fp_elev;
  751.   FILE *fp_terr;
  752.   FILE *fp_wet;
  753.   fp_elev = fopen("e.txt", "wb");
  754.   fp_terr = fopen("t.txt", "wb");
  755.   fp_wet  = fopen("w.txt", "wb");
  756.  
  757.   //rare odd data in terrain: mash to deep
  758.   //where could this possibly come from...?
  759.   for (i=0; i<SIZE; i++) {
  760.     for (j=0; j<SIZE; j++) {
  761.       if (terr[i][j]<0 || terr[i][j]>1000)
  762.         {terr[i][j]=DEEP; printf("mt..");}
  763.     }
  764.   }
  765.   //havent seen anything wrong in elev, but mash just in case
  766.   for (i=0; i<SIZE; i++) {
  767.     for (j=0; j<SIZE; j++) {
  768.       if (elev[i][j]<-1000 || elev[i][j]>1.1)
  769.         {elev[i][j]=0.5; printf("me..");}
  770.     }
  771.   }
  772.  
  773.  
  774.   //================================================================
  775.   //debugging only: to make certain features pop on terrain map
  776.   for (i=0; i<SIZE; i++) {
  777.     for (j=0; j<SIZE; j++) {
  778.       if (terr[i][j]==SHALLOW)  terr[i][j]=70;
  779.       //      if (terr[i][j]==DESERT)  terr[i][j]=120;
  780.     }
  781.   }
  782.   //debugging only: to make certain features pop on elevation map
  783.   /*
  784.   for (i=0; i<SIZE; i++) {
  785.     for (j=0; j<SIZE; j++) {
  786.       //      if (terr[i][j]==70) elev[i][j]=1.4;
  787.     }
  788.   }
  789.   */
  790.  
  791.   //================================================================
  792.   // OUTPUT
  793.   for (j=0; j<SIZE; j++) {
  794.     for (i=0; i<SIZE; i++) {
  795.       fprintf(fp_elev, "%.2f  ", elev[i][j]);
  796.       fprintf(fp_terr, "%2i   ", terr[i][j]);
  797.       fprintf(fp_wet,  "%.2f  ",  wet[i][j]);
  798.     }
  799.     fprintf(fp_elev, "\n");
  800.     fprintf(fp_terr, "\n");
  801.     fprintf(fp_wet,  "\n");
  802.   }
  803.   fclose(fp_elev); fclose(fp_terr);
  804.  
  805.   printf("\nDONE.\n");
  806. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement