小游戏:感染模拟

由于疫情的爆发,准备写一个模拟传染的游戏

但是又玩了《the walking dead》,所以将传染病改为僵尸病毒 婷哥NB!

这个程序由C++编写,使用EGE图形库

基础规则

地图分为三种颜色

灰色表示无人区(也没有僵尸)

绿色表示人类聚集点

红色表示僵尸聚集点

人类规则:

  1. 不会主动向僵尸移动
  2. 繁荣度大于危险值时会定居
  3. 繁荣度小于危险值时会移动
  4. 若两个相邻的人类聚集点的繁荣度和小于1000,则两人类聚集点合并
  5. 若两个相邻的人类聚集点的繁荣度和大于1000,则两人类聚集点不会移动
  6. 繁荣度会不断增加
  7. 若繁荣度大于1000,会用大于1000的部分在四周的无人区上生成新的人类聚集点
  8. 若繁荣度大于1000,且四周没有无人区,则不生成新的人类聚集点,且繁荣度不再增加

僵尸规则:

  1. 随意移动
  2. 若有相邻的人类聚集点会发起攻击
    • 人类战斗力为繁荣度×(警惕度+经验+1)\texttt{繁荣度} \times (\texttt{警惕度}+\texttt{经验}+1)
    • 僵尸战斗力为僵尸繁荣度+min[人类繁荣度,僵尸繁荣度]×0.5\texttt{僵尸繁荣度}+\min[\texttt{人类繁荣度},\texttt{僵尸繁荣度}] \times 0.5
    • 战斗力大者胜,并将战斗力差作为繁荣度
    • 若战斗力相等,则同归于尽
  3. 若繁荣度大于1000,会用大于1000的部分在四周的无人区上生成新的僵尸聚集点
  4. 若繁荣度大于1000,且四周没有无人区,则不生成新的僵尸聚集点,且繁荣度不再增加

人类繁荣度规则:

  1. 随机初始
  2. 每一回合加10

僵尸繁荣度规则:

  1. 初始僵尸聚集地繁荣度为1000
  2. 不会增加

警惕度规则:

  1. 警惕度=1现有人类聚集地数原有人类聚集地数\texttt{警惕度}=1-{\texttt{现有人类聚集地数}\over\texttt{原有人类聚集地数}}

危险值规则:

  1. 危险值=警惕度×1000\texttt{危险值}=\texttt{警惕度} \times 1000

经验规则:

  1. 初始为0
  2. 每一回合增加 0.001

代码

/*
epidemic
made by: wangyxhaha
-lgraphics64 -lgdi32 -limm32 -lmsimg32 -lole32 -loleaut32 -lwinmm -luuid
*/
#include <bits/stdc++.h>
#include <graphics.h>
using namespace std;

struct block{
    int type;//0 null,1 human,2 zombie
    int v;
}world_map[500][500];

struct xy{
    int x,y;
};

int color[3]={0x696969,0x32CD32,0xB22222};
int dx[]={-1,0,1,0},
    dy[]={0,1,0,-1};
int human_at_first,danger;
double careful,ex;

void map_init(int seed){
    srand(seed);
    human_at_first=0;
    for (int i=0;i<500;i++){
        for (int j=0;j<500;j++){
            if (rand()%10==9) world_map[i][j].type=1,world_map[i][j].v=rand()%1000,human_at_first++;
            else world_map[i][j].type=0,world_map[i][j].v=0;
        }
    }
    int zx=rand()%500,zy=rand()%500;
    world_map[zx][zy].type=2,world_map[zx][zy].v=1000;
    return;
}

void draw_map(){
    color_t* buff = getbuffer(NULL);
    for (int i=0;i<500;i++){
        for (int j=0;j<500;j++){
            buff[i+j*500]=color[world_map[i][j].type];
        }
    }
}

void move(){
    int human_now=0;
    for (int i=0;i<500;i++){
        for (int j=0;j<500;j++){
            if (world_map[i][j].type==1) human_now++;
        }
    }
    careful=1.0-((double)(human_now)/(double)(human_at_first));
    danger=1000*careful;
//    danger=1000;
    for (int i=0;i<500;i++){ //human
        for (int j=0;j<500;j++){
            if (world_map[i][j].type==1){
                world_map[i][j].v+=10;
                if (world_map[i][j].v>1000){
                    bool m=0;
                    for (int k=0;k<4;k++){
                        int t1=i+dx[k],t2=j+dy[k];
                        if (t1>=0 && t1<500 && t2>=0 && t2<500){
                            if (world_map[t1][t2].type==0){
                                m=1;
                                break;
                            }
                        }
                    }
                    if (m){
                        while (1){
                            int go=rand()%4;
                            int t1=i+dx[go],t2=j+dy[go];
                            if (t1>=0 && t1<500 && t2>=0 && t2<500){
                                if (world_map[t1][t2].type==0){
                                    world_map[t1][t2].type=1;
                                    world_map[t1][t2].v=world_map[i][j].v-1000;
                                    world_map[i][j].v=1000;
                                    break;
                                }
                            }
                        }
                    }
                    else world_map[i][j].v=1000;
                    continue;
                }
                if (world_map[i][j].v>danger) continue;
                bool alone=0;
                for (int k=0;k<4;k++){
                    int t1=i+dx[k],t2=j+dy[k];
                    if (t1>=0 && t1<500 && t2>=0 && t2<500){
                        if (world_map[t1][t2].type==1){
                            alone=1;
                            if (world_map[i][j].v+world_map[t1][t2].v<1000){
                                world_map[t1][t2].v+=world_map[i][j].v;
                                world_map[i][j].type=0;
                            }
                            break;
                        }
                    }
                }
                if (!alone){
                    bool m=0;
                    for (int k=0;k<4;k++){
                        int t1=i+dx[k],t2=j+dy[k];
                        if (t1>=0 && t1<500 && t2>=0 && t2<500){
                            if (world_map[t1][t2].type==0){
                                m=1;
                                break;
                            }
                        }
                    }
                    if (m){
                        while (1){
                            int go=rand()%4;
                            int t1=i+dx[go],t2=j+dy[go];
                            if (t1>=0 && t1<500 && t2>=0 && t2<500){
                                if (world_map[t1][t2].type==0){
                                    world_map[t1][t2]=world_map[i][j];
                                    world_map[i][j].type=0;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    for (int i=0;i<500;i++){ //zombie
        for (int j=0;j<500;j++){
            if (world_map[i][j].type==2){
                if (world_map[i][j].v>1000){
                    bool m=0;
                    for (int k=0;k<4;k++){
                        int t1=i+dx[k],t2=j+dy[k];
                        if (t1>=0 && t1<500 && t2>=0 && t2<500){
                            if (world_map[t1][t2].type==0){
                                m=1;
                                break;
                            }
                        }
                    }
                    if (m){
                        while (1){
                            int go=rand()%4;
                            int t1=i+dx[go],t2=j+dy[go];
                            if (t1>=0 && t1<500 && t2>=0 && t2<500){
                                if (world_map[t1][t2].type==0){
                                    world_map[t1][t2].type=2;
                                    world_map[t1][t2].v=world_map[i][j].v-1000;
                                    world_map[i][j].v=1000;
                                    break;
                                }
                            }
                        }
                    }
                    else world_map[i][j].v=1000;
                }
                bool alone=0;
                for (int k=0;k<4;k++){
                    int t1=i+dx[k],t2=j+dy[k];
                    if (t1>=0 && t1<500 && t2>=0 && t2<500){
                        if (world_map[t1][t2].type==1){
                            alone=1;
                            if (world_map[t1][t2].v*(careful+1+ex)<world_map[i][j].v+min(world_map[i][j].v,world_map[t1][t2].v)*0.9){
                                world_map[t1][t2].type=2;
                                world_map[t1][t2].v=world_map[i][j].v+min(world_map[i][j].v,world_map[t1][t2].v)*0.9-world_map[t1][t2].v*(careful+1+ex);
                                world_map[i][j].type=0;
                            }
                            else if (world_map[t1][t2].v*(careful+1+ex)>world_map[i][j].v+min(world_map[i][j].v,world_map[t1][t2].v)*0.9){
                                world_map[i][j].type=0;
                                world_map[t1][t2].v=world_map[t1][t2].v*(careful+1+ex)-world_map[i][j].v+min(world_map[i][j].v,world_map[t1][t2].v)*0.9;
                            }
                            else{
                                world_map[i][j].type=0;
                                world_map[t1][t2].type=0;
                            }
                            break;
                        }
                    }
                }
                if (!alone){
                    bool m=0;
                    for (int k=0;k<4;k++){
                        int t1=i+dx[k],t2=j+dy[k];
                        if (t1>=0 && t1<500 && t2>=0 && t2<500){
                            if (world_map[t1][t2].type==0){
                                m=1;
                                break;
                            }
                        }
                    }
                    if (m){
                        while (1){
                            int go=rand()%4;
                            int t1=i+dx[go],t2=j+dy[go];
                            if (t1>=0 && t1<500 && t2>=0 && t2<500){
                                if (world_map[t1][t2].type==0){
                                    world_map[t1][t2]=world_map[i][j];
                                    world_map[i][j].type=0;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

void main_loop(){
    for (;is_run();delay_fps(5)){
        draw_map();
        move();
        ex+=0.001;
//        cout << "flush" << endl;
	}
}

int main(){
    int seed;
    cout << "seed:";
    cin >> seed;
    map_init(seed);
    cout << 1 << endl;
    initgraph(500,500,0);
    main_loop();
    closegraph();
    return 0;
}

注意事项:

  1. seed请输入int型整数
  2. 由于使用的是C++库自带的垃圾随机函数,所以会出现一些诡异的现象
  3. EGE库请自行配置
  4. 文件开始写了需要什么编译指令
  5. 库地址:https://github.com/wangyxhaha/epidemic