Thread: design problem

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    40

    design problem

    I've got a design problem. I'm doing a project for school, which is remaking a 2D game. I chose to make pokémon red which was originally for the game boy system.
    Now in this game there are 165 different attacks, which are grouped by attackes who actually do the same but are less strong etc..
    Anyway I've got about 50 different ways of how an attack has to be executed, some have to lower that stat, some have to raise another, some do this kind of damage, others do damage to enemy and the user, sometimes it inflicts a special status etc.
    The way I solved this now is a method in the battle class where I check which group the attack belonged too, and then if a match was found, it executes the code it says right there. But this is so unbelievably messy. Right now I load the basic stats and names en which group of code they belong too from a textfile.
    What I could do is to make an abstract class and then make 165 derived classes, one for each attack. That way I could just have an attack pointer of the abstract class type, but I can just call execute on it, and it will execute the code from the class the attack really is. But... 165 classes? Seems pretty messy to me too...
    Another way would be to add things to my datafile, like flags of this attack can result in poisoning, and if so how much % chance there is to do so, etc...
    Then I could write the code once en just check the flags what parts have to be executed. But in this case I would have alot of datamembers in the attack class, so I don't know if this would be a good idea as well.

    I know there are design patterns which totally kick ass, but the only one we learned this year was the singleton, we will learn about the rest next year

    So now i'm looking for some tips if there is a design pattern that I can use, or just general tips about how I could do this in a clean way.

    I will be having the same problem with items later on, since each item does something different... .


    edit: don't really know if this should be in this subforum or in game programming, didn't notice there even was a game programming section till after making this post
    sorry if this should have gone in game programming :P
    Last edited by s-men; 06-09-2008 at 04:55 AM.

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Surely you wouldn't need 165 classes. You will perhaps need several classes for simplicity. It sounds like there are two elements that are common to all attacks:
    - An effect on the attacked "person"
    - A probability of the success of the attack.

    You will then have to take into account the attacked figure, e.g. resistance to poison, physical strength (in case of "conventional weapons"), armour/protection (e.g. poison may not work if the contender wears a gas-mask). Perhaps also the delay and duration of the effects (e.g. a sword cut will be immediate effect, and last for, say, a few weeks, a poison attack may take half a day to make full effect, but only lasts for 3 days before fully recovered).

    You could possibly make all of the attacks fit one class, but if you group ones that are similar into groups, and study how you go about implementing one of them, then take two or so other in the same group and see if that throws up any further problems.

    I have no idea if Pokemon attacks are sometimes combinatorial (e.g. a poisoned sword, for example). If so, it may get more messy, and in the end easier to implement just one big class that does "all types of attacks in one class" - it can be done.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    You picked one heck of a starting project. The Pokemon series is extremely well designed.

    You don't need 165 classes; you need 165 instances of one class. (Actually, you only need the data associated with those 165 instances.) The qualities of the attacks can be modeled separately. Basically, there is no need to attempt an inheritance related hierarchy of types/probabilities/power/yield/etc. when you can model those things separately and simply contain one or more of each model in an instance of a specific attack.

    Soma

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    40
    Quote Originally Posted by phantomotap View Post
    The qualities of the attacks can be modeled separately. Basically, there is no need to attempt an inheritance related hierarchy of types/probabilities/power/yield/etc. when you can model those things separately and simply contain one or more of each model in an instance of a specific attack.
    Don't really understand what you mean very well, but well in my current design I have a database_attacks class, which has the following datamember:
    Code:
    vector<Database_Attacks_Instance*> m_Attacks;
    This vector get's filled from a textfile where data is stored like this:
    Code:
    //|name,functionID,base_damage,base_pp,accuracy,type|
    |POUND,0,40,35,255,0|
    the database_attacks_instance class looks like this:
    Code:
    class Database_Attacks_Instance
    {
    public:
    	Database_Attacks_Instance();				// Constructor
    	virtual ~Database_Attacks_Instance();		// Destructor
    
    	//-------------------------------------------------
    	// Methods							
    	//-------------------------------------------------
    	void SetName(tstring &name) {m_Name = name;}
    	void SetBaseDamage(TinyIntU damage) {m_BaseDamage = damage;}
    	void SetType(TinyInt type) {m_Type = type;}
    	void SetAccuracy(TinyIntU acc) {m_Accuracy = acc;}
    	void SetBasePP(TinyIntU PP) {m_BasePP = PP;}
    	void SetFunctionID(TinyIntU func) {m_FunctionID = func;}
    
    	tstring GetName() {return m_Name;}
    	TinyIntU GetBaseDamage() {return m_BaseDamage;}
    	TinyInt GetType() {return m_Type;}
    	TinyIntU GetAccuracy() {return m_Accuracy;}
    	TinyIntU GetBasePP() {return m_BasePP;}
    	TinyIntU GetFunctionID() {return m_FunctionID;}
    
    private: 
    	//-------------------------------------------------
    	// Datamembers								
    	//-------------------------------------------------
    	tstring m_Name; //name of the attack
    	TinyIntU m_BaseDamage; //base damage value
    	TinyInt m_Type; //type of attack
    	TinyIntU m_Accuracy; //accuracy, NOTE: base 256, so this value can be anything from 0 till 255
    	TinyIntU m_BasePP; //base PP
    	TinyIntU m_FunctionID; //ID that will point out which function (what code) should be called to handle this attack while in battle
    	// -------------------------
    	// Disabling default copy constructor and default 
    	// assignment operator.
    	// -------------------------
    	Database_Attacks_Instance(const Database_Attacks_Instance& s);									
    	Database_Attacks_Instance& operator=(const Database_Attacks_Instance& s);	
    };
    So where should I go from there, just make an execute method in the database_attacks_instance, and make it a large switch depending on the m_FunctionID?


    btw, tstring is wstring, TinyInt is char and TinyIntU is an unsigned char
    Last edited by s-men; 06-09-2008 at 05:47 AM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    What is the difference between functions? As far as I understand you would just calculate the loss of health based on the parameters (e.g. base_damage) and combine with the probability of success (accuracy?).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    40
    But some attacks don't do damage, they just do a status infliction, or they boost a certain stat, or sometimes do it all together, or just the calculated damage times 5.
    Sometimes you get damage too, or you drain hp so what the enemy is losing you are gaining. The functionID is the decimal value of those hex numbers on this page, so they need different ways of executing.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. small reference problem
    By DavidP in forum C++ Programming
    Replies: 6
    Last Post: 06-21-2004, 07:29 PM
  2. Problem with destructors.
    By Hulag in forum C++ Programming
    Replies: 7
    Last Post: 06-11-2004, 12:30 PM
  3. Design problem
    By ygfperson in forum C++ Programming
    Replies: 6
    Last Post: 04-19-2003, 01:45 PM
  4. Im a Newbie with a graphics design problem for my simple game
    By Robert_Ingleby in forum C++ Programming
    Replies: 1
    Last Post: 11-23-2001, 06:41 PM
  5. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM