Skip to content
Snippets Groups Projects
Commit 732ff107 authored by Aymeric berthoumieu's avatar Aymeric berthoumieu
Browse files

merge

parents 0653eef8 2a4ad4c4
No related branches found
No related tags found
1 merge request!20Aymeric
.idea/*
.idea
*.o
*.csv
main
......
......
SRCDIR := src/
main : main.cpp Aquarium.o Pet.o Environment.o
g++ -Wall -std=c++11 -o main main.cpp Aquarium.o Pet.o Environment.o -I $(SRCDIR) -lX11 -lpthread
main : main.cpp Aquarium.o Pet.o Environment.o Animal.o
g++ -Wall -std=c++11 -o main main.cpp Aquarium.o Pet.o Environment.o Animal.o -I $(SRCDIR) -lX11 -lpthread
Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Aquarium.cpp -I $(SRCDIR)
......@@ -9,7 +9,9 @@ Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
Pet.o : $(SRCDIR)Pet.h $(SRCDIR)Pet.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Pet.cpp -I $(SRCDIR)
Animal.o : $(SRCDIR)Animal.h $(SRCDIR)Animal.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Animal.cpp -I $(SRCDIR)
Environment.o : $(SRCDIR)Environment.h $(SRCDIR)Environment.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Environment.cpp -I $(SRCDIR)
# CPP Ecosystem Project
## Miscellaneous
This repository contains a directory *templates* which contains some code templates to get a common base for the coding styles adopted while developing this project.
It is highly recommended to have a look at these files before coding here.
SRCDIR := src/
TESTSDIR := tests/
testCollision : $(TESTSDIR)testCollision.cpp Aquarium.o Pet.o Environment.o
g++ -Wall -std=c++11 -o testCollision $(TESTSDIR)testCollision.cpp Aquarium.o Pet.o Environment.o -I $(SRCDIR) -lX11 -lpthread
testCollision : $(TESTSDIR)testCollision.cpp Aquarium.o Pet.o Environment.o Animal.o
g++ -Wall -std=c++11 -o testCollision $(TESTSDIR)testCollision.cpp Aquarium.o Pet.o Environment.o Animal.o -I $(SRCDIR) -lX11 -lpthread
Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Aquarium.cpp -I $(SRCDIR)
......@@ -10,5 +10,8 @@ Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
Pet.o : $(SRCDIR)Pet.h $(SRCDIR)Pet.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Pet.cpp -I $(SRCDIR)
Animal.o : $(SRCDIR)Animal.h $(SRCDIR)Animal.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Animal.cpp -I $(SRCDIR)
Environment.o : $(SRCDIR)Environment.h $(SRCDIR)Environment.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Environment.cpp -I $(SRCDIR)
\ No newline at end of file
SRCDIR := src/
TESTSDIR := tests/
testDeath1 : $(TESTSDIR)testDeath1.cpp Aquarium.o Pet.o Environment.o
g++ -Wall -std=c++11 -o testDeath1 $(TESTSDIR)testDeath1.cpp Aquarium.o Pet.o Environment.o -I $(SRCDIR) -lX11 -lpthread
testDeath1 : $(TESTSDIR)testDeath1.cpp Aquarium.o Pet.o Environment.o Animal.o
g++ -Wall -std=c++11 -o testDeath1 $(TESTSDIR)testDeath1.cpp Aquarium.o Pet.o Environment.o Animal.o -I $(SRCDIR) -lX11 -lpthread
Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Aquarium.cpp -I $(SRCDIR)
......@@ -10,5 +10,8 @@ Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
Pet.o : $(SRCDIR)Pet.h $(SRCDIR)Pet.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Pet.cpp -I $(SRCDIR)
Animal.o : $(SRCDIR)Animal.h $(SRCDIR)Animal.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Animal.cpp -I $(SRCDIR)
Environment.o : $(SRCDIR)Environment.h $(SRCDIR)Environment.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Environment.cpp -I $(SRCDIR)
\ No newline at end of file
SRCDIR := src/
TESTSDIR := tests/
testDeath2 : $(TESTSDIR)testDeath2.cpp Aquarium.o Pet.o Environment.o
g++ -Wall -std=c++11 -o testDeath2 $(TESTSDIR)testDeath2.cpp Aquarium.o Pet.o Environment.o -I $(SRCDIR) -lX11 -lpthread
testDeath2 : $(TESTSDIR)testDeath2.cpp Aquarium.o Pet.o Environment.o Animal.o
g++ -Wall -std=c++11 -o testDeath2 $(TESTSDIR)testDeath2.cpp Aquarium.o Pet.o Environment.o Animal.o -I $(SRCDIR) -lX11 -lpthread
Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Aquarium.cpp -I $(SRCDIR)
......@@ -10,5 +10,8 @@ Aquarium.o : $(SRCDIR)Aquarium.h $(SRCDIR)Aquarium.cpp
Pet.o : $(SRCDIR)Pet.h $(SRCDIR)Pet.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Pet.cpp -I $(SRCDIR)
Animal.o : $(SRCDIR)Animal.h $(SRCDIR)Animal.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Animal.cpp -I $(SRCDIR)
Environment.o : $(SRCDIR)Environment.h $(SRCDIR)Environment.cpp
g++ -Wall -std=c++11 -c $(SRCDIR)Environment.cpp -I $(SRCDIR)
\ No newline at end of file
#include "Animal.h"
#include "Environment.h"
#include <cstdlib>
#include <cmath>
const double Animal::AFF_SIZE = 8.;
const double Animal::MAX_SPEED = 10.;
const double Animal::LIMIT_VIEW = 30.;
int Animal::next = 0;
Animal::Animal() {
identity = ++next;
cout << "const Animal (" << identity << ") par défaut" << endl;
x = y = 0;
cumulX = cumulY = 0.;
probabilityOfFatalCollision = ((double) rand() / (RAND_MAX));
life = 10000 * ((double) rand() / (RAND_MAX));; // must be initialized randomly
orientation = static_cast<double>( rand() )/RAND_MAX*2.*M_PI;
speed = static_cast<double>( rand() )/RAND_MAX*MAX_SPEED;
color = new T[ 3 ];
color[ 0 ] = static_cast<int>( static_cast<double>( rand() )/RAND_MAX*230. );
color[ 1 ] = static_cast<int>( static_cast<double>( rand() )/RAND_MAX*230. );
color[ 2 ] = static_cast<int>( static_cast<double>( rand() )/RAND_MAX*230. );}
Animal::Animal( const Animal & a ){
identity = ++next;
cout << "const Animal (" << identity << ") par copie" << endl;
probabilityOfFatalCollision = ((double) rand() / (RAND_MAX));
life = 10000 * ((double) rand() / (RAND_MAX));; // must be initialized randomly
x = a.x;
y = a.y;
cumulX = cumulY = 0.;
orientation = a.orientation;
speed = a.speed;
color = new T[ 3 ];
memcpy( color, a.color, 3*sizeof(T) );}
Animal::~Animal( void ){
if (color != NULL){
delete[] color;
}
cout << "dest Pet" << endl;
}
Animal& Animal::operator=(Animal&& p) noexcept
{
// Guard self assignment
if (this == &p)
return *this; // delete[]/size=0 would also be ok
cout << "Affectation Pet(" << p.getIdentity() << ")" << endl;
identity = p.getIdentity();
probabilityOfFatalCollision = p.getProbabilityOfFatalCollision();
life = p.getLife(); // must be initialized randomly
x = p.x;
y = p.y;
cumulX = cumulY = 0.;
orientation = p.orientation;
speed = p.speed;
color = p.color;
p.color = NULL;
return *this;
}
// copy assignment
Animal& Animal::operator=(const Animal& p) noexcept
{
cout << "Affectation par copie" << endl;
// Guard self assignment
if (this == &p)
return *this;
identity = p.getIdentity();
probabilityOfFatalCollision = p.getProbabilityOfFatalCollision();
life = p.getLife(); // must be initialized randomly
x = p.x;
y = p.y;
cumulX = cumulY = 0.;
orientation = p.orientation;
speed = p.speed;
memcpy( color, p.color, 3*sizeof(T) );
return *this;
}
void Animal::initCoords( int xLim, int yLim ){
x = rand() % xLim;
y = rand() % yLim;}
void Animal::move( int xLim, int yLim ){
double nx, ny;
double dx = cos( orientation )*speed;
double dy = -sin( orientation )*speed;
int cx, cy;
cx = static_cast<int>( cumulX ); cumulX -= cx;
cy = static_cast<int>( cumulY ); cumulY -= cy;
nx = x + dx + cx;
ny = y + dy + cy;
if ( (nx < 0) || (nx > xLim - 1) ) {
orientation = M_PI - orientation;
cumulX = 0.;}
else {
x = static_cast<int>( nx );
cumulX += nx - x;}
if ( (ny < 0) || (ny > yLim - 1) ) {
orientation = -orientation;
cumulY = 0.;}
else {
y = static_cast<int>( ny );
cumulY += ny - y;}}
void Animal::action( Environment & myEnvironment ){
this->decrement();
if (life > 0) {
move( myEnvironment.getWidth(), myEnvironment.getHeight() );
}
}
void Animal::draw( UImg & support ){
double xt = x + cos( orientation )*AFF_SIZE/2.1;
double yt = y - sin( orientation )*AFF_SIZE/2.1;
support.draw_ellipse( x, y, AFF_SIZE, AFF_SIZE/5., -orientation/M_PI*180., color );
support.draw_circle( xt, yt, AFF_SIZE/2., color );}
bool operator==( const Animal & b1, const Animal & b2 ){
return ( b1.identity == b2.identity );}
bool Animal::isDetecting( const Animal & a ) const{
double dist;
dist = std::sqrt( (x-a.x)*(x-a.x) + (y-a.y)*(y-a.y) );
return ( dist <= LIMIT_VIEW );}
void Animal::decrement() {
// decrement the life of the animal
--life;
}
void Animal::onCollision(){
double proba = ((double) rand() / (RAND_MAX));
if (proba < this->getProbabilityOfFatalCollision()) {
cout << this->getIdentity() << " dies by collision" << endl;
life = 0;
}
}
int Animal::getLife() const {
return life;
}
int Animal::getIdentity() const {
return identity;
}
double Animal::getProbabilityOfFatalCollision() const {
return probabilityOfFatalCollision;
}
std::tuple<int, int> Animal::getCoordinates(){
return std::make_tuple(this->x,this->y);
}
// ############################## for tests ########################################
void Animal::setLife(int i){
life = i;
}
#ifndef _ANIMAL_H_
#define _ANIMAL_H_
#include "UImg.h"
#include <iostream>
#include <vector>
using namespace std;
class BehaviourStrategy;
class Environment;
class Animal{
protected:
static const double AFF_SIZE;
static const double MAX_SPEED;
static const double LIMIT_VIEW;
static int next;
int identity;
int x, y;
double cumulX, cumulY;
double orientation;
double speed;
int life;
double probabilityOfFatalCollision;
bool isMultiple; // for multiple behaviour type
float visibility;
BehaviourStrategy* behaviour;
T* color;
void move(int xLim, int yLim);
public :
Animal();
Animal(const Animal& a); // copy cstor
Animal(Animal&& a); // move cstor
virtual ~Animal();
friend bool operator==(const Animal& a1, const Animal& a2);
Animal& operator=(Animal&& a) noexcept; // move cstor by assignment
Animal& operator=(const Animal& a) noexcept; // assignment
void initCoords(int xLim, int yLim);
std::tuple<int, int> getCoordinates();
void setCoordinates(int new_x, int new_y);
tuple<double, double> getCumul();
void setCumul(double new_cumul_x, double new_cumul_y);
tuple<double, double> getOrientationSpeed();
void setOrientationSpeed(double new_orientation, double new_speed);
float getVisibility();
double getMaxSpeed();
vector<string> getAccessoriesAndCaptors();
int getIdentity() const;
int getLife() const;
double getProbabilityOfFatalCollision() const;
void decrement();
void onCollision();
void action(Environment& myEnvironment);
void draw(UImg& support);
bool isDetecting(const Animal& a) const;
void changeBehaviour();
// for tests
void setLife(int i);
};
#endif
#include "Aquarium.h"
#include "Environment.h"
#include "Statistics.h"
Aquarium::Aquarium( int width, int height, int _delay ) : CImgDisplay(), delay( _delay ){
......@@ -8,7 +9,10 @@ Aquarium::Aquarium( int width, int height, int _delay ) : CImgDisplay(), delay(
cout << "const Aquarium" << endl;
water = new Environment( width, height );
vector<string> names;
Statistics* stats = new Statistics(names);
water = new Environment( width, height, petcreator, stats );
assign( *water, "Simulation d'écosystème" );
move( static_cast<int>((screenWidth-width)/2), static_cast<int>((screenHeight-height)/2) );
......@@ -21,7 +25,6 @@ Aquarium::~Aquarium( void ){
void Aquarium::run( void ){
cout << "running Aquarium" << endl;
while ( ! is_closed() ){
// cout << "iteration de la simulation" << endl;
if ( is_key() ) {
cout << "Vous avez pressé la touche " << static_cast<unsigned char>( key() );
cout << " (" << key() << ")" << endl;
......
......
File changed. Contains only whitespace changes. Show whitespace changes.
<<<<<<< HEAD
#include "Environment.h"
#include "Statistics.h"
#include <cstdlib>
#include <ctime>
#include <math.h>
#include <memory>
#include <vector>
const std:
string multiple = "b_multiple" // name for multiple behaviour
const T Environment::white[] = {(T) 255, (T) 255, (T) 255};
Environment::Environment(int _width, int _height) : UImg(_width, _height, 1, 3), width(_width), height(_height),
nb_steps(0) {
Environment::Environment(int _width, int _height) : UImg(_width, _height, 1, 3), width(_width),
height(_height), nb_steps(0) {
cout << "const Environment" << endl;
std::srand(time(NULL));
}
......@@ -19,32 +21,50 @@ Environment::~Environment() {
cout << "dest Environment" << endl;
}
int Environment::getWidth() const {
return width;
}
int Environment::getHeight() const {
return height;
}
void Environment::step() {
++nb_steps;
++nb_steps; // increment the number of steps
statistics.saveData(); // save statistics of the previous step before doing the new one
cimg_forXY(*this, x, y)
fillC(x, y, 0, white[0], white[1], white[2]);
for (std::vector<Pet>::iterator it = pets.begin(); it != pets.end(); ++it) {
for (std::vector<Animal>::iterator it = animals.begin(); it != animals.end(); ++it) {
hasCollision(*it); // check if there is a collision
it->action(*this);
it->action(*this); // let the animal do the action he has to do
// we draw only if the pet is still alive
if (it->getLife() > 0) {
it->draw(*this);
}
}
this->die();
this->die(); // delete the dead animals
}
int Environment::nbNeighbors(const Pet &p) {
int Environment::nbNeighbors(const Animal &a) {
// find all animals that a can detect
int nb = 0;
//for (std::vector<Pet>::iterator it = pets.begin() ; it != pets.end() ; ++it)
// if (!(p == *it) && p.iSeeYou(*it))
// ++nb;
for (std::vector<Animal>::iterator it = animals.begin(); it != animals.end(); ++it)
if (!(a == *it) && a.isDetecting(*it))
++nb;
return nb;
}
bool mustDie(Pet const &p) {
void Environment::addMember(const Animal &a) {
// add an animal to the ecosystem
this->animals.push_back(a);
this->animals.back().initCoords(width, height);
}
bool mustDie(Animal const &p) {
// return true if the p has a life < 0. It means p must die at the end of the step
if (p.getLife() <= 0) {
cout << " Pets (" << p.getIdentity() << ") is gonna be destructed with life = " << p.getLife() << endl;
}
......@@ -52,28 +72,53 @@ bool mustDie(Pet const &p) {
}
void Environment::die() {
cout << "At step <" << nb_steps << "> : " << endl;
auto it = std::remove_if(pets.begin(), pets.end(), mustDie);
pets.erase(it, pets.end());
// kill animal in the ecosystem at the end of the step
// first we identify the animals to remove (if any)
auto it = std::remove_if(animals.begin(), animals.end(), mustDie);
// then we update Statistics
for (std::vector<Animal>::iterator iter = it; iter != animals.end(); ++iter) {
// All animal at the end of the vector at this step are going to die
// Behaviours
if (iter->getIsMultiple()) {
statistics.modifyData(multiple, false);
} else {
std::string behaviour = iter->getBehaviourName();
statistics.modifyData(behaviour, false);
}
// Captors and accessories
std::vector <std::string> acc = iter->getAccessoriesAndCaptors();
for (string element : acc) {
statistics.modifyData(element, false);
}
}
// Finally, we delete the relevant animals
animals.erase(it, animals.end());
}
void Environment::hasCollision(Pet &p) {
int id = p.getIdentity();
void Environment::hasCollision(Animal &p) {
// Check if p has a collision with another animal
int id = p.getIdentity(); // unique id of p
double r = 15; // collision radius
std::tuple<int, int> pet_coords = p.getCoordinates();
std::tuple<int, int> current_coords;
double dist;
std::tuple<int, int> pet_coords = p.getCoordinates(); // coordinates of p
std::tuple<int, int> current_coords; // will be used to contain coordinates of other animals
double dist; // will me used to store the distance between p and another animal
for (std::vector<Pet>::iterator it = pets.begin(); it != pets.end(); ++it) {
// we check for every other animals
for (std::vector<Animal>::iterator it = animals.begin(); it != animals.end(); ++it) {
// first we verify if the animal is not itself
if (it->getIdentity() != id) {
current_coords = it->getCoordinates();
current_coords = it->getCoordinates(); // get the other animal coordinates
// calculation of the distance between the two animals
dist = std::pow((std::pow((double(std::get<0>(pet_coords)) - double(std::get<0>(current_coords))), 2) +
std::pow((double(std::get<1>(pet_coords)) - double(std::get<1>(current_coords))), 2)), 0.5);
std::pow((double(std::get<1>(pet_coords)) - double(std::get<1>(current_coords))), 2)),
0.5);
// if the two animals are close enough (distance lower than the radius of collision) there is a collision
if (dist <= r) {
cout << "Collision of " << p.getIdentity() << endl;
p.onCollision();
p.onCollision(); // notify the animal it has a collision
}
}
}
......@@ -82,8 +127,10 @@ void Environment::hasCollision(Pet &p) {
// ############################## for tests ########################################
void Environment::setLife(int i) {
// Set life to all pets at i
// It is only used for nominal test purpose
cout << "[TEST] Setting life of all pets at " << i << "." << endl;
for (std::vector<Pet>::iterator it = pets.begin(); it != pets.end(); ++it) {
for (std::vector<Animal>::iterator it = animals.begin(); it != animals.end(); ++it) {
it->setLife(i);
}
}
......@@ -3,7 +3,8 @@
#include "UImg.h"
#include "Pet.h"
#include "Animal.h"
#include "Statistics.h"
#include <iostream>
#include <vector>
......@@ -11,24 +12,35 @@
using namespace std;
class AnimalFactory;
class Statistics;
class Environment : public UImg{
static const T white[];
int width, height;
std::vector<Pet> pets;
std::vector<Animal> animals;
int nb_steps;
std::vector<float> natalityRatios;
float cloningProbability;
AnimalFactory& petCreator();
Statistics& statistics;
public :
Environment(int _width, int _height);
~Environment();
int getWidth() const { return width; };
int getHeight() const { return height; };
int getWidth() const;
int getHeight() const;
void step();
void hasCollision(Animal& a);
void die();
void hasCollision(Pet & p);
void addMember(const Pet & p) { pets.push_back(p); pets.back().initCoords(width, height); };
int nbNeighbors(const Pet & p);
void addMember(const Animal& a);
void addMembersAtRuntime();
void chooseMembersToClone();
void addMemberToclone(Animal* a);
void cloneMembers();
int nbNeighbors(const Animal& a);
std::vector<Animal> detectedNeighbors(Animal& a);
// for test
void setLife(int i);
......
......
#include "Pet.h"
#include "Animal.h"
#include "Environment.h"
#include <cstdlib>
#include <cmath>
#include <memory>
const double Pet::AFF_SIZE = 8.;
const double Pet::MAX_SPEED = 10.;
const double Pet::LIMIT_VIEW = 30.;
int Pet::next = 0;
Pet::Pet( void ){
identity = ++next;
cout << "const Pet (" << identity << ") par défaut" << endl;
x = y = 0;
cumulX = cumulY = 0.;
probabilityOfFatalCollision = ((double) rand() / (RAND_MAX));
life = 10000 * probabilityOfFatalCollision; // must be initialized randomly
orientation = static_cast<double>( rand() )/RAND_MAX*2.*M_PI;
speed = static_cast<double>( rand() )/RAND_MAX*MAX_SPEED;
color = new T[ 3 ];
color[ 0 ] = static_cast<int>( static_cast<double>( rand() )/RAND_MAX*230. );
color[ 1 ] = static_cast<int>( static_cast<double>( rand() )/RAND_MAX*230. );
color[ 2 ] = static_cast<int>( static_cast<double>( rand() )/RAND_MAX*230. );}
Pet::Pet( const Pet & p ){
identity = ++next;
cout << "const Pet (" << identity << ") par copie" << endl;
probabilityOfFatalCollision = ((double) rand() / (RAND_MAX));
life = 10000 * probabilityOfFatalCollision; // must be initialized randomly
x = p.x;
y = p.y;
cumulX = cumulY = 0.;
orientation = p.orientation;
speed = p.speed;
color = new T[ 3 ];
memcpy( color, p.color, 3*sizeof(T) );}
Pet& Pet::operator=(Pet&& p) noexcept
{
// Guard self assignment
if (this == &p)
return *this; // delete[]/size=0 would also be ok
cout << "Affectation Pet(" << p.getIdentity() << ")" << endl;
identity = p.getIdentity();
probabilityOfFatalCollision = p.getProbabilityOfFatalCollision();
life = p.getLife(); // must be initialized randomly
x = p.x;
y = p.y;
cumulX = cumulY = 0.;
orientation = p.orientation;
speed = p.speed;
color = p.color;
p.color = NULL;
return *this;
}
// copy assignment
Pet& Pet::operator=(const Pet& p)
{
cout << "Affectation par copie" << endl;
// Guard self assignment
if (this == &p)
return *this;
identity = p.getIdentity();
probabilityOfFatalCollision = p.getProbabilityOfFatalCollision();
life = p.getLife(); // must be initialized randomly
x = p.x;
y = p.y;
cumulX = cumulY = 0.;
orientation = p.orientation;
speed = p.speed;
memcpy( color, p.color, 3*sizeof(T) );
return *this;
}
Pet::~Pet( void ){
if (color != NULL){
delete[] color;
}
cout << "dest Pet" << endl;
}
std::tuple<int, int> Pet::getCoordinates(){
return std::make_tuple(this->x,this->y);
}
void Pet::initCoords( int xLim, int yLim ){
x = rand() % xLim;
y = rand() % yLim;}
void Pet::move( int xLim, int yLim ){
double nx, ny;
double dx = cos( orientation )*speed;
double dy = -sin( orientation )*speed;
int cx, cy;
cx = static_cast<int>( cumulX ); cumulX -= cx;
cy = static_cast<int>( cumulY ); cumulY -= cy;
nx = x + dx + cx;
ny = y + dy + cy;
if ( (nx < 0) || (nx > xLim - 1) ) {
orientation = M_PI - orientation;
cumulX = 0.;}
else {
x = static_cast<int>( nx );
cumulX += nx - x;}
if ( (ny < 0) || (ny > yLim - 1) ) {
orientation = -orientation;
cumulY = 0.;}
else {
y = static_cast<int>( ny );
cumulY += ny - y;}}
void Pet::action( Environment & myEnvironment ){
this->decrement();
if (life > 0) {
move( myEnvironment.getWidth(), myEnvironment.getHeight() );
}
}
void Pet::draw( UImg & support ){
double xt = x + cos( orientation )*AFF_SIZE/2.1;
double yt = y - sin( orientation )*AFF_SIZE/2.1;
support.draw_ellipse( x, y, AFF_SIZE, AFF_SIZE/5., -orientation/M_PI*180., color );
support.draw_circle( xt, yt, AFF_SIZE/2., color );}
bool operator==( const Pet & b1, const Pet & b2 ){
return ( b1.identity == b2.identity );}
bool Pet::isDetecting( const Pet & p ) const{
double dist;
dist = std::sqrt( (x-p.x)*(x-p.x) + (y-p.y)*(y-p.y) );
return ( dist <= LIMIT_VIEW );}
void Pet::decrement() {
// decrement the life of the animal
--life;
}
void Pet::onCollision(){
double proba = ((double) rand() / (RAND_MAX));
if (proba < this->getProbabilityOfFatalCollision()) {
cout << this->getIdentity() << " dies by collision" << endl;
life = 0;
}
}
// ############################## for tests ########################################
void Pet::setLife(int i){
life = i;
}
\ No newline at end of file
Pet::Pet(): Animal(){};
Pet::~Pet() {};
......@@ -2,6 +2,7 @@
#define _PETS_H_
#include "UImg.h"
#include "Animal.h"
#include <iostream>
......@@ -11,48 +12,10 @@ using namespace std;
class Environment;
class Pet{
static const double AFF_SIZE;
static const double MAX_SPEED;
static const double LIMIT_VIEW;
static int next;
int identity;
int x, y;
double cumulX, cumulY;
double orientation;
double speed;
int life;
double probabilityOfFatalCollision;
T* color;
void move(int xLim, int yLim);
class Pet: public Animal{
public :
Pet();
Pet(const Pet& p); // copy cstor
Pet( Pet && p ); // move cstor
~Pet();
Pet& operator=(Pet&& p) noexcept; //move constructor by assignment
Pet& operator=(const Pet& p); // assignment
void action(Environment& myEnvironment);
void draw(UImg& support);
bool isDetecting(const Pet& p) const;
void initCoords(int xLim, int yLim);
void decrement();
void onCollision();
tuple<int, int> getCoordinates();
int getIdentity() const {return identity;};
int getLife() const {return life;};
double getProbabilityOfFatalCollision() const {return probabilityOfFatalCollision;};
friend bool operator==(const Pet& p1, const Pet& p2);
// for tests
void setLife(int i);
};
#endif
......@@ -17,15 +17,18 @@ using namespace std;
mutex logMutex;
bool fileExists(string& fileName) {
// check if the file named fileName exist or not
return static_cast<bool>(ifstream(fileName));
}
bool writeCsvFile(string &fileName, map<string,int> data, vector<string> headers) {
// write data in csv file
lock_guard<mutex> csvLock(logMutex);
fstream file;
file.open (fileName, ios::out | ios::app);
if (file) {
// add a line to the csv file with the data
for (vector<string>::iterator it = headers.begin(); it != headers.end(); ++it){
file << data[*it] << ",";
}
......@@ -36,11 +39,13 @@ bool writeCsvFile(string &fileName, map<string,int> data, vector<string> headers
}
bool writeHeadersCsvFile(string &fileName, vector<string> headers) {
// write the headers to the csv file
lock_guard<mutex> csvLock(logMutex);
fstream file;
file.open (fileName, ios::out | ios::app);
if (file) {
// add the headers to the file
for (vector<string>::iterator it = headers.begin(); it != headers.end(); ++it){
file << *it << ",";
}
......@@ -52,6 +57,7 @@ bool writeHeadersCsvFile(string &fileName, vector<string> headers) {
Statistics::Statistics(vector<string> behaviorAccessoriesCaptorsNames){
headers = behaviorAccessoriesCaptorsNames;
// save the headers add initialize them at 0
for(vector<string>::iterator it = headers.begin(); it != headers.end(); ++it){
data.insert(pair<string,int>(*it,0) );
}
......@@ -61,16 +67,20 @@ Statistics::Statistics(vector<string> behaviorAccessoriesCaptorsNames){
char* dt = ctime(&now);
csvFile = strcat(dt, "-statistics.csv");
// if the file does not exists, we create it and add the headers
if(!fileExists(csvFile)){writeHeadersCsvFile(csvFile, headers);}
else{cerr << "File " << csvFile << " already exist." << endl;}
}
void Statistics::modifyData(string key, bool increment){
// modify the data contained in header with the key "key". If increment is at true the data takes +1,
// else the data takes -1
if (increment){data[key] = data[key] + 1;}
else{data[key] = data[key] - 1;}
}
void Statistics::saveData(){
// save the current stage of headers in the csv file
if (!writeCsvFile(csvFile, data, headers)) {
std::cerr << "Failed to write to file: " << csvFile << "\n";
}
......
......
......@@ -3,6 +3,7 @@
//
#include "Aquarium.h"
#include "Environment.h"
#include "Animal.h"
#include "Pet.h"
#include <iostream>
......
......
......@@ -3,6 +3,7 @@
//
#include "Aquarium.h"
#include "Environment.h"
#include "Animal.h"
#include "Pet.h"
#include <iostream>
......
......
......@@ -3,6 +3,7 @@
//
#include "Aquarium.h"
#include "Environment.h"
#include "Animal.h"
#include "Pet.h"
#include <iostream>
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment