Sign in to follow this  
Ultimape

Critique my Idea

Recommended Posts

Ultimape    100
I've written my first "game", although you can't actually interact with it... yet. Simple text based rendering I have a 2d gameworld, which manages "organisms". it is a vector of vectors of pointers to organisms. each game loop, all organisms are manipulated and they "ask" the game world for things. they can ask it what is at a specific cell they can ask it for coords of a random cell of TYPE adjacent to where they are, (where type can be any organism type, or empty) they can ask it to kill a cell they can ask it to move a cell There is a base class organism (pure virtual) and derived classes: predator "lion", prey "antelope" and they have 4 options: eat, move, breed, starve antelopes don't eat or starve, they just move and breed (after 3 moves) lions can eat if there is a surrounding antelope, move, breed (after 8moves), and starve (if not eaten in 3 moves) each organism manages its own logic for what to do when asked to do something it makes a rather interesting pattern, where the lions overtake the ants until there aren't enough ants to eat, and then they die off, letting the ants repopulate, thus repeating the cycle. running at 140x40, it makes some rather psychedelic patterns, complete with swirling and such. What are some ideas to expand on this... what other organisms should I add, what else should they do? I had ideas of making a "player" organism which is controlled by the user and a "bullet" organism which "eats" in a straight line till it can't move anymore and disappears. or maybe some "life" properties, where if they are overpopulated, the antelopes die. I've already extended it to move diagonally by having the game world return diagonals, and not just up down left and right. Also, i made the antlions canibalize if they were going to starve.

Share this post


Link to post
Share on other sites
alnite    3436
It seems that you are making some sort of life simulation. Well, it is fairly complex, so the first question I have to ask if you have actually implemented a program that does this or if it's just some wild idea.

Share this post


Link to post
Share on other sites
Zahlman    1682
Projects of this sort can be greatly interesting. I would resist the urge to try to make a "real game" out of it. Instead, have the user interact by controlling the parameters of the simulation. E.g., instead of hard-coding the "age of maturity" of each animal, have the user provide the value.

But if you really want *critique*, I'm going to have to see the code. ;)

Share this post


Link to post
Share on other sites
Ultimape    100
Do you like my code? I've endevord to use consistant formatting and attempted to make good comments.

it was a real b*tch to get the organsim and maiworld to compile, interdependancy hell. But I figured it out with help from articles here on game dev.




twodpoint.h

/******************************************************************************
| file | twodpoint.h |
| author | 'Ultim'Ape-Iñago |
| date | 2006/11/13 |
| description | Defines a cell position |
\******************************************************************************/


#ifndef TwoDPoint_H_INCLUDED
#define TwoDPoint_H_INCLUDED

class TwoDPoint
{

private:
int posx;
int posy;

public:
TwoDPoint ( int PosY =-1,int PosX=-1 );
bool operator == ( const TwoDPoint &other );
void set(int PosY,int PosX);
void print();
int x();
int y();
};


#endif // CELL_H_INCLUDED





twodpoint.cpp

#include <iostream>
#include "twodpoint.h"

TwoDPoint::TwoDPoint ( int y,int x )
{
set(x,y);
}

bool
TwoDPoint::operator == ( const TwoDPoint &other )
{
if ( this->posx == other.posx && this->posy == other.posy ) {
return true;
} else {
return false;
}
}

void
TwoDPoint::set(int y,int x)
{
posx = x;
posy = y;
}

int
TwoDPoint::x()
{
return posx;
}


int
TwoDPoint::y()
{
return posy;
}


void
TwoDPoint::print()
{
std::cout << "("<<posy<<","<<posx<<")";
}





enumerations.h

#ifndef ENUMERATIONS_H_INCLUDED
#define ENUMERATIONS_H_INCLUDED

class MaiWorldGrid;
enum CreatureType {
BAD = 0,
NONE = 1,
EMPTY = 1,
ANT = 2,
DOODLEBUG = 3
};

#endif // ENUMERATIONS_H_INCLUDED





maierthgame.h

/******************************************************************************
| file | maierthgame.h |
| author | 'Ultim'Ape-Iñago |
| date | 2006/11/13 |
| description | A simulation of animal preditory behavior |
| | The main program file |
\******************************************************************************/


#ifndef MAIERTHGAME_H_INCLUDEDD

#include "maiworld.h"
#include "enumerations.h"
#endif





maierthgame.cpp


#include <iostream>
#include "maierthgame.h"
#include "maiworld.h"

int main()
{
srand ( time ( NULL ) );
MaiWorldGrid gameWorld(76,19); //default game world

gameWorld.populateGridRandom ( DOODLEBUG,0.0125 );
gameWorld.populateGridRandom ( ANT, 0.25);

do{
system("cls");
gameWorld.displayGrid();

std::cout<< "Population "<< gameWorld.getCount() << "\n ([Enter] for next frame)";


gameWorld.eatAll(DOODLEBUG);
gameWorld.moveAll(DOODLEBUG);
gameWorld.breedAll(DOODLEBUG);
gameWorld.starveAll(DOODLEBUG);

gameWorld.eatAll(ANT);
gameWorld.moveAll(ANT);
gameWorld.breedAll(ANT);
gameWorld.starveAll(ANT);



gameWorld.turnDone(DOODLEBUG);
gameWorld.turnDone(ANT);



} while(std::getchar());

}





maiworld.h

/******************************************************************************
| file | maiworld.h |
| author | 'Ultim'Ape-Iñago |
| date | 2006/11/13 |
| description | The world class holds positional data and a list of organisims |
\******************************************************************************/


#ifndef MAIWORLDGRID_H_INCLUDED
#define MAIWORLDGRID_H_INCLUDED


#include "enumerations.h"
#include "twodpoint.h"

#include <vector>
using std::vector;


class Organism; //forward declairation

class DoodleBug;// forward declairation

class Ant; // forward declairation

const int DEFAULTWIDTH = 20;
const int DEFAULTHEIGHT = 20;

class MaiWorldGrid
{

public:
MaiWorldGrid ( int width = DEFAULTWIDTH,
int height = DEFAULTHEIGHT );
CreatureType queryCell ( TwoDPoint position ); // Get creature type within cell.
TwoDPoint queryNearest ( CreatureType creature,
TwoDPoint position ); //Get nearest cell of creature type.
void killCell ( TwoDPoint position ); // remove creature at position
void moveCell ( TwoDPoint posSource,
TwoDPoint posDest ); // move creature from source to destination, removing creature at dest if exist
void createCell ( CreatureType creature,
TwoDPoint position ); // create creature at position, removing at position if already exist
void displayGrid (); // print grid to stdout
void populateGridRandom ( CreatureType creature,
int number ); // create number of creatures randomly around grid
void populateGridRandom ( CreatureType creature,
double percentage ); // create number of creatrues randomly around grid, perportional to the size of grid
void eatAll ( CreatureType creature );
void moveAll ( CreatureType creature );
void breedAll ( CreatureType creature );
void starveAll ( CreatureType creature );
void turnDone (CreatureType creature);

int getCount() { return creatureCount; }

private:
vector < vector <Organism *> > grid; // the game world grid
//list < Organism> creatures; // array of creatures on gameworld
int creatureCount;
};

#include "organism.h"
#include "organism.ant.h"
#include "organism.doodlebug.h"

#endif





maiworld.cpp


#include <iostream>
#include "maiworld.h"


MaiWorldGrid::MaiWorldGrid ( int width,
int height )
{
grid.resize ( height ); // make rows

for ( int i = 0;i < height;i++ ) grid[i].resize ( width );

for ( int row = 0; row < height;row++ )
for ( int col = 0; col < width; col++ )
grid[row][col] = NULL;

//for ( vector<vector<Organism*> >::iterator row = grid.begin();row < grid.end();row++ ) { //for each row
// grid[row].resize ( width, NULL ); // make columns, with value null in each
// }


creatureCount = 0;

}


CreatureType
MaiWorldGrid::queryCell ( TwoDPoint position )
{
// CHECK FOR IF OFF EDGE OF GRID

if ( position.x() < 0 || position.y() < 0 ) {
return BAD;
}

if ( position.x() >= grid.size() || position.y() >= grid[0].size() ) {
return BAD;
}

if ( grid[position.x() ][position.y() ] == NULL ) { // if NULL pointer
return EMPTY; // no creature there
} else {
return grid[position.x() ][position.y() ]->getType();
}



}


