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 "client.h"
00026 #include "agent.h"
00027 #include "log.h"
00028 #include "world.h"
00029 #include "message.h"
00030
00031 #ifndef M_PI
00032 # define M_PI 3.14159265358979323846
00033 #endif
00034
00035 Client::~Client(){
00036 world->clientOut(this);
00037 }
00038
00039 Client::Client(ost::TCPSocket &sock, World *w) : baseClient(sock,w){
00040 initialize();
00041 }
00042
00043 void Client::Run(void){
00044 log <<"Run Agent Client"<<endl;
00045
00046 try{
00047 while(1){
00048 Message msg(stream);
00049 switch(msg.type){
00050 case messageNewCylinder:
00051 newCylinder(msg);
00052 break;
00053 case messageGrow:
00054 grow(msg);
00055 break;
00056 case messageSendEnergy:
00057 sendEnergy(msg);
00058 break;
00059 case messageMove:
00060 move(msg);
00061 break;
00062 case messageDrop:
00063 dropCylinder(msg);
00064 break;
00065 case messageSendMessage:
00066 sendMessage(msg);
00067 break;
00068 case messageLog:
00069 clientLog(msg);
00070 break;
00071 case messageEndOfTurn:
00072 endOfTurn(msg);
00073 break;
00074 default:
00075 log <<"Unknown message type "<<msg.type<<endl;
00076 }
00077 }
00078 }
00079 catch(...){
00080 log <<"Exception caught! Exiting client!"<<endl;
00081 alive=false;
00082 return;
00083 }
00084
00085 alive=false;
00086 log <<"End of Agent Client"<<endl;
00087 }
00088
00089 void Client::initialize(){
00090
00091 char version;
00092 version=stream->get();
00093 log<<"Client protocol version is "<<int(version)<<"."<<endl;
00094 if (version!=0x00){
00095 log <<"Invalid version!!!"<<endl;
00096 alive=false;
00097 return;
00098 }
00099
00100
00101 char c; name="";
00102 c=stream->get();
00103 while(c!=0){
00104 name+=c;
00105 *stream>>c;
00106 }
00107 log <<"Client name: "<<name<<endl;
00108
00109
00110
00111 Agent *ag=new Agent(this,Point3d(0,0,15),NULL,0);
00112 log <<"First agent of client in "<<(*ag)[0]->getPosition().toString()<<endl;
00113 world->newAgent(ag);
00114 }
00115
00116
00117
00118
00119 void Client::newCylinder(Message &msg){
00120 if (msg.size!=4){
00121 log <<"Bad newCylinder message"<<endl;
00122 return;
00123 }
00124 unsigned char cyl=msg.umsg[0];
00125 double angle=(((unsigned char)msg.umsg[1])*2*M_PI)/256.0;
00126 double height=((unsigned char)msg.umsg[2])/255.0;
00127 unsigned short energy=msg.umsg[3];
00128
00129
00130
00131 Agent *agent=world->getAgent(msg.organismId);
00132 Cylinder *cylinder=NULL;
00133 if (NULL!=agent)
00134 cylinder=(*agent)[cyl];
00135 if (cylinder==NULL){
00136 log <<"Cylinder or agent does not exist!"<<int(cyl)<<endl;
00137 msg.size=0;
00138 }
00139 else{
00140 if (cylinder->getEnergy()>=energy){
00141
00142
00143 cylinder->newIntention(Action(angle, height, energy));
00144
00145
00146 msg.size=1;
00147 msg.msg[0]=agent->getCylinderCount();
00148 }
00149 else{
00150 msg.size=0;
00151 }
00152 }
00153
00154 msg.petition=false;
00155
00156 msg.sendTo(stream);
00157 stream->sync();
00158 }
00159
00160
00161
00162
00163
00164 void Client::dropCylinder(Message &msg){
00165 if (msg.size<1){
00166 log <<"Bad dropCylinder message"<<endl;
00167 return;
00168 }
00169 unsigned char cyl=msg.umsg[0];
00170
00171 Agent *agent=world->getAgent(msg.organismId);
00172 Cylinder *cylinder=NULL;
00173 if (agent!=NULL)
00174 cylinder=(*agent)[cyl];
00175
00176 if (cylinder==NULL){
00177 log <<"Cylinder or agent does not exist!"<<int(cyl)<<endl;
00178 msg.size=0;
00179 }
00180 else{
00181 cylinder=cylinder->getFather();
00182 if (cylinder==NULL){
00183 log <<"Can't drop 1st cylinder of agent"<<endl;
00184 msg.size=0;
00185 }
00186 else{
00187 cylinder->newIntention(Action(cyl, msg.msg+1, msg.size-1));
00188 }
00189 }
00190
00191 msg.petition=false;
00192 msg.sendTo(stream);
00193 stream->sync();
00194 }
00195
00196
00197
00198
00199
00200
00201 void Client::sendMessage(Message &msg){
00202 if (msg.size<4){
00203 log <<"Bad sendMessage message"<<endl;
00204 return;
00205 }
00206
00207 Agent *agent=world->getAgent(msg.organismId);
00208
00209 long agentId=((msg.umsg[0]&0x0FF)<<24)+((msg.umsg[1]&0x0FF)<<16)+
00210 ((msg.umsg[2]&0x0FF)<<8 )+((msg.umsg[3]&0x0FF));
00211 char *message=&(msg.msg[4]);
00212
00213 Cylinder *cyl=(*agent)[0];
00214 if (NULL==cyl)
00215 log <<"this agent cant' send messages"<<endl;
00216 else
00217 cyl->newIntention(Action(agentId, msg.size-4, message));
00218
00219 msg.size=0;
00220 msg.petition=false;
00221 msg.sendTo(stream);
00222 stream->sync();
00223 }
00224
00225
00226
00227
00228
00229
00230 void Client::sendEnergy(Message &msg){
00231 if (msg.size!=3){
00232 log <<"Bad sendEnergy message"<<endl;
00233 return;
00234 }
00235 unsigned char cyl1=msg.umsg[0];
00236 unsigned char cyl2=msg.umsg[1];
00237 unsigned char energy=msg.umsg[2];
00238
00239
00240
00241 Agent *agent=world->getAgent(msg.organismId);
00242 Cylinder *cylinder1=NULL,*cylinder2=NULL;
00243 if (NULL!=agent){
00244 cylinder1=(*agent)[cyl1];
00245 cylinder2=(*agent)[cyl2];
00246 }
00247 if ((cylinder1==NULL)||(cylinder2==NULL)){
00248 log <<"Cylinder(s) or agent does not exist!"<<int(cyl1)<<" "<<int(cyl2)<<endl;
00249 msg.size=0;
00250 }
00251 else{
00252 if (cylinder1->dist(cylinder2)==1)
00253 if (cylinder1->getEnergy()>=energy)
00254 cylinder1->newIntention(Action(cyl2, energy));
00255 else
00256 msg.size=0;
00257 else if (cylinder2->dist(cylinder1)==1)
00258 if (cylinder2->getEnergy()>=energy)
00259 cylinder2->newIntention(Action(cyl1, energy));
00260 else
00261 msg.size=0;
00262 else
00263 msg.size=0;
00264 }
00265
00266 msg.petition=false;
00267 msg.sendTo(stream);
00268 stream->sync();
00269 }
00270
00271
00272
00273
00274 void Client::grow(Message &msg){
00275 if (msg.size!=2){
00276 log <<"Bad grow message"<<endl;
00277 return;
00278 }
00279 unsigned char cyl=msg.umsg[0];
00280 GrowType type=((msg.umsg[1]>>7)&1) ? growVertical : growHorizontal;
00281 unsigned short int energy=msg.umsg[1]&0x07F;
00282
00283
00284 msg.petition=false;
00285
00286 Agent *agent=world->getAgent(msg.organismId);
00287
00288 Cylinder *cylinder=NULL;
00289 if (NULL!=agent)
00290 cylinder=(*agent)[cyl];
00291 if (cylinder==NULL){
00292 log <<"Cylinder or agent does not exist!"<<int(cyl)<<endl;
00293 msg.size=0;
00294 }
00295 else{
00296 if (cylinder->getEnergy()>=energy){
00297
00298
00299 cylinder->newIntention(Action(energy, type));
00300
00301
00302 }
00303 else{
00304 msg.size=0;
00305 }
00306 }
00307
00308 msg.petition=false;
00309 msg.sendTo(stream);
00310 stream->sync();
00311 }
00312
00313
00314
00315
00316 void Client::move(Message &msg){
00317 if (msg.size!=3){
00318 log <<"Bad move message"<<endl;
00319 return;
00320 }
00321 unsigned char cyl=msg.umsg[0];
00322 MoveType type=moveUnknown;
00323 switch((msg.msg[1]>>6)&3){
00324 case 0:
00325 type=moveVerticalCW;
00326 break;
00327 case 1:
00328 type=moveVerticalCCW;
00329 break;
00330 case 2:
00331 type=moveHorizontalCW;
00332 break;
00333 case 3:
00334 type=moveHorizontalCCW;
00335 break;
00336 }
00337 unsigned short int energy=((msg.umsg[1]&0x03F)<<8)+msg.umsg[2];
00338
00339
00340 msg.petition=false;
00341
00342 Agent *agent=world->getAgent(msg.organismId);
00343
00344 Cylinder *cylinder=NULL;
00345 if (NULL!=agent)
00346 cylinder=(*agent)[cyl];
00347 if (cylinder==NULL){
00348 log <<"Cylinder or agent does not exist!"<<int(cyl)<<endl;
00349 msg.size=0;
00350 }
00351 else{
00352 if (cylinder->getEnergy()>=energy){
00353
00354 cylinder->newIntention(Action(energy, type));
00355
00356
00357 }
00358 else{
00359 msg.size=0;
00360 }
00361 }
00362
00363 msg.petition=false;
00364 msg.sendTo(stream);
00365 stream->sync();
00366 }
00367
00368
00369
00370
00371
00372 void Client::clientLog(Message &msg){
00373 string str="";
00374 for (unsigned int i=0;i<msg.size;i++)
00375 str+=char(msg.msg[i]);
00376 log <<"Log: "<<str<<endl;
00377
00378
00379 msg.size=0;
00380 msg.petition=false;
00381 msg.sendTo(stream);
00382 stream->sync();
00383 }
00384
00385
00386 void Client::endOfTurn(Message &msg){
00387 msg.petition=false;
00388 msg.sendTo(stream);
00389 stream->sync();
00390 dontWalk();
00391 }