文明模拟器
本人不是原作者,只是在原作的基础上经行了加强和完善。
#include<bits/stdc++.h>
#include<windows.h>
#include<conio.h>
using namespace std;
#define KD(VK_NONAME) ((GetAsyncKeyState(VK_NONAME)&0x8000)?1:0)
const int maxn=110;
const int sleep=1000;//屏幕速度
struct civil//文明
{
int level,id;
vector<int> planets;
string name;
bool alive;
}c[maxn];
struct planet//星球
{
int dist,belong;
string name;
}p[maxn];
struct warship//舰队
{
int from;
int frompl;
int to;
int ti;
warship(){}
warship(int _frompl,int _to,int _ti):from(p[_frompl].belong),frompl(_frompl),to(_to),ti(_ti){}
};
bool operator<(warship a,warship b){ return a.ti>b.ti; }
string lv[]={"石器时代","青铜时代","铁器时代","蒸汽时代","电气时代","原子时代","信息时代","广播恒星坐标","1/100光速航行","1/10光速航行","光速航行","黑暗森林打击"};
string destroy[]={"严寒","烈焰","双日凌空","三日凌空","三日连珠","大撕裂"};
string godfind[]={"按 l 查看各文明等级,","按 p 查看星球状况,","按 a 查看舰队数量,","按 c 查看某文明面板,","按 r 进入下一个时代,","按 f 快进多个时代"};
priority_queue<warship>q,r;
int sum,aler[maxn],lyear,fyear,isl[maxn],win;
bool flag,flv,fpl,fwar,gf[maxn],nl;
map<string,int> mp;
string str;
void chck(int n);
void lose(int id);
string sFromInt(int x);
int main()
{
system("COLOR 0E");
//freopen("ST.in","r",stdin);
//freopen("ST.out","w",stdout);
int i,j,n,year,cnt;
unsigned int sd=2333;
cout<<"文明的数量(本宇宙较小,最多只能诞生 100 个文明 >_< ):";
cin>>n;//输入:第一行字符串个数,接下来若干行字符串
int rd=abs(((100-n)+7)*10); sum=n;
cout<<n<<"个文明的名字:"<<endl;
for(i=1;i<=n;++i)
{
cin>>c[i].name;
mp[c[i].name]=i;
c[i].id=rand()%99843357;
p[i].name=c[i].name;
unsigned int tmp=622;
for(j=0;j<c[i].name.size();j++) tmp=703*tmp+c[i].name[j];
sd=sd*3071+tmp;
srand(time(NULL));//每个名字(文明)的初始等级是确定的,类似名字竞技场
c[i].level=rand()%7;
c[i].planets.push_back(i);
c[i].alive=1;
p[i].dist=rand()%50+10;
p[i].belong=i;
}
cout<<"以下是各文明的初始等级:\n";
for(int i=1;i<=n;++i)
cout<<"文明"<<i<<": lv."<<c[i].level<<endl;
cout<<"请按下 r 键继续:\n";
while(!(KD('R')));
system("cls");
cout<<"宇宙在一片黑暗中诞生了..."<<"\n\n";
srand(time(NULL));//之后的演化会受所有输入名字的共同影响,也会被名字顺序影响
for(i=n+1;i<=n*2;++i)//1~n星球是n个文明的母星
{
p[i].dist=rand()%50+10;
//n+1~n*2星球是无人星球
p[i].belong=0;
p[i].name=sFromInt(i-n)+"号";
/*
//n+i星球属于第i个文明
p[i].belong=i-n;
p[i].name=c[i-n].name+"2号";
c[i-n].planets.push_back(i);
*/
}
srand(time(NULL));
for(year=0;;year+=rand()%5+10)
{
chck(n);
if(nl || !sum)
{
cout<<"是时候结束了呢...\n";
break;
}
flag=0;
while(!q.empty() && year>q.top().ti)//舰队到达
{
cout<<"第"<<year<<"年:"<<endl, flag=1;
warship now=q.top();
q.pop();
int id=now.to;
i=now.from;
if(p[id].belong==i) continue; aler[i]--;
cout<<"来自"<<c[i].name<<"文明的舰队到达"<<p[id].name<<"星球。";
if(p[id].belong==0 || (c[p[id].belong].level<c[i].level&&rand()%3))
{
cout<<"并占领了"<<p[id].name<<"星球"<<endl;
lose(id);
p[id].belong=i;
c[i].planets.push_back(id);
if(!c[i].alive)
cout<<c[i].name<<"文明重生"<<endl, c[i].alive=1, ++sum;
}
else
{
cout<<"攻击失败"<<endl;
if(c[p[id].belong].level>=7)
{
cout<<p[id].name<<"星球广播了"<<p[now.frompl].name<<"星球的位置"<<endl;
if(rand()%2)
r.push(warship(0,now.frompl,rand()%5*10+year+p[now.frompl].dist+p[id].dist));
}
}
Sleep(sleep);
}
while(!r.empty() && year>r.top().ti)//黑暗森林打击到达
{
if(!flag)
cout<<"第"<<year<<"年:"<<endl, flag=1;
int id=r.top().to;
r.pop();
cout<<p[id].name<<"星球被黑暗森林打击"<<endl;
lose(id);
p[id].belong=0;
Sleep(sleep);
}
for(i=1;i<=n;i++)
{
if(!c[i].alive) continue;
if(rand()%20==0)//技术爆炸
{
if(!flag)
cout<<"第"<<year<<"年:"<<endl, flag=1;
c[i].level++;
cout<<c[i].name<<"文明发生技术爆炸,";
if(c[i].level<=11)
{
if(c[i].level<7)
cout<<"进入"<<lv[c[i].level]<<endl;
else
cout<<"具备"<<lv[c[i].level]<<"能力"<<endl;
}
else
cout<<"等级"<<c[i].level<<endl;
Sleep(sleep);
}
else if(rand()%10==0 && c[i].level>7 && c[i].planets.size()<n*2)//发出舰队
{
if(!flag)
cout<<"第"<<year<<"年:"<<endl, flag=1;
int id;
do
id=rand()%(n*2)+1;
while(p[id].belong==i);
int speed=min(c[i].level,10);
int d=p[c[i].planets[0]].dist+p[id].dist;
if(speed==8)
d*=100;
if(speed==9)
d*=10;
cout<<c[i].name<<"文明向"<<p[id].name<<"星球发出"<<lv[speed]<<"舰队,将在"<<d<<"年后到达"<<endl;
aler[i]++;
q.push(warship(c[i].planets[0],id,year+d));
Sleep(sleep);
}
}
if(win!=0)
rd-=2;
if(rand()%rd==0)//自然灾害(全部来自《三体1》)
{
if(!flag)
cout<<"第"<<year<<"年:"<<endl, flag=1;
int id;
do
id=rand()%(n*2)+1;
while(p[id].belong==0);
cout<<p[id].name<<"星球上的文明在"<<destroy[rand()%6]<<"中毁灭了"<<endl;
lose(id);
p[id].belong=0;
Sleep(sleep);
}
if(!flag)
continue;
cout<<"\n";
--fyear;
if(fyear>0)
continue;
if(rand()%15==0)
{
if(year-lyear<20)
cout<<"十数载弹指又过去了...\n";
else if(year-lyear>=20 && year-lyear<100)
cout<<"数十载已过,是一代人还是两代人?亦或是更多?...\n";
else
cout<<"百余年已过,好像一切都不一样了,又好像什么都没变...\n";
}
memset(gf,0,sizeof(gf));
for(int i=0;i<6;++i)
cout<<godfind[i]<<"\n";
while(1)
{
if(KD('L') && !gf[0])
{
cout<<"\n";
if(rand()%15==0 && !flv && year>1250)
cout<<"文明的强弱真的很重要吗?还是说你们已经厌倦了面对下一个十年?又或者是...恐惧?\n", flv=1;
for(int i=1;i<=n;++i)
if(!isl[i])
cout<<c[i].name<<": lv."<<c[i].level<<"\n";
cout<<"\n"; gf[0]=1;
for(int i=0;i<6;++i)
if(!gf[i])
cout<<godfind[i]<<"\n";
}
else if(KD('P') && !gf[1])
{
cout<<"\n";
if(rand()%15==0 && !fpl && year>1300)
cout<<"星球?原来你们还是会关注它们的啊!我还以为在你们手里,星球只是一个工具呢... \n", fpl=1;
cout<<"星球编号: \n";
for(int i=1;i<=n;++i)
cout<<p[i].name<<"星:"<<c[p[i].belong].name<<"\n";
cout<<"\n"; gf[1]=1;
for(int i=0;i<6;++i)
if(!gf[i])
cout<<godfind[i]<<"\n";
}
else if(KD('A') && !gf[2])
{
cout<<"\n";
cout<<"舰队数量:";
if(rand()%100==0 && !fwar && year>1000)
cout<<"(舰队,代表着力量,但也有可能是孤独的旅人...)", fwar=1;
cout<<"\n";
for(int i=1;i<=n;++i)
if(!isl[i])
cout<<c[i].name<<": "<<aler[i]<<"个"<<"\n";
cout<<"\n"; gf[2]=1;
for(int i=0;i<6;++i)
if(!gf[i])
cout<<godfind[i]<<"\n";
}
else if(KD('C') && !gf[3])
{
cout<<"\n";
cout<<"请输入文明名称:";
getch();
cin>>str;
if(isl[mp[str]])
cout<<"抱歉,您找的文明已经被毁去...\n\n";
else
{
int idx=mp[str];
cout<<"文明编号: "<<c[idx].id<<"\n文明等级: lv."<<c[idx].level<<"\n舰队数量: "<<aler[idx]<<"个\n\n";
gf[3]=1;
}
for(int i=0;i<6;++i)
if(!gf[i])
cout<<godfind[i]<<"\n";
}
else if(KD('F'))
{
getch();
cout<<"请输入快进的时代数量(最多为 60 个时代):";
cin>>fyear;
while(fyear>60)
cout<<"请输入一个小于六十的数字:", cin>>fyear;
break;
}
else if(KD('R'))
break;
}
cout<<"\n\n"; lyear=year;
}
cout<<"\n这个世界的熵增也已到了尽头,最终的“胜者”是"<<c[win].name<<"文明,多么辉煌啊...\n可最终也还是要被忘却...";
return 0;
}
void chck(int n)
{
int f=0,idx;
for(int i=1;i<=n;++i)
{
if(!aler[i] && !c[i].alive)
isl[i]=1, f++;
else
idx=i;
}
if(f==n-1)
win=idx;
nl=(f==n);
}
void lose(int id)
{
int i=p[id].belong;
if(i==0)
return;
vector<int>&v=c[i].planets;
vector<int>::iterator it;
for(it=v.begin();it!=v.end();++it)
if(*it==id)
break;
v.erase(it);
if(v.size()==0)
{
c[i].alive=0;
sum--;
cout<<">>"<<c[i].name<<"文明毁灭了......\n";
if(aler[i]>0)
cout<<">>可是希望的火种早已踏上征途...\n";
Sleep(sleep*2);
}
}
string sFromInt(int x)
{
string ret;
while(x)
{
ret=char(x%10+'0')+ret;
x/=10;
}
return ret;
}
//made by iyka