TwoDPoint
MaiWorldGrid::queryNearest ( CreatureType creature,
TwoDPoint position )
{
vector<TwoDPoint> templist;
TwoDPoint up = TwoDPoint ( position.x() + 1, position.y() );
TwoDPoint down = TwoDPoint ( position.x() - 1, position.y() );
TwoDPoint left = TwoDPoint ( position.x(), position.y() - 1 );
TwoDPoint right = TwoDPoint ( position.x (), position.y() + 1 );
/*UNCOMMENT FOR DIAGANALS!*/
// TwoDPoint upright = TwoDPoint ( position.x ()+1, position.y() +1 );
// TwoDPoint upleft = TwoDPoint ( position.x ()+1, position.y() -1);
// TwoDPoint downright = TwoDPoint ( position.x ()-1, position.y() +1 );
// TwoDPoint downleft = TwoDPoint( position.x ()-1, position.y() -1 );


//look for creature in all directions

if ( queryCell ( up ) == creature ) {
templist.push_back ( up );
}

if ( queryCell ( down ) == creature ) {
templist.push_back ( down );
}

if ( queryCell ( left ) == creature ) {
templist.push_back ( left );
}

if ( queryCell ( right ) == creature ) {
templist.push_back ( right );
}
/* UNCOMMENT FOR DIAGONALS!*/
// if ( queryCell ( upright ) == creature ) {
// templist.push_back ( upright );
// }
//
// if ( queryCell ( downright ) == creature ) {
// templist.push_back ( downright );
// }
//
// if ( queryCell ( upleft ) == creature ) {
// templist.push_back ( upleft );
// }
//
// if ( queryCell ( downleft ) == creature ) {
// templist.push_back ( downleft );
// }

//do stuff
if ( templist.size() == 0 ) { // no creatures found
return position; // return the middle
} else { // some creatures found
return templist[rand() % templist.size() ]; // return random creature
}


}


void
MaiWorldGrid::killCell ( TwoDPoint position )
{
Organism * temp; // create temp
temp = grid[position.x() ][position.y() ]; // copy organism to temp
grid[position.x() ][position.y() ] = NULL; // remove from grid
delete temp; // delete organism

// also need to delete from linked list


if ( creatureCount > 0 ) {
creatureCount--;
}
}


void
MaiWorldGrid::moveCell ( TwoDPoint posSource,
TwoDPoint posDest )
{
if ( grid[posDest.x() ][posDest.y() ] != NULL ) { // if something in dest
killCell ( posDest ); // kill it
posDest.print();
}

grid[posDest.x() ][posDest.y() ] = grid[posSource.x() ][posSource.y() ]; // move creature over
grid[posSource.x() ][posSource.y() ] = NULL; // remove from original location


}


void
MaiWorldGrid::createCell ( CreatureType creature,
TwoDPoint position )
{
Organism * temp;

if ( creature == ANT ) {
temp = new Ant ( *this, creature, position );
} else if ( creature == DOODLEBUG ) {
temp = new DoodleBug ( *this, creature, position );
} else if ( creature == NONE || creature == EMPTY ) {
temp = NULL;
}



if ( temp != NULL ) {
// add to linked list
grid[position.x() ][position.y() ] = temp;

creatureCount++;

}


}


void
MaiWorldGrid::displayGrid ()
{
std::cout << " /";

for ( int col = 0; col < grid[0].size(); col ++ ) { // for each col
std::cout << "-";
}

std::cout << "\\\n";




for ( int row = 0; row < grid.size(); row++ ) { //for each row
std::cout << " |";

for ( int col = 0; col < grid[row].size(); col ++ ) { // for each col

if ( grid[row][col] != NULL ) { // if creature
grid[row][col]->print(); // call creatures print
} else { // if no creature
std::cout << " "; // draw empty space
}
}


std::cout << "|\n";
}

std::cout << " \\";

for ( int col = 0; col < grid[0].size(); col ++ ) { // for each col
std::cout << "-";
}

std::cout << "/";

std::cout << std::endl;
}


void
MaiWorldGrid::populateGridRandom ( CreatureType creature, int number )
{
int maxCreatures = grid.size() * grid[0].size();


if ( number > maxCreatures - creatureCount ) { // if making too many creatuers
number = maxCreatures - creatureCount; // only create up to availble space
}

int row;
int col;
TwoDPoint position ( -1, -1 );
bool placed = false;


for ( int i = 0; i < number; i++ ) {
placed = false;

while ( !placed ) {
row = rand() % grid.size();
col = rand() % grid[0].size();

if ( grid[row][col] == NULL ) { // if no creature
position = TwoDPoint ( row, col );
createCell ( creature, position ); // create creature
placed = true;
}
}
}

}


