Initializing classes more than once

Initializing classes more than once

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

Post Reply
User avatar
krogothe
AI Developer
Posts: 1050
Joined: 14 Nov 2005, 17:07

Initializing classes more than once

Post by krogothe »

Say i have a class that creates an array. I want to use that array and its methods in two or more other classes...
Do i have to create 2 instances of that class? will that take up more memory?
also is it possible to stick a whole array in the register for faster loading/saving?
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I would add a function in that class that returns a pointer to the desired array, that way other classes only need create a pointer and point it to that functions return value.
User avatar
krogothe
AI Developer
Posts: 1050
Joined: 14 Nov 2005, 17:07

Post by krogothe »

but how can you pass arguments into a pointer? just like the IAICallback pointers?

and while were at it:
are vectors any slower than arrays?
how do you check if a folder exists?
how do you create a new folder?
how do i find out how wide/tall a building's footprint is?
why do you set your forum status as hidden?
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

are vectors any slower than arrays?
Only when you make it reallocate all the time:

Fastest (data.clear() doesn't reallocate!! just sets the size to zero)

Code: Select all

vector<int> data;

void test() { 
  while (need_to_do_stuff) {
    data.clear();
    fill data vector
    use data vector
  }
}
Slightly worse (data is allocated and freed everytime test is called)

Code: Select all


void test() { 
  vector<int> data;
  while (need_to_do_stuff) {
    data.clear();
    fill data vector
    use data vector
  }
}
Worst: (data is allocated and destroyed everytime it goes through the loop)

Code: Select all


void test() { 
  while (need_to_do_stuff) {
    vector<int> data;
    data.clear();
    fill data vector
    use data vector
  }
}
Accessing and looping through the data is just as fast probably, not a real difference.
how do you check if a folder exists?
Can be done in multiple ways, Win32 crap, going through the file tree with findfirst style (of which several forms exist as well), using boost::filesystem,......
how do you create a new folder?
mkdir() might work
how do i find out how wide/tall a building's footprint is?
UnitDef::xsize, UnitDef::ysize
why do you set your forum status as hidden?
I'm admin and I don't even know :|
User avatar
Triaxx2
Posts: 422
Joined: 29 Aug 2004, 22:24

Post by Triaxx2 »

Because he doesn't want people to know when he's online, and suddenly start sending him ten million PM's?
User avatar
krogothe
AI Developer
Posts: 1050
Joined: 14 Nov 2005, 17:07

Post by krogothe »

Wow awesome guys!
and how would i go about implementing a vector to work as a struct?
vector<struct> data;
data[z].x = y?

like that? and the brackets [] work just like an array right?
so the only real differences are the neat little functions like .push_back, clear etc? (im reading up on them)

All i really want to do is fill the vector array once and then remove values from it occasionally (could i remove a value right in the middle of it? how are the other values affected?)
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

All i really want to do is fill the vector array once and then remove values from it occasionally (could i remove a value right in the middle of it? how are the other values affected?)
Then you might want to use std::list... or if order doesn't matter, my ptrvec template. In general when deciding which template you should use, there are a few things to note:

- does it have fast random access like std::vector,std::deque and normal arrays:
array[element index]

- do you need to insert and remove elements from it regularly? then you want a container with constant time insertion+removal like std::list

- should it be sorted and have unique items: set/map,
the last two are very powerful but also generate a lot of code and use more memory than vector and list and I'm guessing that when used very often, they can really slow down the CPU caching..
User avatar
krogothe
AI Developer
Posts: 1050
Joined: 14 Nov 2005, 17:07

Post by krogothe »

hmm ill have to look up on the differences between a list and vector and deques too (vecs and deqs seem similar but lists are slower for some reason)...
it wont be changed very often at all but will be accessed often so ill go for something fast!
User avatar
PauloMorfeo
Posts: 2004
Joined: 15 Dec 2004, 20:53

Re: Initializing classes more than once

Post by PauloMorfeo »

krogothe wrote:Say i have a class that creates an array. I want to use that array and its methods in two or more other classes...
Do i have to create 2 instances of that class? ...
Do you want to make something like this?
note, this is C# so in C++ should look diferently (still similar).

A class:

Code: Select all

class UnitList
{
	//Create an Array
	private Array unitList= new Array();
	
	//stuff
	
	public bool IsUnitUnderFire (Unit unit)
	{
		//do your stuff to check it
	}
}
Accessing an object made out of the class «UnitList» in another method:, example 1:

Code: Select all

class krogotheProgram
{
	static void Main ()
	{
		UnitList unitList= new UnitList();
		krogotheProgram2 k= new krogotheProgram2();
		k.checkUnitsUnderFire (unitList);
	}
}

class krogotheProgram2
{
	public void checkUnitsUnderFire (UnitList unitList)
	{
		foreach (Unit u in unitList) {
			if (unitList.IsUnitUnderFire(u)) {
				//Means unit is under fire
				//You've just accessed a method in the class UnitList in
				//  a method diferent from the one that created an instance out of it
			}
		}
	}
}
Accessing an object made out of the class «UnitList» in another method:, example 2:

Code: Select all

class krogotheProgram
{
	static void Main ()
	{
		UnitList unitList= new UnitList();
		krogotheProgram2 k= new krogotheProgram2(unitList);
		k.checkUnitsUnderFire ();
	}
}

class krogotheProgram2
{
	private UnitList unitList;
	
	//The constructor of the class
	public krogotheProgram2 (UnitList u)
	{
		unitList= u;
	}
	
	public void checkUnitsUnderFire ()
	{
		foreach (Unit u in unitList) {
			if (unitList.IsUnitUnderFire(u)) {
				//Means unit is under fire
				//You've just accessed a method in the class UnitList in
				//  a method diferent from the one that created an instance out of it
			}
		}
	}
}
They work slightly diferent.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

not the same at all, but helpful if you\'re learning C#
User avatar
krogothe
AI Developer
Posts: 1050
Joined: 14 Nov 2005, 17:07

Post by krogothe »

Yeah, ive thought about passing the classes as arguments to the constructor, which works but since ill be using a lot of classes it will make the code really messy, passing 10+ classes....
What ive tried doing so far is creating instances of all classes in the GlobalAI class and then passing just a pointer to GlobalAI to each class:

Code: Select all

void CGlobalAI::InitAI(IGlobalAICallback* callback, int team)
{
	cb=callback->GetAICallback();
	ut = new UnitTable(this);
	ut->Init();
	mm = new MetalMap(this);
	mm->init();
}

Code: Select all

MetalMap::MetalMap(CGlobalAI* ai)
{
	this->ai = ai;
	cb = ai->cb;
and then to use the actual methods:

Code: Select all

float3 MetalMap::GetNearestMetalSpot (int builderid)
{
	float Tempscore = 0;
	const UnitDef* extractor = ai->ut->GetResourceBuilding(1,1);
 //////////lots of irrelevant code
}
The above should work, right? I can use callback functions in all classes like that without passing the IAICalback class, by just using ai->cb->method().
Am I missing something really obvious here? (since sub seems to get his AI to do that no probs!)
User avatar
jcnossen
Former Engine Dev
Posts: 2440
Joined: 05 Jun 2005, 19:13

Post by jcnossen »

I've used that method too for quite some time. From a design point of view, you might want to make a seperate structure with all the globals in it (In JCAI this is called CGlobals):

Code: Select all


struct Globals {
  MetalStuff *ms;
  ResourceThings *rt;
  IAICallback *cb;
  TaskManager *tm;
};

Otherwise you'll end up with both the high-level and low level stuff in your CGlobalAI class, which can make things a bit messy when your code is growing.
User avatar
krogothe
AI Developer
Posts: 1050
Joined: 14 Nov 2005, 17:07

Post by krogothe »

Ive never thought of that! Zaph youre a genius...
lemme try it out!


EDIT:
Yup! its working! you have no idea how much this has just helped my AI! (ill post a little topic soon about what i can do with it now!)
User avatar
Veylon
AI Developer
Posts: 174
Joined: 21 Sep 2005, 19:45

Post by Veylon »

Clever!

I mostly use things like this in my Init function for my AI:

Code: Select all

UnitDefList = new UnitDefClass(callback);
Metaller = new MetalClass(callback, UnitDefList);
Builder = new BuildClass(callback, UnitDefList, Metaller);
Attacker = new AttackClass(this, callback, UnitDefList);
But I think yours is better.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

I use a similair system. GlobalAI class creates a globals object liek the above btu thent he globals object creates all the agents and deals with all the stuff, so really the Global is NTAI and not cgloablAI.
Post Reply

Return to “AI”