00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <thread.h>
00024 #include <math.h>
00025 #include "cylinder.h"
00026 #include "log.h"
00027 #include "world.h"
00028 #include "agent.h"
00029
00030
00031
00032
00033
00034 Cylinder *Cylinder::grow(GrowType type, unsigned short int usedEnergy){
00035 double grow=usedEnergy*0.95;
00036
00037
00038 if (type==growHorizontal)
00039 width=sqrt((mass+grow)/(2*M_PI*height));
00040 else{
00041 height=((mass+grow)/(2*M_PI*width*width));
00042 }
00043
00044 mass=2*M_PI*width*width*height;
00045 energy-=grow;
00046
00047 return dropEnergy(usedEnergy*0.05);
00048 }
00049
00050
00051
00052
00053 Cylinder *Cylinder::move(MoveType type, unsigned short int usedEnergy){
00054 if (father==NULL){
00055 log <<"Can't move cylinder without parent, energy not wasted"<<endl;
00056 }
00057
00058 if (type==moveVerticalCW){
00059
00060
00061 }
00062 else if (type==moveVerticalCCW){
00063
00064
00065 }
00066 else if (type==moveHorizontalCW){
00067
00068
00069 }
00070 else if (type==moveHorizontalCCW){
00071
00072
00073 }
00074
00075 else{
00076 log <<"Wrong movement type ("<<int(type)<<")"<<endl;
00077 }
00078
00079
00080 double relation=energy/mass;
00081 double dropE=(log10(relation+1)/(relation*2))*log10(usedEnergy+1);
00082 energy-=(usedEnergy-dropE);
00083 return dropEnergy(dropE);
00084 }
00085
00086
00087
00088
00089 Cylinder *Cylinder::drop(unsigned char sonId, const char *creationMessage, unsigned long messageSize){
00090 Cylinder *cyl=NULL;
00091 unsigned short int i;
00092 for (i=son.size();i--;)
00093 if (son[i]->cylinderId==sonId){
00094 cyl=son[i];
00095 break;
00096 }
00097
00098 if (NULL==cyl){
00099 log <<"Can't drop NULL cylinder or it's not a direct son!"<<endl;
00100 return NULL;
00101 }
00102
00103 son.erase(&son[i]);
00104
00105 World *world=getWorld();
00106 if (NULL==world){
00107 log <<"Can't drop if you are not in a world!!"<<endl;
00108 return NULL;
00109 }
00110
00111 world->newAgent(cyl, creationMessage, messageSize);
00112
00113 return NULL;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 Cylinder *Cylinder::createCylinder(double angle, double atHeight, unsigned short int usedEnergy){
00123 energy-=usedEnergy;
00124
00125 orientationBase.normalize();
00126
00127 double h=7*usedEnergy/(16*M_PI*width*width);
00128
00129 Cylinder *cyl=new Cylinder(world, this, usedEnergy/8, width,h,
00130 Vector3d(atHeight, angle, 0), true);
00131
00132 son.push_back(cyl);
00133
00134 return NULL;
00135 }
00136
00137
00138
00139
00140 Cylinder *Cylinder::sendEnergyTo(unsigned char son, unsigned short usedEnergy){
00141 Cylinder *cyl=(*this)[son];
00142 if (NULL==cyl)
00143 return NULL;
00144
00145 energy-=usedEnergy;
00146
00147 cyl->energy+=usedEnergy;
00148
00149 return NULL;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 Cylinder *Cylinder::dropEnergy(double droppedEnergy){
00160 return NULL;
00161 energy-=droppedEnergy;
00162
00163 double h=cbrt(droppedEnergy/(576*M_PI));
00164
00165
00166
00167
00168
00169
00170
00171
00172 return new Cylinder(world, this, droppedEnergy*7/8, h*6,h,
00173 Vector3d(cos(energy*mass),energy,0), false);
00174 }
00175
00176 Cylinder *Cylinder::sendMessage(unsigned long int _agentId, const char *message, unsigned long int size){
00177 if (agent==NULL)
00178 return NULL;
00179
00180 unsigned long int agentId=agent->getId();
00181
00182
00183
00184
00185 world->addMessage(message,size,agent);
00186
00187 if (_agentId==agentId)
00188 return NULL;
00189
00190 Agent *agent=world->getAgent(_agentId);
00191 if (NULL==agent)
00192 return NULL;
00193 agent->receiveMessage(agentId, message, size);
00194
00195 return NULL;
00196 }
00197
00198
00199
00200
00201
00202 Cylinder *Cylinder::performAction(){
00203 Cylinder *ret=NULL;
00204 switch(desiredAction.action){
00205 case growTo:
00206 ret=grow(GrowType(desiredAction.growType), desiredAction.energy);
00207 break;
00208 case newCylinder:
00209 ret=createCylinder(desiredAction.angle, desiredAction.height, desiredAction.energy);
00210 break;
00211 case sendEnergy:
00212 ret=sendEnergyTo(desiredAction.cylinder, desiredAction.energy);
00213 break;
00214 case moveCylinder:
00215 ret=move(desiredAction.moveType, desiredAction.energy);
00216 break;
00217 case dropCylinder:
00218 ret=drop(desiredAction.cylinder, desiredAction.message, desiredAction.messageSize);
00219 break;
00220 case sendMessageAction:
00221 ret=sendMessage(desiredAction.agentId, desiredAction.message, desiredAction.messageSize);
00222 break;
00223 case none:
00224 break;
00225 default:
00226 log <<"desired Action "<<int(desiredAction.action)<<" not implemented yet"<<endl;
00227 break;
00228 }
00229
00230 desiredAction=Action();
00231 return ret;
00232 }
00233