tj310
望南
采纳率100%
2015-05-24 02:50

捕食者与被捕食者求大神解题C++.

已采纳
    创建简单的二维“捕食者-被捕食者”模拟。在这个模拟中,被捕食者是蚂蚁(ant),捕食者是狮蚁(doodlebug)。这些小生物生活在20×20的网格中。每个单元格每次只能由一个个体占据。网格是封闭的,所以个体不允许离开世界边缘。时间以time step为单位。个体在每个time step里面都要采取某项行动。

蚂蚁的行为像下面这样建模。
Move(移动):在每个time step中,都随机向上、向下、向左或者向右移动。假如所选方向上的邻居单元格被占据,或者会造成蚂蚁移动到网格的边缘之外,那么蚂蚁就停留在当前的单元格中。
Breed(繁殖):如果一只蚂蚁在3个time step中保存存活,在第3个time step结束之后(也就是在移动之后),该蚂蚁会繁殖。为了模拟繁殖,需要在相邻(上、下、左或者右)的一个空单元格中创建一只新蚂蚁。没有可用的空单元格,就不会繁殖。一旦成功繁殖出后代,除非再次经历3个time step,否则不能繁殖另一个后代。

狮蚁的行为像下面这样建模。
Move(移动):在每个time step中,假如有一只相邻的蚂蚁(上、下、左或者右),就移动到那个单元格,吃掉蚂蚁。否则,狮蚁就按照和蚂蚁相同的规则移动。注意,狮蚁不能吃掉狮蚁。
Breed(繁殖):假如一只狮蚁在8个time step中保持存活,在第8个time step结束之后,会按照与蚂蚁相同的方式繁殖出一只新狮蚁。
Starve(饥饿):假如一只狮蚁在连续3个time step中没有吃掉一只蚂蚁,在第3个time step结束之后,它会感到饥饿并死亡。该狮蚁应从网格中拿掉。
在一轮中,所有狮蚁都应该先于蚂蚁移动。

写程序来实现这个模拟,使用ASCII字符“o”表示蚂蚁,“x”表示狮蚁。创建名为Organism(有机生物)的类,它封装了通用于蚂蚁和狮蚁的基本数据。该类应该有一个名为Move的virtual函数,它要在派生类Ant和Doodlebug中进行具体的定义。可能需要额外的数据结构来跟踪已移动的生物。
使用5只狮蚁和100只蚂蚁初始化这个世界。在每个time step后,都提示用户按Enter键移动到下一个time step。应该看到狮蚁和蚂蚁数量的循环变化——虽然一些随机性的混乱可能造成一种或两种生物的毁灭。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

5条回答

  • useryoung useryoung 6年前

    问题有些高深,没有答案呀

    点赞 评论 复制链接分享
  • gamefinity 知常曰明 6年前

    SOURCE.H

    #ifndef __SOURCE_H__
    #define __SOURCE_H__
    
    struct Step
    {
        int dx;
        int dy;
    };
    
    enum AnimalType
    {
        IsAnt,
        IsDoodlebug
    };
    
    class Animal;
    class Cell
    {
    public:
        int x;
        int y;
        Animal *animal;
    
    public:
        Cell(int x0, int y0);
        Cell *nearbyCell(int dir);
        bool in(Animal *animal0);
        Animal *leave();
    };
    
    class Animal
    {
    protected:
        int maxBreedTime;
        int breedTime;
        int maxStarveTime;
        int starveTime;
    public:
        AnimalType type;
        Animal *next;
        Animal *prior;
    public:
        Animal();
        virtual ~Animal();
    
    public://virtual
        virtual Animal *breedChild() = 0;
        virtual bool canEat(AnimalType animal) = 0;
        virtual bool eat() = 0;
    
    public:
        Cell *cell;
        bool breed();
        bool move();
        void step();
    };
    
    class Ant :public Animal
    {
    public:
        Ant() ;
    public:
        virtual Animal *breedChild();
        virtual bool canEat(AnimalType t);
        virtual bool eat();
    };
    
    class Doodlebug :public Animal
    {
    public:
        Doodlebug() ;
    public:
        virtual Animal *breedChild();
        virtual bool canEat(AnimalType t);
        virtual bool eat();
    };
    
    
    Step Steps[4] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };
    int maxWidth;
    int maxHeight;
    Cell ***Status;
    Animal *DoodleBugs;
    Animal *Ants;
    
    #endif //__SOURCE_H__
    

    SOURCE.CPP

    #include <stdio.h>
    #include <stdlib.h>
    #include "Source.h"
    
    //========================================
    //
    // Cell
    //
    Cell::Cell(int x0, int y0)
    {
        this->x = x0;
        this->y = y0;
        this->animal = NULL;
    }
    Cell *Cell::nearbyCell(int dir)
    {
        int x0 = this->x + Steps[dir].dx;
        int y0 = this->y + Steps[dir].dy;
        if (x0 < 0 || y0 < 0 || x0 >= maxWidth || y0 >= maxHeight)
            return NULL;
        else
        {
            return Status[x0][y0];
        }
    }
    bool Cell::in(Animal *animal0)
    {
        if (this->animal != NULL)
            return false;
        else
        {
            animal0->cell = this;
            this->animal = animal0;
            return true;
        }
    }
    Animal *Cell::leave()
    {
        Animal *theAnimal = this->animal;
        theAnimal->cell = NULL;
        this->animal = NULL;
        return theAnimal;
    }
    //========================================
    //
    // Animal
    //
    Animal::Animal()
    {
        this->cell = NULL;
        this->breedTime = 0;
        this->starveTime = 0;
    
        this->prior = NULL;
        this->next = NULL;
    }
    bool Animal::breed()
    {
        if (this->breedTime >= maxBreedTime)
        {
            for (int i = 0; i < 4; i++)
            {
                Cell *c = this->cell->nearbyCell(i);
                if (c != NULL && c->animal == NULL)
                {
                    c->in(this->breedChild());
                    this->breedTime = 0;
                    return true;
                }
            }
        }
        return false;
    }
    bool Animal::move()
    {
        int dir = rand() % 4;
        Cell *c = this->cell->nearbyCell(dir);
        if (c == NULL)
            return false;
        else if (c->animal == NULL)
        {
            c->in(this->cell->leave());
            return true;
        }
    }
    void Animal::step()
    {
        bool dosth = false;
        this->breedTime++;
        this->starveTime++;
    
        dosth |= this->breed();
        dosth |= this->eat();
        if (!dosth)
        {
            this->move();
        }
    
        if (this->maxStarveTime > 0 && this->starveTime >= this->maxStarveTime)
        {
            //starve
            this->cell->leave();
            delete (this);
        }
    }
    Animal::~Animal()
    {
        Animal *t = this->next;
        this->prior->next = t;
        if (t != NULL)
            t->prior = this->prior;
    }
    //========================================
    //
    // Ant
    //
    Ant::Ant() : Animal()
    {
        this->type = IsAnt;
        this->maxStarveTime = -1;
        this->maxBreedTime = 3;
    
        if (Ants != NULL)
        {
            this->prior = Ants;
            this->next = Ants->next;
            if (Ants->next != NULL) Ants->next->prior = this;
            Ants->next = this;
        }
    }
    Animal *Ant::breedChild()
    {
        return new Ant();
    }
    bool Ant::canEat(AnimalType t)
    {
        return false;
    }
    bool Ant::eat()
    {
        return false;
    }
    //========================================
    //
    // Doodlebug
    //
    Doodlebug::Doodlebug() :Animal()
    {
        this->type = IsDoodlebug;
        this->maxStarveTime = 3;
        this->maxBreedTime = 8;
    
        if (DoodleBugs != NULL)
        {
            this->prior = DoodleBugs;
            this->next = DoodleBugs->next;
            if (DoodleBugs->next != NULL) DoodleBugs->next->prior = this;
            DoodleBugs->next = this;
        }
    }
    Animal *    Doodlebug::breedChild()
    {
        return new Doodlebug();
    }
    bool    Doodlebug::canEat(AnimalType t)
    {
        if (t == IsAnt)
            return true;
        else
            return false;
    }
    bool    Doodlebug::eat()
    {
        for (int i = 0; i < 4; i++)
        {
            Cell *c = this->cell->nearbyCell(i);
            if (c!=NULL && c->animal != NULL && this->canEat(c->animal->type))
            {
                Animal *theAnimal = c->leave();
                delete(theAnimal);
                this->starveTime = 0;
                return true;
            }
        }
        return false;
    }
    //========================================
    //
    // main
    //
    void randomSet(Animal *animal0)
    {
        srand(0);
        int x;
        int y;
        do
        {
            x = rand() % maxWidth;
            y = rand() % maxHeight;
        }
        while (Status[x][y]->animal != NULL);
        Status[x][y]->in(animal0);
    }
    void  printoutHead()
    {
        printf("+");
        for (int i = 0; i < maxWidth; i++)
        {
            printf("=");
        }
        printf("+\n");
    }
    void printoutDetail(int r)
    {
        printf("|");
        for (int i = 0; i < maxWidth; i++)
        {
            if (Status[i][r]->animal == NULL)
                printf(" ");
            else
            {
                switch (Status[i][r]->animal->type)
                {
                case IsAnt:
                    printf("O");
                    break;
                case IsDoodlebug:
                    printf("X");
                    break;
                default:
                    printf("?");
                    break;
                }
            }
        }
        printf("|\n");
    }
    void printout()
    {
        printoutHead();
        for (int i = 0; i < maxHeight; i++)
            printoutDetail(i);
        printoutHead();
    }
    void main()
    {
        int nDoodleBug;
        int nAnt;
    
        printf("请输入区域宽度:");
        scanf("%d", &maxWidth);
        printf("请输入区域高度:");
        scanf("%d", &maxHeight);
        printf("请输入初始狮蚁数量:");
        scanf("%d", &nDoodleBug);
        printf("请输入初始蚂蚁数量:");
        scanf("%d", &nAnt);
    
        //maxWidth = 3;
        //maxHeight = 4;
        //nDoodleBug = 2;
        //nAnt = 5;
    
        Status = new Cell**[maxWidth];
        DoodleBugs = new Doodlebug();
        Ants = new Ant();
    
        for (int i = 0; i < maxWidth; i++)
        {
            Status[i] = new Cell*[maxHeight];
            for (int j = 0; j < maxHeight; j++)
            {
                Status[i][j] = new Cell(i, j);
            }
        }
    
        for (int i = 0; i < nDoodleBug; i++)
        {
            randomSet(new Doodlebug());
        }
        for (int i = 0; i < nAnt; i++)
        {
            randomSet(new Ant());
        }
    
        printout();
        system("pause");
        while (true)
        {
            Animal *a = DoodleBugs->next;
            Animal *a0;
            for ( a0 = (a == NULL ? NULL : a->next); a != NULL; a = a0, a0 = (a == NULL ? NULL : a->next))
                a->step();
            a = Ants->next;
            for ( a0 = (a == NULL ? NULL : a->next); a != NULL; a = a0, a0 = (a == NULL ? NULL : a->next))
                a->step();
            printout();
    
            system("pause");
        }
    }
    
    
    点赞 1 评论 复制链接分享
  • xianfajushi 智者知已应修善业 6年前

    大致分析如下,等有空写:
    /*无论多复杂的问题都从最简单最容易想到的地方下手:
    1.首先创建二维数组表示世界char 世界[20][20];
    2.创建两种动物一维数组char 蚂蚁类[400],狮蚁类[400];
    3.初始化两种动物随机分布,需要随机产生2个数表示数组维度序号int a = rand() % 20,b = rand() % 20;同时检测是否已经赋值以完成初始化随机分布。
    4.移动判断:如果数组元素不等于空,则固定二维中的一维并使另一维序++或--交替去完成,随机生成0或1决定方向,传递返回维度序号。
    5.狮蚁生存判断:5.1吃掉判断:有吃则饥饿为0, 5.2饥饿判断:取值判断
    6.繁殖判断:移动+时间步判断
    7.创建两种动物类包含二维序和时间步数struct 蚂蚁类{ int aa; int bb; int 繁殖; };struct 狮蚁类{ int aa; int bb; int 繁殖; int 饥饿; };
    8.
    */

    点赞 1 评论 复制链接分享
  • xianfajushi 智者知已应修善业 6年前

    一个地球星球上茫茫人海,怎么会没答案?
    /*捕食者与被捕食者求大神解题C++.
    创建简单的二维“捕食者-被捕食者”模拟。在这个模拟中,被捕食者是蚂蚁(ant),捕食者是狮蚁(doodlebug)。这些小生物生活在20×20的网格中。每个单元格每次只能由一个个体占据。网格是封闭的,所以个体不允许离开世界边缘。时间以time step为单位。个体在每个time step里面都要采取某项行动。
    蚂蚁的行为像下面这样建模。
    Move(移动):在每个time step中,都随机向上、向下、向左或者向右移动。假如所选方向上的邻居单元格被占据,或者会造成蚂蚁移动到网格的边缘之外,那么蚂蚁就停留在当前的单元格中。
    Breed(繁殖):如果一只蚂蚁在3个time step中保存存活,在第3个time step结束之后(也就是在移动之后),该蚂蚁会繁殖。为了模拟繁殖,需要在相邻(上、下、左或者右)的一个空单元格中创建一只新蚂蚁。没有可用的空单元格,就不会繁殖。一旦成功繁殖出后代,除非再次经历3个time step,否则不能繁殖另一个后代。

    狮蚁的行为像下面这样建模。
    Move(移动):在每个time step中,假如有一只相邻的蚂蚁(上、下、左或者右),就移动到那个单元格,吃掉蚂蚁。否则,狮蚁就按照和蚂蚁相同的规则移动。注意,狮蚁不能吃掉狮蚁。
    Breed(繁殖):假如一只狮蚁在8个time step中保持存活,在第8个time step结束之后,会按照与蚂蚁相同的方式繁殖出一只新狮蚁。
    Starve(饥饿):假如一只狮蚁在连续3个time step中没有吃掉一只蚂蚁,在第3个time step结束之后,它会感到饥饿并死亡。该狮蚁应从网格中拿掉。
    在一轮中,所有狮蚁都应该先于蚂蚁移动。

    写程序来实现这个模拟,使用ASCII字符“o”表示蚂蚁,“x”表示狮蚁。创建名为Organism(有机生物)的类,它封装了通用于蚂蚁和狮蚁的基本数据。该类应该有一个名为Move的virtual函数,它要在派生类Ant和Doodlebug中进行具体的定义。可能需要额外的数据结构来跟踪已移动的生物。
    使用5只狮蚁和100只蚂蚁初始化这个世界。在每个time step后,都提示用户按Enter键移动到下一个time step。应该看到狮蚁和蚂蚁数量的循环变化——虽然一些随机性的混乱可能造成一种或两种生物的毁灭。
    /
    /
    无论多复杂的问题都从最简单最容易想到的地方下手:
    1.首先创建二维数组表示世界动物类容器 世界[20][20] = {};
    2.struct 蚁类{char 名称 int 繁殖; int 饥饿; bool 移标 = false; };
    3.初始化两种动物随机分布,需要随机产生2个数表示数组维度序号int a = rand() % 20,b = rand() % 20;同时检测是否已经赋值以完成初始化随机分布。
    4.移动判断:如果数组元素不等于空,则固定二维中的一维并使另一维序++或--交替去完成或二维各+1或-1形成八个方向移动,四方或八方选择int 八方[8][2]={{0,1},{1,0},{1,1},{0,-1},{-1,0},{-1,-1},{1,-1},{-1,1}}rand() % 4。
    5.狮蚁生存判断:5.1吃蚂蚁判断:有吃则饥饿为0, 5.2饥饿判断:取值判断
    6.繁殖判断:时间步判断
    其实对写游戏没兴趣,不过消磨时间倒是玩别人写的游戏,哈哈;这是第一次对这种题目有点兴趣,所以,还是花费了点时间和精力进行构思和调试,以上基本实现从初步分析和后来推敲来写这个程序,注释掉的繁殖语句,还没写的狮蚁处理函数,或许什么时候有心情了会补充完整,发布在博客中。
    /
    void 随机种子()
    {
    time_t now;
    time(&now);
    srand((unsigned int)now);
    }
    int *方向(int 维)
    {
    static int 八方[8][2] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 }, { 1, 1 }, { -1, -1 }, { 1, -1 }, { -1, 1 } };
    return 八方[维];
    }
    struct 蚁类{ char 名称 = '.'; int 繁殖 = 0; int 饥饿 = 0; bool 移标 = false; };
    void 随即分布数组(蚁类 数组[20][20], int 数量, char 名称 = '!')
    {
    随机种子();
    do
    {
    int 一维 = rand() % 20, 二维 = rand() % 20;
    if (数组[一维][二维].名称 == '.')
    {
    数组[一维][二维].名称 = 名称;
    数量--;
    }
    } while (数量);
    }
    void 显示蚁数组(蚁类 数组[20][20])
    {
    int 一维(0), 二维(0);
    do
    {
    std::cout << 数组[一维][二维++].名称;
    if (二维 > 19)
    {
    二维 = 0;
    一维++;
    std::cout << endl;
    }
    } while (一维 < 20);
    }
    void 蚂蚁动作(蚁类 数组[20][20], bool 移动判断)
    {
    随机种子();
    int 一维(0), 二维(0);
    do
    {
    int 移动 = rand() % 8, 移向1 = 一维 + 方向(移动)[0], 移向2 = 二维 + 方向(移动)[1];
    if (移向1 >= 0 && 移向1 < 20)if (移向2 >= 0 && 移向2 < 20)/
    移动在界内*/
    {
    蚁类 移点 = 数组[一维][二维], 移格 = 数组[移向1][移向2];
    if (移点.名称 == '|')/*蚂蚁*/
    {
    if (移格.名称 == '!')/*被吃掉*/
    {
    数组[一维][二维] = 蚁类();
    continue;
    }
    if (移格.名称 == '.' && 移动判断 == 移点.移标)/*移动*/
    {
    数组[移向1][移向2] = 移点;
    数组[移向1][移向2].繁殖++;
    数组[移向1][移向2].移标 = 移动判断 ? false : true;
    //if (移点.繁殖 == 3)/*新生*/
    //{
    // 数组[一维][二维].繁殖 = 0;
    // 数组[一维][二维].移标 = 移动判断 ? false : true;
    // 数组[移向1][移向2].繁殖 = 0;
    //}
    //else
    数组[一维][二维] = 蚁类();
    }
    }
    }
    if (++二维 > 19){ 二维 = 0; ++一维; }
    } while (一维 < 20);
    std::cout << endl;
    }

    主函数调用

    蚁类 蚁[20][20];
    随即分布数组(蚁,100, '|');
    随即分布数组(蚁, 5);
    显示蚁数组(蚁);
    
    int 步伐(2000); bool 移动判断 = false;
    do
    {
        蚂蚁动作(蚁, 移动判断);
        移动判断 = 移动判断 ? false : true;
        system("cls");
        显示蚁数组(蚁);
        //Sleep(6);
    } while (--步伐);
    
    之上运行可以看到在2000步内蚂蚁移动和被吃的屏幕演示,暂时注释掉繁殖代码.
    
    点赞 评论 复制链接分享
  • xianfajushi 智者知已应修善业 6年前

    分析还需要进一步推敲

    点赞 评论 复制链接分享

相关推荐