void
MaiWorldGrid::populateGridRandom ( CreatureType creature, double percentage )
{
int maxCreatures = grid.size() * grid[0].size();
int number = static_cast<int> ( maxCreatures * percentage );

populateGridRandom ( creature, number ); // no sense writing redundant code :D



}


void
MaiWorldGrid::eatAll ( CreatureType creature )
{
for ( int row = 0; row < grid.size();row++ ) { //for each row

for ( int col = 0;col < grid[row].size();col++ ) { // for each col

if ( grid[row][col] != NULL ) { // if creature

if ( grid[row][col]->getType() == creature ) { //and the creature
grid[row][col]->eat(); // call creature's eat


}
}
}
}

}




void
MaiWorldGrid::moveAll ( CreatureType creature )
{
for ( int row = 0; row < grid.size();row++ ) { //for each row

for ( int col = 0;col < grid[row].size();col++ ) { // for each col

if ( grid[row][col] != NULL ) { // if creature

if ( grid[row][col]->getType() == creature ) { //and the creature
grid[row][col]->move(); // call creature's move

}
}
}
}
}



void
MaiWorldGrid::breedAll ( CreatureType creature )
{
for ( int row = 0; row < grid.size();row++ ) { //for each row

for ( int col = 0;col < grid[row].size();col++ ) { // for each col

if ( grid[row][col] != NULL ) { // if creature

if ( grid[row][col]->getType() == creature ) { //and the creature
grid[row][col]->breed(); // call creature's breed
}
}
}
}
}



void
MaiWorldGrid::starveAll ( CreatureType creature )
{
vector<Organism*> templist;

// find all starving creatures of creature type

for ( int row = 0; row < grid.size();row++ ) { //for each row

for ( int col = 0;col < grid[row].size();col++ ) { // for each col

if ( grid[row][col] != NULL ) { // if a creature

if ( grid[row][col]->getType() == creature ) { //and the creature type

if ( grid[row][col]->starve() ) {// if starving
templist.push_back ( grid[row][col] );
}
}
}
}
}


for ( int creature = 0;creature < templist.size();creature++ ) { //for each creature
killCell ( templist[creature]->getPosition() ); // kill creature
}
}

void
MaiWorldGrid::turnDone ( CreatureType creature )
{
for ( int row = 0; row < grid.size();row++ ) { //for each row

for ( int col = 0;col < grid[row].size();col++ ) { // for each col

if ( grid[row][col] != NULL ) { // if a creature

if ( grid[row][col]->getType() == creature ) { //and the creature type

grid[row][col]->unMoved();
}
}
}
}
}





organism.h

/******************************************************************************
| file | organism.h |
| author | 'Ultim'Ape-Iñago |
| date | 2006/11/13 |
| description | Defines the properties of a general organism |
\******************************************************************************/


#ifndef ORGANISM_H_INCLUDED
#define ORGANISM_H_INCLUDED

#include "enumerations.h"
#include "twodpoint.h"

class MaiWorldGrid; // forward declairation

class Organism
{

public:
Organism();
Organism ( MaiWorldGrid &worldGridRef,
CreatureType type,
TwoDPoint position );
void setType ( CreatureType type );
CreatureType getType();
void setWorld (MaiWorldGrid &worldGridRef );
MaiWorldGrid* getWorld();
void setPosition ( TwoDPoint position );
TwoDPoint getPosition();
bool hasMoved();
void Moved();
void unMoved();
virtual void eat() = 0;
virtual void move() = 0;
virtual void breed() = 0;
virtual bool starve() = 0;
virtual void print() = 0;

protected:
MaiWorldGrid *worldGrid;
CreatureType type;
TwoDPoint position;
bool isMoved;

};


#endif





organism.cpp

#include "organism.h"

Organism::Organism()
{
worldGrid = 0; // no refrence?
type = EMPTY; // "none"
position.set ( -1, -1 );
isMoved = false;
}

Organism::Organism ( MaiWorldGrid &worldGridRef, CreatureType type, TwoDPoint position )
{
setWorld ( worldGridRef );
setType ( type );
setPosition ( position );
isMoved = false;
}

void
Organism::setType ( CreatureType type )
{
this->type = type;
return;
}

CreatureType
Organism::getType()
{
return type;
}

void
Organism::setWorld ( MaiWorldGrid &worldGridRef )
{
this->worldGrid = &worldGridRef;
return;
}

MaiWorldGrid *
Organism::getWorld()
{
return worldGrid;
}

void
Organism::setPosition ( TwoDPoint position )
{
this->position = position;
return;
}

TwoDPoint
Organism::getPosition()
{
return position;
}

bool
Organism::hasMoved()
{
return isMoved;
}

void
Organism::Moved()
{
isMoved = true;
}

void
Organism::unMoved()
{
isMoved = false;
}





organism.doodlebug.h

/******************************************************************************
| file | organism.doodlebug.h |
| author | 'Ultim'Ape-Iñago |
| date | 2006/11/13 |
| description | Defines special properties of a doodlebug |
\******************************************************************************/


#ifndef ORGANISM_DOODLEBUG_H_INCLUDED
#define ORGANISM_DOODLEBUG_H_INCLUDED

#include "enumerations.h"
#include "twodpoint.h"
#include "organism.h"

class MaiWorldGrid;

class DoodleBug : public Organism
{

public:
DoodleBug();
DoodleBug ( MaiWorldGrid &WorldGridRef,
CreatureType type,
TwoDPoint position );
void eat();
void move();
void breed();
bool starve();
void print();

//protected:
// MaiWorldGrid &world;
// CreatureType type;
// TwoDPoint position;
// bool hasMoved;

private:
int hunger; // keeps track how hungry the creature is
int horny; // keeps track of how horny the creature is

};

#include "maiworld.h"

#endif





organism.doodlebug.cpp

#include <iostream>
#include "organism.doodlebug.h"

DoodleBug::DoodleBug() : Organism()
{
hunger = 0;
horny = 0;
}


DoodleBug::DoodleBug ( MaiWorldGrid &WorldGridRef,
CreatureType type,
TwoDPoint position )
: Organism ( WorldGridRef,
type,
position )
{
hunger = 0;
horny = 0;
}


void
DoodleBug::eat()
{
if ( hasMoved() ) { // if moved this turn
return; // do nothing

}
TwoDPoint dest = worldGrid->queryNearest ( ANT, position );

if (dest == position && hunger >=3) { // if super hungry
//dest = worldGrid->queryNearest (DOODLEBUG, position); // become canaible
}

if ( dest == position ) { // if not find food

return; // do not eat, do not collect move penatly
} else { // if found food

worldGrid->killCell ( dest ); // munch munch!

hunger = 0; // MMMmmm! food
horny++; // survived a turn, me so horny!
worldGrid->moveCell ( position, dest ); // move me there
position = dest;
Moved();
return; // done eating
}
}


void
DoodleBug::move()
{
if ( hasMoved() ) { // if moved this turn
return; // do nothing

}

horny++; // survived a turn, me so honry!
hunger++; // surived a turn, me so hungry!

TwoDPoint dest = worldGrid->queryNearest ( EMPTY, position );

if ( dest == position ) { // if no surrounding spot
Moved(); // has moved this turn

return; // do nothing
} else { // if found surrounding spot

worldGrid->moveCell ( position, dest ); // move me there
position = dest; // record the move
Moved(); // has moved this turn;
return; // done moving
}

}


void
DoodleBug::breed()
{
if ( horny >= 8 ) { // if want sex now!
TwoDPoint dest = worldGrid->queryNearest ( EMPTY, position );

if ( dest == position ) { // but no room for sex
return; // no sex for you
} else { // else if is room for sex
worldGrid->createCell ( DOODLEBUG, dest ); // yay sex!
horny = 0; // no more sex drive
return; // doen sexing
}
} else { // else not horny
return; // so do nothing
}
}

bool
DoodleBug::starve()
{
if ( hunger >= 3 ) { // if not eaten enough
return true; // should be killed
} else { // else
return false; // stay alive
}
}

void
DoodleBug::print()
{
std::cout<<"X";
}





organism.ant.h

/******************************************************************************
| file | organism.ant.h |
| author | 'Ultim'Ape-Iñago |
| date | 2006/11/13 |
| description | Defines special properties of an ant |
\******************************************************************************/


#ifndef ORGANISM_ANT_H_INCLUDED
#define ORGANISM_ANT_H_INCLUDED

#include "enumerations.h"
#include "twodpoint.h"
#include "organism.h"

class MaiWorldGrid;

class Ant : public Organism
{

public:
Ant();
Ant ( MaiWorldGrid &WorldGridRef,
CreatureType type,
TwoDPoint position );
void eat();
void move();
void breed();
bool starve();
void print();

//protected:
// MaiWorldGrid &world;
// CreatureType type;
// TwoDPoint position;
// bool hasMoved;

private:
int hunger;
int horny;


};

#include "maiworld.h"

#endif





organism.ant.cpp

#include <iostream>
#include "organism.ant.h"

Ant::Ant() : Organism()
{
hunger = 0;
horny = 0;
}


Ant::Ant ( MaiWorldGrid &WorldGridRef,
CreatureType type,
TwoDPoint position )
: Organism ( WorldGridRef,
type,
position )
{
hunger = 0;
horny = 0;
}


void
Ant::eat()
{
hunger = 0; // ants don't need to eat, intsa full
}


void
Ant::move()
{
if ( hasMoved() ) { // if moved this turn
return; // do nothing

}

horny++; // survived a turn, me so honry!
hunger++; // surived a turn, me so hungry!

TwoDPoint dest = worldGrid->queryNearest ( EMPTY, position );

if ( dest == position ) { // if no surrounding spot
Moved(); // has moved this turn

return; // do nothing
} else { // if found surrounding spot

worldGrid->moveCell ( position, dest ); // move me there
position = dest; // record the move
Moved(); // has moved this turn;
return; // done moving
}
}


void
Ant::breed()
{
if ( horny >= 1 ) { // if want sex now!
TwoDPoint dest = worldGrid->queryNearest ( EMPTY, position );

if ( dest == position ) { // but no room for sex
horny = 0;
return; // no sex for you
} else { // else if is room for sex
worldGrid->createCell ( ANT, dest ); // yay sex!
horny = 0; // no more sex drive
return; // doen sexing
}
}
}

bool
Ant::starve()
{
return false; // ants don't starve
}

void
Ant::print()
{
std::cout<<"o";
}



Share this post


Link to post
Share on other sites
KulSeran    3267
I sugest slow expantions into it.
Try to make a food chain, then a food tree.

Plants grow at a set rate per square so long as it still has growth on it.
A dead square "reseeds" after some time if there are plants ajacent.

Ants eat plants off a square at some rate till that square dies, or the ant
decides to move on.

Lions eat ants.

-------------
Lions chase ants.
Ants run from lions.
Lions run from large enough populations of ants.
Ants like to wonder, and dont always notice lions aproaching.

-------------
Add a second Ant like animal with different parameters.
Add a new Lion like animal with different parameters.
Add different plants that have different things that eat them.

ect.
ect.
ect.


There is TONES of room to make this into a fun little demo thing to watch and
tweek the parameters of.

Share this post


Link to post
Share on other sites
Ultimape    100
Quote:
Original post by KulSeran
I sugest slow expantions into it.
Try to make a food chain, then a food tree.

Plants grow at a set rate per square so long as it still has growth on it.
A dead square "reseeds" after some time if there are plants ajacent.

Ants eat plants off a square at some rate till that square dies, or the ant
decides to move on.

Lions eat ants.


Yes, I like where this is going... the ants as it is are basically just plants in that they are breeding (seeding) in random directions. Adding in a "grazing" option would be pretty neat funcitonality. Although it would be hard to tell if the ant was grazing or moving. Maybe things like trees and other non movable objects / varied terrain.

Quote:
Original post by KulSeranLions chase ants.
Ants run from lions.
Lions run from large enough populations of ants.
Ants like to wonder, and dont always notice lions aproaching.


I could expand the map's queryneraest into a quiry directonal... allowing the ants to look around... hehe, it'd be cool for lions to hide in thick vegitation.

I'd need some basic pathfinding or steering behavior... that would be realitively easy, if timeconsuming. Yay flocking!



Quote:
Original post by KulSeranAdd a second Ant like animal with different parameters.
Add a new Lion like animal with different parameters.
Add different plants that have different things that eat them.


Like cheetas (fast), leopards (ambush), crocidials (water only)... hmm. I should make it an entire african savhanna



Quote:
Original post by KulSeran
There is TONES of room to make this into a fun little demo thing to watch and
tweek the parameters of.


I should make the gameworld display not just in ascii, but in opengl. that would make it very interesting to watch.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this