文明模拟器

· · 休闲·娱乐

本人不是原作者,只是在原作的基础上经行了加强和完善。

#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

(如有改进建议,请私信我——iyka)