#include "includes.h" template class person { private: point loc; //Person's location point dst; //Person's destination point* (*communicator)(point lo, int id, T w, int tid); static int ID; int this_id; public: person(){}; ~person(){}; person(point loca, point* (*com)(point lo, int id, T w, int tid)) { this_id=ID++; dst=loca; loc=dst; communicator=com; } int id(){ return this_id;} void set_communicator(point* (*com)(point lo, int id, T w, int tid)) { if(communicator==NULL) communicator=com; } point get_loc(){ return loc;} point get_dst(){ return dst;} point* call_communicator(T w, int tid){ return this->communicator(loc, this_id, w, tid);} void move_to(point new_loc){ dst=new_loc;} void move() { float y_diff, x_diff, mag; mag = sqrt(dist_sqr(dst,loc)); y_diff=x_diff=1.5; if(mag < 1) return; y_diff=y_diff* (dst.get_y()-loc.get_y())/mag; x_diff=x_diff* (dst.get_x()-loc.get_x())/mag; //if(y_diff<1&&x_diff<1) // return; loc.set_y(loc.get_y()+y_diff); loc.set_x(loc.get_x()+x_diff); } }; template int person::ID=0; //world is really meant to be subclassed.. this shell has practically no usefull functionality class world { private: person** plist; int cap_size; int num_people; public: world(){}; ~world(){}; world(int cap_sz, person** pl, int num_ppl) { cap_size=cap_sz; num_people=num_ppl; plist=pl; } /*void add_person(person* joe) { if(num_people** get_plist() { return plist; } person* get_person(int id) { for(int j = 0; j < num_people; j++) { if(plist[j]->id()==id) return plist[j]; } } point find(int PID) { for(int j = 0; j < num_people; j++) { if(plist[j]->id()==PID) return plist[j]->get_loc(); } } //most important function to override to define behavior bool can_find(int PFind, int PLook) { for(int i = 0; i < num_people; i++) { if(plist[i]->id()==PFind) { point pt1 = plist[i]->get_loc(); for(int j = 0; j < num_people; j++) { if(j==i) continue; if(plist[j]->id()==PLook) { point pt2 = plist[j]->get_loc(); if(dist_sqr(pt1,pt2) < 10000) return true; } } return false; } } return false; } }; typedef point*(*commptr)(point, int, world, int); class PNetwork //used for networks of people -police,gangs,teams,etc. { private: person** plist; int mode; weight_list** targets; int num_people; int cap_size; world* com_world; int targ_ID; /*--Generic Communicators--*/ static point* seek_communicator(point in, int PID, world w, int tid) { if(w.can_find(PID,tid)==true) { cout<<"CAN HAS!!\n"; point pt = w.find(tid); return new point(pt.get_x(),pt.get_y()); } else return NULL; } static point* avoid_communicator(point in, int PID, world w, int tid) { if(w.can_find(PID,tid)==true) { point pt = w.find(tid); return new point(in.get_x()+(pt.get_x()-in.get_x()), in.get_y()+(pt.get_y()-in.get_y())); } else return NULL; } static point* follow_communicator(point in, int PID, world w, int tid) { if(w.can_find(PID,tid)==true) { point pt = w.find(tid); float mag = sqrt(dist_sqr(pt,in)); if(mag<10) return NULL; mag = (mag-10)/mag; point *joe = new point((in.get_x()-pt.get_x())*mag,(in.get_y()-pt.get_y())*mag); return joe; } else return new point(in.get_x(),in.get_y()); } public: //NOTE: BAD! PNetwork() { plist=NULL; targets=NULL; mode=seek; } ~PNetwork(){}; PNetwork(world* w, int md, int tid, int caps) { targ_ID=tid; com_world=w; plist = new person*[caps]; targets = new weight_list*[caps]; mode=md; cap_size=caps; num_people=0; } commptr generic_communicator() { switch(mode) { //seek and hotseek use same gen. communicator, differences in behavior are in engine case seek: return &seek_communicator; case hotseek: return &seek_communicator; case avoid: return &avoid_communicator; case hotavoid: return &avoid_communicator; case follow: return &follow_communicator; } } bool has_person(int ID) { for(int i = 0; i < num_people; i++) if(plist[i]->id()==ID) return true; return false; } void add_person(person* new_dude) { if(new_dude->id()==targ_ID) return; new_dude->set_communicator(generic_communicator()); if(num_people==cap_size) return; plist[num_people]=new_dude; switch(mode) { case seek: targets[num_people]=new weight_list(.5,15); break; case avoid: targets[num_people]=new weight_list(.5,15); break; case hotseek: targets[num_people]=new weight_list(.75,10); break; case hotavoid: targets[num_people]=new weight_list(.75,10); break; case follow: targets[num_people]=new weight_list(.75,10); break; } num_people++; } void rm_person(int PID) { int access_id; for(access_id = 0; access_idid()!=PID) continue; else { person **temp = new person*[cap_size]; int j = 0; for(int k = 0; k < num_people-1; k++) { if(j==access_id) j++; temp[k]=plist[j]; j++; } plist=temp; return; } } } void step() { point *temp; for(int i = 0; i < num_people; i++) { temp=plist[i]->call_communicator(*com_world, targ_ID); if (temp==NULL) continue; for(int j = 0; j < num_people; j++) { if(j==i) targets[j]->add(*temp,5); else { //float ds = dist_sqr(plist[j]->get_loc(),plist[i]->get_loc()); //if(ds <= 25) targets[j]->add(*temp,1); //else if(ds >=2025) // targets[j]->add(*temp,45/(2*(ds-5))); //else // targets[j]->add(*temp,(-1/80)*(ds-5)+1); } } } for(int i = 0; i < num_people; i++) { plist[i]->move_to(targets[i]->sum()); } } void move_ppl() { for(int i = 0; i < num_people; i++) plist[i]->move(); } };