/
MapEditor_MapGenerate.cpp
108 lines (93 loc) · 3.78 KB
/
MapEditor_MapGenerate.cpp
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Benjamin Laws, Matt Rundle, Matt Mahan, Paul Kennedy
// CSE 20212-01 Final Project
// Random Map Generator
#include "MapEditor.h"
#include <iostream>
#include <iomanip>
#include <valarray>
using namespace std;
void MapEditor::RandomMapGenerate(string savename,int cornervalues[4]){
int tilevalue[40][40] = {{0}};
int corners[4] = {0,0,39,39};
// reference arrays: tileX and tileY in class header
// tile order: deepwater,water,sand,grass,grass,evergreen,tree,grass,grass,dirt,rock,snow,mountains,snow,rock,lava
// set unspecified corner values
for(int i=3;i>=0;i--){ // check backwards so that first corner of first map is definitely grass
if(cornervalues[i]==-1){ // check other corners if unspecified
for(int j=0;j<4;j++){
if(cornervalues[j]!=-1){
cornervalues[i]=cornervalues[j]+pow(-1,rand()%2)*(rand()%10); // set unspecified corner to some specified corner +/- up to 9
if(cornervalues[i]>95) cornervalues[i]=95;
if(cornervalues[i]<-1) cornervalues[i]=0;
break;
}
}
if(cornervalues[i]==-1){
cornervalues[i]=50; // if still unspecified (should only happen to first corner of first map), set to grass
if(debug) cout<<" Set map corner arbitrarily..."<<endl;
}
}
}
// set corners in map array
int a=0;
for(int i=0;i<40;i+=39){
for(int j=0;j<40;j+=39){
tilevalue[i][j]=cornervalues[a];
a++;
}
}
// generate map recursively
RMG_Recursion(corners,tilevalue);
// set corners again to ensure world continuity
a=0;
for(int i=0;i<40;i+=39){
for(int j=0;j<40;j+=39){
tilevalue[i][j]=cornervalues[a];
a++;
}
}
// intermix two types of trees
for(int i=0;i<40;i++){
for(int j=0;j<40;j++){
if(tilevalue[i][j]/6==5 && rand()%2) tilevalue[i][j]+=6;
else if(tilevalue[i][j]/6==6 && rand()%2) tilevalue[i][j]-=6;
}
}
if(debug)
for(int i=0;i<40;i+=39)
for(int j=0;j<40;j+=39)
cout<<" Corner value: "<<tilevalue[i][j]<<endl;
// write to file
ofstream fptr;
fptr.open(savename.c_str());
if(fptr.is_open() == false) return;
for(int i=0;i<40;i++){
for(int j=0;j<40;j++) fptr<<setw(2)<<setfill('0')<<tilevalue[i][j]<<" ";
fptr<<endl;
}
fptr.close();
}
void MapEditor::RMG_Recursion(int pos[4],int tilevalue[40][40]){
if(abs(pos[0]-pos[2])<2 && abs(pos[1]-pos[3])<2) return; // base case
// edges take average of nearest two corners
tilevalue[(pos[0]+pos[2])/2][pos[1]] = (tilevalue[pos[0]][pos[1]]+tilevalue[pos[0]][pos[3]])/2; // left edge
tilevalue[(pos[0]+pos[2])/2][pos[3]] = (tilevalue[pos[2]][pos[1]]+tilevalue[pos[2]][pos[3]])/2; // right edge
tilevalue[pos[0]][(pos[1]+pos[3])/2] = (tilevalue[pos[0]][pos[1]]+tilevalue[pos[2]][pos[1]])/2; // top edge
tilevalue[pos[2]][(pos[1]+pos[3])/2] = (tilevalue[pos[0]][pos[3]]+tilevalue[pos[2]][pos[3]])/2; // bottom edge
// center takes average of four corners plus/minus random fluctuation based on distance
tilevalue[(pos[0]+pos[2])/2][(pos[1]+pos[3])/2] = (tilevalue[pos[0]][pos[1]]+tilevalue[pos[0]][pos[3]]+tilevalue[pos[2]][pos[1]]+tilevalue[pos[2]][pos[3]])/4 + pow(-1,rand()%2)*((rand()%(pos[2]-pos[0])));
if(tilevalue[(pos[0]+pos[2])/2][(pos[1]+pos[3])/2] < 0) tilevalue[(pos[0]+pos[2])/2][(pos[1]+pos[3])/2]=0;
if(tilevalue[(pos[0]+pos[2])/2][(pos[1]+pos[3])/2] > 95) tilevalue[(pos[0]+pos[2])/2][(pos[1]+pos[3])/2]=95;
// recursion
int newpos[4] = {pos[0],pos[1],(pos[0]+pos[2])/2,(pos[1]+pos[3])/2};
RMG_Recursion(newpos,tilevalue); // top-left quadrant
newpos[1] = (pos[1]+pos[3])/2;
newpos[3] = pos[3];
RMG_Recursion(newpos,tilevalue); // top-right quadrant
newpos[0] = (pos[0]+pos[2])/2;
newpos[2] = pos[2];
RMG_Recursion(newpos,tilevalue); // bottom-right quadrant
newpos[1] = pos[1];
newpos[3] = (pos[1]+pos[3])/2;
RMG_Recursion(newpos,tilevalue); // bottom-left quadrant
}