原本想做一个生存游戏,懒了,遂改为地图生成.
没有使用广为人知的perlin算法,选择以dfs为基础进行改进.
#include <bits/stdc++.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <thread>
#pragma GCC optimize(3)
#define elif else if
#define pass do{}while(0)
#define ocean 0
#define sea 1
#define lake 2
#define forest 3
#define plain 4
#define grassland 5
#define mountain 6
#define volcano 7
#define hill 8
#define iceland 9
#define desert 10
#define kbhit(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
using namespace std;
int input1,checkr=8;
char input2;
int rand_number(int x,int y){
srand(time(NULL)+x*x);
srand(rand()+y*y);
return rand()+x*y;
}
/*void full_screen()
{
HWND hwnd = GetForegroundWindow();
int cx = GetSystemMetrics(SM_CXSCREEN);
int cy = GetSystemMetrics(SM_CYSCREEN);
LONG l_WinStyle = GetWindowLong(hwnd,GWL_STYLE);
SetWindowLong(hwnd,GWL_STYLE,(l_WinStyle | WS_POPUP | WS_MAXIMIZE) & ~WS_CAPTION & ~WS_THICKFRAME & ~WS_BORDER);
SetWindowPos(hwnd, HWND_TOP, 0, 0, cx, cy, 0);
}
*/
void SetColorAndBackground(int ForgC, int BackC) {
WORD wColor=((BackC & 0x0F)<<4)+(ForgC & 0x0F);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),wColor);
}
class land{
public:
int lands,resource,x,y;
char look;
void load_look(land &a){
switch(a.lands){
case 0:{
a.look='~';
break;
}
case 1:{
a.look='@';
break;
}
case 2:{
a.look='#';
break;
}
case 3:{
a.look='$';
break;
}
case 4:{
a.look='=';
break;
}
case 5:{
a.look='-';
break;
}
case 6:{
a.look='^';
break;
}
case 7:{
a.look='*';
break;
}
case 8:{
a.look='&';
break;
}
case 9:{
a.look='+';
break;
}
case 10:{
a.look='X';
break;
}
default:{
a.look='?';
break;
}
}
return;
}
};
short maxx,maxy,searchcnt,size,loadnum=0;
land blocks[7735][7735];
bool loaded[7735][7735];
int r1,r2,r3,r4,r5,r6,r7,r8,r9;
void dfs(int number,int x,int y,int landnum){
int qy=landnum;
r1=rand_number(maxx,maxx+322122)%2+2;
r2=rand_number(maxx,114)%2+3;
r3=rand_number(maxx,784*y)%2+4;
r4=rand_number(maxx,44+number)%2+3;
r5=rand_number(maxx,46*x)%2+5;
r6=rand_number(maxx,34+y)%2+3;
r7=rand_number(maxx,6+x)%2+2;
r8=rand_number(maxx,7+x)%2+2;
r9=rand_number(maxy,y+2)%5;
if(x>maxx||y>maxy||x<0||y<0||number>=size||loaded[x][y]==1){
return;
}
if(qy==6||qy==7){
number+=1;
}
if(qy==1||qy==2){
number--;
}
loaded[x][y]=1;
bool a=rand_number(x,x+1992)%r1;
bool h=rand_number(x,y+6)%r2;
bool b=rand_number(y,3945)%r3;
bool f=rand_number(x,y+245)%r4;
bool d=rand_number(x,y+4438)%r5;
bool e=rand_number(x,y+13454)%r6;
bool c=rand_number(number,3974298)%r7;
bool g=rand_number(x+y,354)%r8;
blocks[x][y].lands=qy;
if(!a){
dfs(number+8,x+1,y,landnum);
}
if(!b){
dfs(number+8,x-1,y,landnum);
}
if(!c){
dfs(number+3,x,y-1,landnum);
}
if(!d){
dfs(number+3,x,y+1,landnum);
}
if(!e){
dfs(number+2,x+1,y-1,landnum);
}
if(!f){
dfs(number+2,x-1,y+1,landnum);
}
if(!g){
dfs(number+2,x-1,y-1,landnum);
}
if(!h){
dfs(number+2,x+1,y+1,landnum);
}
if(!r9){
loaded[x][y]=0;
}
return;
}
void check(){
cout<<endl;
long long CNT=0;
for(int x=1;x<=maxx;x+=checkr){
for(int y=1;y<=maxy;y+=checkr){
CNT++;
if(blocks[x][y].lands==6){
if(blocks[x+1][y].lands!=6&&blocks[x+1][y].lands!=0&&blocks[x+1][y].lands!=1)blocks[x+1][y].lands=8;
if(blocks[x-1][y].lands!=6&&blocks[x-1][y].lands!=0&&blocks[x-1][y].lands!=1)blocks[x-1][y].lands=8;
if(blocks[x][y+1].lands!=6&&blocks[x][y+1].lands!=0&&blocks[x][y+1].lands!=1)blocks[x][y+1].lands=8;
if(blocks[x][y-1].lands!=6&&blocks[x][y-1].lands!=0&&blocks[x][y-1].lands!=1)blocks[x][y-1].lands=8;
}
if(blocks[x][y].lands==8){
if(blocks[x+1][y].lands==4||blocks[x+1][y].lands==3||blocks[x+1][y].lands==9)blocks[x+1][y].lands=5;
if(blocks[x-1][y].lands==4||blocks[x-1][y].lands==3||blocks[x-1][y].lands==9)blocks[x-1][y].lands=5;
if(blocks[x][y+1].lands==4||blocks[x][y+1].lands==3||blocks[x][y+1].lands==9)blocks[x][y+1].lands=5;
if(blocks[x][y-1].lands==4||blocks[x][y-1].lands==3||blocks[x][y-1].lands==9)blocks[x][y-1].lands=5;
}
cout<<"\rChecking... "<<(float)checkr*(float)checkr*((float)CNT/(float)(maxx*maxy))*100<<"% ";
int rrr=rand_number(23423,CNT)%3;
if(!rrr){
dfs(0,x,y,1);
}
}
}
return;
}
void printland(char x){
if(x=='~'||x=='#'||x=='@'){
SetColorAndBackground(1,9);
}
if(x=='-'||x=='$'){
SetColorAndBackground(11,2);
}
if(x=='X'||x=='='){
SetColorAndBackground(14,6);
}
if(x=='*'){
SetColorAndBackground(12,8);
}
if(x=='^'){
SetColorAndBackground(8,7);
}
if(x=='&'){
SetColorAndBackground(5,2);
}
if(x=='+'){
SetColorAndBackground(7,15);
}
putchar(x);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED |FOREGROUND_GREEN | FOREGROUND_BLUE);
}
void loadmap(){
cout<<"Loading map...\n";
for(int i=1;i<=searchcnt;i++){
loadnum++;
cout<<"\rGenerating... "<<((float)i/searchcnt)*100<<"% ";
int xx=rand_number(i,1)%maxx;
int yy=rand_number(i,11)%maxy;
int k=abs(rand_number(i+time(NULL)+3874338,3748)%11);
if(i==1){
dfs(0,xx,yy,2);
}
dfs(0,xx,yy,k);
}
check();
cout<<"Map loading finished!\n";
Sleep(500);
system("cls");
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof cfi;
cfi.nFont = 0;
cfi.dwFontSize.X = 1;
cfi.dwFontSize.Y = 1;
cfi.FontWeight = FW_THIN;
cfi.FontFamily = FF_DONTCARE;
wcscpy(cfi.FaceName, L"Raster");
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi);
bool SetConsoleFont(HANDLE,DWORD);
system("mode con cols=4140 lines=4140");
SetColorAndBackground(7,16);
for(int i=0;i<=maxx+1;i++){
cout<<endl;
for(int j=0;j<=maxy;j++){
if(i==maxx+1){
//cout<<j;
if(j<10){
//cout<<" ";
}
if(j>=10&&j<100){
// cout<<" ";
}
continue;
}
thread t1(printland(blocks[i][j].look));
thread t2(blocks[i][j].load_look(blocks[i][j]));
t2.join();
t1.join();
}
//cout<<" "<<i;
}
}
void printmap(){
CONSOLE_FONT_INFOEX cfi;
cfi.cbSize = sizeof cfi;
cfi.nFont = 0;
cfi.dwFontSize.X = 1;
cfi.dwFontSize.Y = 1;
cfi.FontWeight = FW_THIN;
cfi.FontFamily = FF_DONTCARE;
wcscpy(cfi.FaceName, L"Raster");
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfi);
bool SetConsoleFont(HANDLE,DWORD);
system("cls");
for(int i=0;i<=maxx+1;i++){
cout<<endl;
for(int j=0;j<=maxy;j++){
blocks[i][j].load_look(blocks[i][j]);
printland(blocks[i][j].look);
}
}
return;
}
void getfile(){
ifstream fin("S0.1.5.set");
cout<<"正在读取文件...\n";
Sleep(600);
fin>>maxx>>maxy>>size>>searchcnt;
cout<<"完成读取文件.\n";
fin.close();
Sleep(500);
system("cls");
return;
}
void outfile(){
ofstream fout("S0.1.5.set");
cout<<"正在保存...\n";
fout<<maxx<<" "<<maxy<<" "<<size<<" "<<searchcnt;
Sleep(500);
cout<<"保存完毕!\n";
fout.close();
return;
}
void save_map(){
ofstream fout("Map_Save0.1.3.txt");
cout<<"正在保存...\n";
for(int i=0;i<=maxx+1;i++){
fout<<endl;
for(int j=0;j<=maxy;j++){
fout<<blocks[i][j].lands<<" ";
}
}
cout<<"保存完毕!\n";
fout.close();
}
void get_map(){
ifstream fin("Map_Save0.1.3.txt");
cout<<"正在读入...\n";
for(int i=0;i<=maxx+1;i++){
for(int j=0;j<=maxy;j++){
fin>>blocks[i][j].lands;
}
}
cout<<"读入完毕!\n";
fin.close();
}
void MAP(){
cout<<"0 读入地图存档 1 新建地图 2 保存地图\n";
cin>>input1;
if(input1==0){
get_map();
printmap();
}
else if(input1==1){
loadmap();
cout<<"\n保存此地图?1保存 否则退出\n";
cin>>input1;
if(input1==1){
save_map();
}
else{
return;
}
}
else if(input1==2){
save_map();
}
else{
cout<<"输入错误。\n";
Sleep(500);
system("cls");
MAP();
}
}
void start(){
r:
cout<<setw(107)<<"请选择游戏模式"<<endl;
cout<<setw(107)<<"#——————#"<<endl;
cout<<setw(107)<<"| 开始生存(1)|"<<endl;
cout<<setw(107)<<"#——————#"<<endl;
cout<<'\n';
cout<<setw(107)<<"#——————#"<<endl;
cout<<setw(107)<<"| 游戏设置(s)|"<<endl;
cout<<setw(107)<<"#——————#"<<endl;
cout<<'\n';
cout<<setw(107)<<"#——————#"<<endl;
cout<<setw(107)<<"| 退出游戏(e)|"<<endl;
cout<<setw(107)<<"#——————#"<<endl;
system("pause");
if(kbhit('1')){
MAP();
}
else if(kbhit('S')){
puts("1 地图长宽 2 地形大小 3 生成次数 4检查倍率(越大地形越多样) t 保存 设置 f 退出");
for(;;){
system("pause");
if(kbhit('1')){
cout<<"输入高度。\n";
cin>>input1;
maxx=input1;
cout<<"输入宽度。\n";
cin>>input1;
maxy=input1;
}
else if(kbhit('2')){
cout<<"输入地形最大大小。\n";
cin>>size;
}
else if(kbhit('3')){
cout<<"输入生成次数。\n";
cin>>searchcnt;
}
else if(kbhit('4')){
cout<<"输入检查精度。1x输入1,2x数入2,4x输入3,8x输入4.\n";
cin>>input1;
switch(input1){
case 1:{
checkr=8;
break;
}
case 2:{
checkr=4;
break;
}
case 3:{
checkr=2;
break;
}
case 4:{
checkr=1;
break;
}
}
}
else if(kbhit('T'))
outfile();
else if(kbhit('F')){
system("cls");
goto r;
}
}
}
else if(kbhit('E')){
int love;
love = MessageBox(GetConsoleWindow(), "确定要退出游戏嘛?", "确定吗?", MB_YESNOCANCEL|MB_ICONEXCLAMATION);
if(love==6)
return;
else{
system("cls");
goto r;
}
}
else{
system("cls");
goto r;
pass;
}
pass;
return;
}
int main(){
cout.tie(0);
cin.tie(0);
getfile();
//full_screen();
system("mode con cols=4140 lines=4140");
start();
}