1. Welcome to Smogon! Check out the Smogon Starters Hangout for everything you need to know about starting out in the community. Don't forget to introduce yourself in the Introduction and Hangout Thread, too!
  2. Welcome to Smogon Forums! Please take a minute to read the rules.

Damage Calculator (DP)

Discussion in 'Locked / Outdated Analyses' started by david stone, Jan 25, 2008.

  1. david stone

    david stone Fast-moving, smart, sexy and alarming.
    is a Site Staff Alumnusis a Smogon IRC AOp Alumnusis a Programmer Alumnusis a Super Moderator Alumnusis a Researcher Alumnusis a Contributor Alumnusis a Battle Server Moderator Alumnus

    Joined:
    Aug 3, 2005
    Messages:
    5,150
    I made a damage calculator in C++ for DP. I did it partly to learn C++, but also because it seems like none of the other calculators out there get it exactly right (often they are off just a bit due to rounding). To the best of my knowledge, this will always output the correct number.

    This is what I have yet to add:

    Unaware
    Simple
    2v2 support

    In the two supported ambiguous cases (the order of Me First vs. Tinted Lens and the order of DeepSeaScale vs. Rock-type in Sandstorm Special Defense bonus), my calculator does the multiplication in the same order as Shoddybattle.

    I also don't yet have a way to auto-calculate the power of variable power moves (coming eventually, but that's after the next step).

    I plan to give it a way to automatically enter a lot of this data just by saying who the defender is, what the attack is, etc.

    There is currently no real interface. It's just a command-line prompt. If you enter stupid data ("What is the attackers level?" "df!") you'll cause some sort of strange error. Creating a nice interface is the last of my goals. However, it is a goal, as it's something I'd like to learn.

    This is partly a learning thing for me, so here is the source code for it. If you see a way to improve it / spot an error, please let me know.

    Code:
    // Pokemon DP Damage Calculator, Beta release 1, 2008-Jan-25 23:06 EST
    
    #include <iostream>
    #include <cmath>
    #include <string>
    using namespace std;
    
    inline string lcase(const string str)	// convert strings to lowercase
    {
    	char *const pstr = _strlwr(_strdup(str.c_str()));
    	const string ret = pstr;
    	free(pstr);
    	return ret;
    }
    
    int main ()
    {
    calculate:	// goto anchor
    	double level;	// Attacker's level
    	double power;	// Move's base power
    	double HH = 1;	// Helping Hand
    	double BPAIM = 1;	// Base Power Attacker Item Modifier (Muscle Band, Wise Glasses, Type-boosting items)
    	double Charge = 1;	// Charge
    	double sport = 1;	// Mud Sport / Water Sport
    	double BPAAM = 1;	// Base Power Attacker Ability Modifier (Blaze, Iron Fist, Overgrow, Reckless, Rivalry, Swarm, Technician, Torrent)
    	double BPDAM = 1;	// Base Power Defender Ability Modifier (Dry Skin, Heatproof, Thick Fat)
    	double atk;	// Attacking stat
    	double ASM = 0;	// Attacking Stat Modifier
    	double AAM = 1; // Attack Ability Modifier (Flower Gift (on the attacker), Guts, Huge Power, Hustle, Pure Power, Slow Start, Solar Power)
    	double AIM = 1;	// Attack Item Modifier (Choice Band, Choice Specs, DeepSeaTooth, Light Ball, Thick Club)
    	double def;	// Defending stat
    	double DSM = 0;	// Defending Stat Modifier
    	double DAM = 1;	// Defense Ability Modifier (Flower Gift (on the defender), Marvel Scale)
    	double DIM = 1;	// Defense Item Modifier (DeepSeaScale, Metal Powder, Soul Dew)
    	double SS = 1;	// Sandstorm Special Defense bonus to Rocks
    	double boom = 1;	// Explosion / Selfdestuct Defense modifier
    	double BRN = 1;	// Burn
    	double RL = 1;	// Reflect / Light Screen
    	double weather = 1;	// Sunny Day / Rain Dance
    	double FF = 1;	// Flash Fire
    	double CH = 1;	// Critical Hit
    	double item = 1;	// Life Orb, Metronome
    	double TL = 1;	// Tinted Lens
    	double MF = 1;	// Me First
    	double STAB = 1;	// Same Type Attack Bonus (STAB)
    	string spectrum;	// Whether the move is physical or special
    	string type;	// What type the move is
    	double Type1 = 1;	// Effectiveness on the defender's first type
    	double Type2 = 1;	// Effectiveness on the defender's second type
    	double AEM = 1;	// Ability Effectiveness Multiplier (Solid Rock, Filter)
    	double EB = 1;	// Expert Belt
    	double RB = 1;	// Resistance berries
    	double HP = 1;	// HP
    	int maxDamage = 0;
    	int minDamage = 0;
    	int midDamage = 0;	// Temporary variable to find chance to OHKO
    	double R;	// The Random number
    	double probability = 0;	// Chance to OHKO
    	double probabilityPercent;
    	double maxPercent;
    	double minPercent;
    	string recalculate;
    	cout << "How effective is the attack on the defender's first type? (0 for No Effect, .5 for Not Very Effective, 1 for neutral, 2 for Super Effective) ";
    	cin >> Type1;
    	if (Type1 != 0)
    	{
    		cout << "How effective is the attack on the defender's second type? (0 for No Effect, .5 for Not Very Effective, 1 for neutral, 2 for Super Effective) ";
    		cin >> Type2;
    		if (Type2 != 0)
    		{
    			cout << "What is the attacker's level? ";
    			cin >> level;
    			cout << "Is the move physical or special? ";
    			cin >> spectrum;
    			spectrum = lcase(spectrum);
    			cout << "What type is the move? ";
    			cin >> type;
    			type = lcase(type);
    			cout << "What is the base power of the move? ";
    			cin >> power;
    			if (power <= 60)
    			{
    				cout << "Does the attacker have Technician? (1.5 for yes, 1 for no) ";
    				cin >> BPAAM;
    			}
    			cout << "What is the attacking stat? ";
    			cin >> atk;
    			cout << "What is the attacking stat modifier? (-6 through 6) ";
    			cin >> ASM;
    			if (ASM >= 0)	// Converts stages to multipliers
    				ASM = (2 + ASM) / 2;
    			else
    				ASM = 2 / (2 - ASM);
    			cout << "Does Pikachu have a Light Ball? (2 for yes, 1 for no) ";
    			cin >> AIM;
    			if (AIM == 1)
    			{
    				cout << "Is there a type-boosting item in play? (1.2 for yes, 1 for no) ";
    				cin >> BPAIM;
    			}
    			if (spectrum == "physical")	// Physical attacks
    			{
    				if (BPAAM == 1)
    				{
    					cout << "Does the attacker have Pure Power / Huge Power? (2 for yes, 1 for no) ";
    					cin >> AAM;
    					if (AAM == 1)
    					{
    						cout << "Is Guts activated? (1.5 for yes, 1 for no) ";
    						cin >> AAM;
    						if (AAM == 1)
    						{
    							cout << "Is Hustle activated? (1.5 for yes, 1 for no) ";
    							cin >> AAM;
    							if (AAM == 1)
    							{
    								cout << "Is Slow Start active? (.5 for yes, 1 for no) ";
    								cin >> AAM;
    								if (AAM == 1)
    								{
    									cout << "Does the attacker have Flower Gift activated? (1.5 for yes, 1 for no) ";
    									cin >> AAM;
    								}
    							}
    						}
    					}
    				}
    				if ((AIM == 1) && (BPAIM == 1))
    				{
    					cout << "Is the attacker holding a Choice Band? (1.5 for yes, 1 for no) ";
    					cin >> AIM;
    					if (AIM == 1)
    					{
    						if (AIM == 1)
    						{
    							cout << "Does Cubone / Marowak have a Thick Club? (2 for yes, 1 for no) ";
    							cin >> AIM;
    							if (AIM == 1)
    							{
    								cout << "Is the attacker holding a Muscle Band? (1.1 for yes, 1 for no) ";
    								cin >> BPAIM;
    							}
    						}
    					}
    				}
    			}
    			else	// Special attacks
    			{
    				cout << "Is Solar Power active? (1.5 for yes, 1 for no) ";
    				cin >> AAM;
    				cout << "Is the attacker holding Choice Specs? (1.5 for yes, 1 for no) ";
    				cin >> AIM;
    				if ((AIM == 1) && (BPAIM == 1))
    				{
    					cout << "Is the attacker holding Wise Glasses? (1.1 for yes, 1 for no) ";
    					cin >> BPAIM;
    				}
    			}
    			if ((AIM == 1) && (BPAIM == 1))
    			{
    				cout << "Is the attacker holding a Life Orb? (1.3 for yes, 1 for no) ";
    				cin >> item;
    				if (item == 1)
    				{
    					cout << "Is the attacker holding a Metronome? (2 for yes, 1 for no) ";
    					cin >> item;
    					if (item > 1)
    					{
    						cout << "How many times has the attack been used already? ";
    						cin >> item;
    						item = (item / 10) + 1;
    						if (item > 2)
    							item = 2;
    					}
    				}
    			}
    			cout << "What is the defending stat? ";
    			cin >> def;
    			cout << "What is the defending stat modifier? (-6 through 6)";
    			cin >> DSM;	
    			if (DSM >= 0)	// Converts stages to multipliers
    				DSM = (2 + DSM) / 2;
    			else
    				DSM = 2 / (2 - DSM);
    			if (spectrum == "physical")
    			{
    				cout << "Is Reflect in play? (2 for yes, 1 for no) ";
    				cin >> RL;
    				cout << "Is the attacker burned? (2 for yes, 1 for no) ";
    				cin >> BRN;
    				cout << "Is the attacker using Explosion or Selfdestruct? (2 for yes, 1 for no) ";
    				cin >> boom;
    				cout << "Does the defender have Marvel Scale activated? (1.5 for yes, 1 for no) ";
    				cin >> DAM;
    				cout << "Is Ditto holding Metal Powder? (1.5 for yes, 1 for no) ";
    				cin >> DIM;
    				if (BPAAM == 1)
    				{
    					cout << "Is Iron Fist activated? (1.2 for yes, 1 for no) ";
    					cin >> BPAAM;
    					if (BPAAM == 1)
    					{
    						cout << "Is Reckless activated? (1.2 for yes, 1 for no) ";
    						cin >> BPAAM;
    					}
    				}
    			}
    			else
    			{
    				cout << "Is Light Screen in play? (2 for yes, 1 for no) ";
    				cin >> RL;
    				cout << "Is the defender a Rock type during Sandstorm? (1.5 for yes, 1 for no) ";
    				cin >> SS;
    				cout << "Is Flower Gift activated on the target? (1.5 for yes, 1 for no) ";
    				cin >> DAM;
    				cout << "Is Latias or Latios holding Soul Dew? (1.5 for yes, 1 for no) ";
    				cin >> DIM;
    				if (DIM == 1)
    				{
    					cout << "Is Ditto holding Metal Powder? (1.5 for yes, 1 for no) ";
    					cin >> DIM;
    					if (DIM == 1)
    					{
    						cout << "Is Clamperl holding DeepSeaScale? (2 for yes, 1 for no) ";
    						cin >> DIM;
    					}
    				}
    			}
    			if (BPAAM == 1)
    			{
    				cout << "Is Rivalry activated? (1.25 for same gender, .75 for opposite gender, 1 for no) ";
    				cin >> BPAAM;
    			}
    			if ((type == "fire") || (type == "ice"))
    			{
    				cout << "Does the defender have Thick Fat? (.5 for yes, 1 for no) ";
    				cin >> BPDAM;
    				if (type == "fire")
    				{
    					if (BPDAM == 1)
    					{
    						cout << "Does the defender have Heatproof? (.5 for yes, 1 for no) ";
    						cin >> BPDAM;
    						if (BPDAM == 1)
    						{
    							cout << "Does the defender have Dry Skin? (1.25 for yes, 1 for no) ";
    							cin >> BPDAM;
    						}
    					}
    					cout << "Is Sunny Day in effect? (1.5 for yes, 1 for no) ";
    					cin >> weather;
    					if (weather == 1)
    					{
    						cout << "Is Rain Dance in effect? (.5 for yes, 1 for no) ";
    						cin >> weather;
    					}
    					cout << "Is Flash Fire activated? (1.5 for yes, 1 for no) ";
    					cin >> FF;
    					if (BPAAM == 1)
    					{
    						cout << "Is Blaze activated? (1.5 for yes, 1 for no) ";
    						cin >> BPAAM;
    					}
    				}
    			}
    			else if (type == "water")
    			{
    				cout << "Is Rain Dance in effect? (1.5 for yes, 1 for no) ";
    				cin >> weather;
    				if (weather == 1)
    				{
    					cout << "Is Sunny Day in effect? (.5 for yes, 1 for no) ";
    					cin >> weather;
    				}
    				if (BPAAM == 1)
    				{
    					cout << "Is Torrent activated? (1.5 for yes, 1 for no) ";
    					cin >> BPAAM;
    				}
    			}
    			else if (type == "electric")
    			{
    				cout << "Was Charge used on the previous turn? (2 for yes, 1 for no) ";
    				cin >> Charge;
    			}
    			else if (type == "grass")
    			{
    				if (BPAAM == 1)
    				{
    					cout << "Is Overgrow activated? (1.5 for yes, 1 for no) ";
    					cin >> BPAAM;
    				}
    			}
    			else if (type == "bug")
    			{
    				if (BPAAM == 1)
    				{
    					cout << "Is Swarm activated? (1.5 for yes, 1 for no) ";
    					cin >> BPAAM;
    				}
    			}
    			cout << "Is the attacker using the move Me First? (1.5 for yes, 1 for no) ";
    			cin >> MF;
    			cout << "Is the attack of the same type as the attacker (STAB)? (1.5 for yes, 1 for no) ";
    			cin >> STAB;
    			if (Type1 * Type2 > 1)
    			{
    				cout << "Does the defender have Filter / Solid Rock? (.75 for yes, 1 for no) ";
    				cin >> AEM;
    				if ((AIM == 1) && (BPAIM) && (item = 1))
    				{
    					cout << "Is the attacker holding an Expert Belt? (1.2 for yes, 1 for no) ";
    					cin >> EB;
    				}
    			}
    			else if ((Type1 * Type2 < 1) && (Type1 * Type2 != 0))
    			{
    				cout << "Does the attacker have the ability Tinted Lens? (2 for yes, 1 for no) ";
    				cin >> TL;
    			}
    			if (Type1 * Type2 >= 1)
    			{
    				if (type != "normal")
    				{
    					cout << "Is the defender holding a resistance berry that will activate? (2 for yes, 1 for no) ";
    					cin >> RB;
    				}
    				else if (Type1 * Type2 > 1)
    				{
    					cout << "Is the defender holding a Chilan Berry? (2 for yes, 1 for no) ";
    					cin >> RB;
    				}
    			}
    			cout << "Is the attacker's ally using Helping Hand? (1.5 for yes, 1 for no) ";
    			cin >> HH;
    			cout << "Is the move a critical hit? (2 for yes, 1 for no, 3 for Sniper) ";
    			cin >> CH;
    			if (CH != 1)
    			{
    				if (ASM < 1)
    					ASM = 1;
    				if (DSM > 1)
    					DSM = 1;
    				RL = 1;
    			}
    			cout << "What is the defender's HP? ";
    			cin >> HP;
    			power = floor(floor(floor(floor(floor(floor(power * HH) * BPAIM) * Charge) * sport) * BPAAM) * BPDAM);
    			if (power == 0)
    				power = 1;
    			atk = floor(floor(floor(atk * ASM) * AAM) * AIM);
    			if (atk == 0)
    				atk = 1;
    			def = floor(floor(floor(floor(floor(def * DSM) * DAM) * DIM) * SS) / boom);
    			if (def == 0)
    				def = 1;
    			maxDamage = floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(level * 2 / 5 + 2) * power * atk / 50) / def) / BRN) / RL) * weather) * FF + 2) * CH * item) * TL * MF) * STAB) * Type1) * Type2) * AEM) * EB) / RB);
    			minDamage = floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(level * 2 / 5 + 2) * power * atk / 50) / def) / BRN) / RL) * weather) * FF + 2) * CH * item) * TL * MF) * .85) * STAB) * Type1) * Type2) * AEM) * EB) / RB);
    			maxPercent = 100 * maxDamage / HP;
    			minPercent = 100 * minDamage / HP;
    		}
    	}
    	if (maxDamage >= HP)
    	{
    		R = 217;
    		while ((R <= 255) && (midDamage < HP))	// Cycles through all possible values for R until it finds the lowest R that grants a OHKO, only if such a value is possible
    		{
    			midDamage = floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(level * 2 / 5 + 2) * power * atk / 50) / def) / BRN) / RL) * weather) * FF + 2) * CH * item) * TL * MF) * floor(R * 100 / 255)) / 100) * STAB) * Type1) * Type2) * AEM) * EB) / RB);
    			R = R + 1;
    		}
    		probability = (256 - R);
    		probabilityPercent = (probability / 39) * 100;
    		cout << "There is a " << probability << "/39 chance to OHKO, or " << probabilityPercent << "%\n";
    		cout << "Damage is " << minDamage << "-" << HP << ", or " << minPercent << "%-100%\n";
    	}
    	else
    		cout << "Damage is " << minDamage << "-" << maxDamage << ", or " << minPercent << "%-" << maxPercent << "%" << '\n';
    	cout << "Would you like to calculate again? (1 for yes, 0 for no)";
    	cin >> recalculate;
    	if (recalculate != "0")
    		goto calculate;	// Brings you back to the start to recalculate
    	return 0;
    }
    So, want to help me beta test it? I don't anticipate any errors, but whatever.

    I know the structure is a bit funny (as in the order it asks about everything), but expect that to be improved next version (likely some time tomorrow?).

    Attached Files:

  2. Cathy

    Cathy

    Joined:
    Jul 11, 2007
    Messages:
    1,061
    I know it was I who suggested that lcase() function but it turns out that strlwr() is actually a Microsoft-extension and not part of the C standard library (it failed to compile in gcc). If anybody else is compiling it in gcc, I used this version of lcase():

    Code:
    #include <cctype>
    #include <algorithm>
    inline string lcase(string s) {
        transform(s.begin(), s.end(), s.begin(), (int( *)(int))toupper);
        return s;
    }
    This should work in VC++ as well.
  3. timw06

    timw06

    Joined:
    Jun 27, 2007
    Messages:
    543
    It works fine and produces a decent result. A few suggestions.
    ~ What is the point of asking for the type of the attacking move? You already ask us for STAB and it doesn't autocalculate effectiveness. Same thing with Physical/Special
    ~ Why not amalgamate all the separate prompts for items into one (eg: 1 = Choice Specs 2 = Wise Glasses etc.)
    ~ The same for abilities
    ~ Could you get it to accept arguments on the command line as that makes it easier to create shortcuts to certain results. I have six on my desktop for each of my pokemon that all go something like
    Code:
    [I]ruby damagecalc7.rb ? 202 ? ? ? 3 3 -[/I]
    It saves time because you only have to enter half the info each time.
    ~ When the attack could OHKO the pokemon the result is a bit confusing...
    Code:
    Damage is 292-100, or 292%-100%
    With the same variables but with a poke with more HP it is more sane.

    Finally, you have errors on compile: I know nothing about C so I don't know whether they matter or not!

    Code:
    tim@tim-laptop:~$ g++ ObiDamageCalc.c
    ObiDamageCalc.c: In function ‘int main()’:
    ObiDamageCalc.c:356: warning: converting to ‘int’ from ‘double’
    ObiDamageCalc.c:357: warning: converting to ‘int’ from ‘double’
    ObiDamageCalc.c:367: warning: converting to ‘int’ from ‘double’
    
    It's obvious you have spent a lot of time on this though so kudos to you.

    Working Linux binaries are attached if anyone's interested...

    Attached Files:

  4. X-Act

    X-Act np: Biffy Clyro - Shock Shock
    is a Site Staff Alumnusis a Programmer Alumnusis a Smogon IRC SOp Alumnusis a Researcher Alumnusis a CAP Contributor Alumnusis a Tiering Contributor Alumnusis a Contributor Alumnusis an Administrator Alumnus

    Joined:
    Feb 17, 2006
    Messages:
    4,675
    Replacing

    Code:
    maxDamage = floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(level * 2 / 5 + 2) * power * atk / 50) / def) / BRN) / RL) * weather) * FF + 2) * CH * item) * TL * MF) * STAB) * Type1) * Type2) * AEM) * EB) / RB);
    with

    Code:
    maxDamage = (int) floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(floor(level * 2 / 5 + 2) * power * atk / 50) / def) / BRN) / RL) * weather) * FF + 2) * CH * item) * TL * MF) * STAB) * Type1) * Type2) * AEM) * EB) / RB);
    and doing the same thing for minDamage one line later and for midDamage 10 lines later should cure the compiler warnings by typecasting the answer to an integer value. The problem was that floor(x) returns a double value, not an int (unnaturally). Alternatively, you could use integer division and get rid of all those floor functions!

    You don't need to do the following, but it's better to do without goto. I'd put

    Code:
    do
    instead of

    Code:
    calculate:
    and

    Code:
    while (recalculate != "0");
    instead of

    Code:
    if (recalculate != "0")
      goto calculate;
    Also, replace

    Code:
    cout << "Damage is " << minDamage << "-" << HP << ", or " << minPercent << "%-100%\n";
    with

    Code:
     
    if (minDamage > HP)
      cout << "Damage is " << HP << ", or 100%\n";
    else
      cout << "Damage is " << minDamage << "-" << HP << ", or " << minPercent << "%-100%\n";
    
    Hope this helps a bit with debugging. :)

    @timw06: The type is asked because of such things as Thick Fat. The physical versus special is for Reflect/Light Screen etc.
  5. X-Trader

    X-Trader

    Joined:
    Aug 9, 2007
    Messages:
    4,991
    Obi, the Damage Calculator that is attached doesn't work on Macs.
  6. Aldaron

    Aldaron indefatigable workhorse
    is a Tournament Directoris a Battle Server Administratoris a Smogon IRC SOPis a Tiering Contributoris a Contributor to Smogonis an Administrator
    OU and IRC Leader

    Joined:
    Aug 5, 2007
    Messages:
    4,534
    I downloaded it and extracted it. When I tried to run it, I got this:

    "The application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem"

    I have Windows XP.
  7. ryubahamut

    ryubahamut
    is a Site Staff Alumnusis a Programmer Alumnusis a Forum Moderator Alumnusis a Contributor Alumnus

    Joined:
    Jan 18, 2007
    Messages:
    999
    i'm getting the same error. some time back when i had installed anope on my computer, i got the exact same error, which was subsequently fixed by copying a .manifest file from the net. could that be the issue obi?

    i tried compiling using mingw32, but it's a bulky 500k executable, or i would have posted a link here

    edit: colinjf, compile it using the g++ command and not gcc
  8. Cathy

    Cathy

    Joined:
    Jul 11, 2007
    Messages:
    1,061
    I did use g++ to invoke gcc. As I said, that change is required because strlwr() is a Microsoft extension. My post was intended to help other people compiling using gcc in a POSIX environment.
  9. pear

    pear

    Joined:
    Mar 4, 2006
    Messages:
    270
    Did you try using strip.exe on it?
  10. ryubahamut

    ryubahamut
    is a Site Staff Alumnusis a Programmer Alumnusis a Forum Moderator Alumnusis a Contributor Alumnus

    Joined:
    Jan 18, 2007
    Messages:
    999
    pear: good idea, man. stripped and UPX'ed down to 82 KB, zips to 81 kb, so did not bother to zip further. http://ryubahamut.googlepages.com/damcalc.exe but not sure whether this requires the mingw32 runtime or not. XP users may attempt running this.

    ColinJF: perhaps i'm able to compile under msys because the mingw32 dll uses windows runtime? that might be the case. sorry!
  11. Justin8649

    Justin8649
    is a Tournament Director Alumnusis a Site Staff Alumnusis a Battle Server Admin Alumnusis a Smogon IRC SOp Alumnusis a Contributor Alumnusis an Administrator Alumnus

    Joined:
    Jan 26, 2005
    Messages:
    2,700
    That is what you call a RTE (Run Time Error.) Most RTEs are the cause of bad/lazy programming. When you are developing an application and debugging/testing it, you need to think like a user. You want to make your application is as fool-proof as possible. If somebody tries to enter just a space or fake input, you need to have a way to validate the input. It is really easy to validate input with Regular Expressions. Since this is basically just checking for numbers mostly, I would recommend checking to see if the input is an integer with a simple while loop. Keep repeating the loop until the input is valid.
  12. david stone

    david stone Fast-moving, smart, sexy and alarming.
    is a Site Staff Alumnusis a Smogon IRC AOp Alumnusis a Programmer Alumnusis a Super Moderator Alumnusis a Researcher Alumnusis a Contributor Alumnusis a Battle Server Moderator Alumnus

    Joined:
    Aug 3, 2005
    Messages:
    5,150
    Life Orb appears to do nothing. I don't know what the error is, as it was working in prior versions. Can anyone spot the error?
  13. X-Act

    X-Act np: Biffy Clyro - Shock Shock
    is a Site Staff Alumnusis a Programmer Alumnusis a Smogon IRC SOp Alumnusis a Researcher Alumnusis a CAP Contributor Alumnusis a Tiering Contributor Alumnusis a Contributor Alumnusis an Administrator Alumnus

    Joined:
    Feb 17, 2006
    Messages:
    4,675
    What's the latest version of the program? I can try to help.
  14. chip_the_fox

    chip_the_fox

    Joined:
    Sep 21, 2007
    Messages:
    218
    the only "problem" i have is you enter waterfall's data (80 power/water type) and it asks if your using selfdestruct/explosion but other than that i really have no complaints

Users Viewing Thread (Users: 0, Guests: 0)