D/P Damage Calculator (C++)

Xenon's Damage Calculator

Hello, I'm Xenon, and I recently made a Damage Calculator in C++ primarily for my own use, but I thought I'll post it here to get some suggestions and of course, you can use it as well if you like it. I have only added the important items and effects that we generally see in the OU environment since we do not usually see much of type boosting items, hustle, slow start or Pokémons holding metronome and so on.

Download Now!

The file that you will download is zipped in .rar format, so you will need WinRAR to open it (get it here if you don't have it).

The Pro's and Con's of this Calculator in my Opinion :

Pro's :

1. It is quite user friendly in my opinion, even if you can not use the mouse.

2.
The calculator will not ask you for too many inputs and test your patience, since I already mentioned that this calculator is meant only for standard OU battle scenarios and will ask you only for the important values.

3.
The calculator will suggest how many more EVs the attacking Pokémon needs to KO the opponent or how many EVs the defending Pokémon needs to survive the attack (i've not seen this feature in most of the calculators, so thought it would be helpful ^^).

An example of how a Zapdos (252 HP/ 0 Def) takes damage from a Gyarados's Stone Edge (1 Dragon Dance, 0 Atk, Adamant) :



Con's :

1. Since it is written in C++, it will not look flashy or attractive :(

2. This calculator does not ask for conditions like Burn, Choice Band and Choice Specs even though they are very commonly seen.
The reason behind this :
For burn status, all you have to do is enter -2 in the attacking stat modifier, +1 for Choice Band / Specs. So it is kind of easy to enter those data and i did not find any point in adding one more variable for them.

3. No 2vs2 battle mode, though i plan on adding it in the future versions.

4. For some alignment purposes, i have used Turbo C++, and hence the source code will not work on Dev C++ and many more which do not run on DOS - based screens.

Edit : This calculator does not work on Linux. I'll make some changes to hopefully make it work on Linux by 2 days ^^

The Source Code (phew, 329 lines takes quite some time to type...) :

Code:
#include <iostream.h>
#include <conio.h>
#include <math.h>
#include <dos.h>
#include <process.h>

void dcalculator();
void menu();

void introduction()
{
 clrscr();
 cout<<"\n\n\n\t\t    *Xenon's Damage Calculator v2.0*";
 cout<<"\n\n\nThis is a Damage calculator based on the damage formula of Pok‚mon Diamond/Pearl";
 cout<<"\nAll the conditions in the standard OU environment have been added.";
 cout<<"\nMost of the special conditions involving Ditto's metal powder, Pikachu's light\nball and many more scenarios which are not seen in the OU environment have not\nbeen added.";
 cout<<"\nIf your Pok‚mon is holding a Choice Band / Choice Specs, just add +1 to your\nattacking status modifiers.";
 cout<<"\nThis Program will not work for 2vs2 battles.";
 cout<<"\n\n\n\t Thank You for spending your time reading this page ";
 cout<<"\n\n\n\nIn case of any errors, please PM me if you are in Smogon, or contact me at\ndarksceptile@live.com";
 cout<<"\n\n\n\n\t\tPress any Key to Return to the Menu";
 getch();
 menu();
}

void cred()
{
 clrscr();
 cout<<"\n\n\n\t\t    *Xenon's Damage Calculator v2.0*";
 cout<<"\n\n\n\n\n\n\t\t\t\tCredits\n\n\n";
 for(int a=0;a<78;a++)
  cout<<"-";
 cout<<"\n1. X-Act : For using the D/P formula he posted in Smogon.";
 cout<<"\n2. Obi : I wrote this program after i saw him make a Damage Calculator in C++.\n";
 for(a=0;a<78;a++)
  cout<<"_";
 cout<<"\n\n\n\n\t\t    Press any Key to Return to the Menu";
 getch();
 menu();
}

void menu()
{
 clrscr();

 char ans;

 cout<<"\n\n\n\t   #####    ####   ##   ##   ###   ###   ###   ####   ####  ##\n";
 cout<<"\t   ##  ##  ######  ##  ##          ## ### ##  ######  ## ## ##\n";
 cout<<"\t   ##  ##  ##  ##  ## ##     ###   ##  #  ##  ##  ##  ##  ####\n";
 cout<<"\t   #####   ##  ##  ####     #   #  ##     ##  ##  ##  ##   ###\n";
 cout<<"\t   ##      ##  ##  ## ##    ####   ##     ##  ##  ##  ##    ##\n";
 cout<<"\t   ##      ######  ##  ##   ##     ##     ##  ##  ##  ##    ##\n";
 cout<<"\t   ##       ####   ##   ##   ####  ##     ##   ####   ##    ##\n";

 cout<<"\n\n\n\n\t\t    *Xenon's Damage Calculator v1.40*";

 cout<<"\n\n\n\n\t\t\t\tMENU";
 cout<<"\n\n\t\t";

 for(int a=0;a<36;a++)
  cout<<"-";

 cout<<"\n\t\t| 1. Introduction                  |";
 cout<<"\n\n\t\t| 2. Use Damage Calculator         | ";
 cout<<"\n\n\t\t| 3. Credits                       |";
 cout<<"\n\n\t\t| 4. Exit                          |";
 cout<<"\n\t\t";

 for(a=0;a<36;a++)
  cout<<"_";

 cout<<"\n\n\t\tInput : ";
 cin>>ans;

 if(ans=='1')
  introduction();

 else if(ans=='2')
  dcalculator();

 else if(ans=='3')
  cred();
 else if(ans=='4')
 {
  cout<<"\n\n\tThank You for using Xenon's Damage Calculator v2.00";
  getch();
  exit(1);
 }
 else
 {
  cout<<"\n\n\tWrong Input ! Please Choose Again.";
  getch();
  menu();
 }
}

void dcalculator()
{
 clrscr();
 int lvl,atk,bp,def,a,mindamage,maxdamage,middamage,critmin,critmax;
 float hp,eff,stab,rmin,rmax,pmin,pmax,cmin,cmax,amod,dmod,rl,itm,mod3;
 char ch;

 rl=1.00;
 itm=1.00;
 mod3=1.00;

 cout<<"\n\n\n\t\t    *Xenon's Damage Calculator v2.00*";
 cout<<"\n\n\nEnter the level of the attacking Pok‚mon : ";
 cin>>lvl;
 cout<<"\nEnter the attacking stat of the attacking Pok‚mon: ";
 cin>>atk;
 cout<<"\nEnter the attacking stat modifier (-6 to +6) : ";
 cin>>amod;
 if(amod>0)
 {
  atk*=(1+(amod/2));
 }
 if(amod<0)
 {
  atk*=(2/(2-amod));
 }
 cout<<"\nEnter the Base Power of the move used : ";
 cin>>bp;
 cout<<"\nIs the move STABed (y or n) ? ";
 cin>>ch;
 if(ch=='y')
  stab=1.5;
 else
  stab=1;
 cout<<"\nEnter the HP of the defending Pok‚mon : ";
 cin>>hp;
 cout<<"\nEnter the defending stat of the defending Pok‚mon : ";
 cin>>def;
 cout<<"\nEnter the defending stat modifier (-6 to +6) : ";
 cin>>dmod;
 if(dmod>0)
 {
  def=def*(1+(dmod/2));
 }
 if(dmod<0)
 {
  def=def*(2/(2-dmod));
 }
 cout<<"\nEnter how effective is the attack on the opponent ->";
 cout<<"\n1. 2x Not Effective\n2. Not Effective\n3. Normal\n4. Super Effective\n5. 2x Super Effective";
 cout<<"\nInput : ";
 cin>>a;

 switch(a)
 {
  case 1: eff=0.25; break;
  case 2: eff=0.50; break;
  case 3: eff=1.00; break;
  case 4: eff=2.00; break;
  case 5: eff=4.00; break;
 }

 cout<<"\nDo you want to add any more conditions (y or n) ? ";
 cin>>ch;
 if(ch=='y')
 {
  cout<<"\nIs Light Screen / Reflect in play (y or n) ? ";
  cin>>ch;
  if(ch=='y')
   rl=0.50;

  cout<<"\nIs the attacking Pok‚mon equipped with Life Orb (y or n) ? ";
  cin>>ch;
  if(ch=='y')
   itm=1.30;

  cout<<"\nIs the Pok‚mon attacking using an Expert Belt (y or n) ? ";
  cin>>ch;
  if(ch=='y')
   mod3=1.20;

  cout<<"\nIs the defending Pok‚mon holding a Resistance Berry (y or n) ? ";
  cin>>ch;
  if(ch=='y')
   mod3=0.50;
 }

 mindamage=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*atk/50))/def))*rl))+2)*0.85*itm))*eff*stab*mod3;
 maxdamage=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*atk/50))/def))*rl))+2)*1.00*itm))*eff*stab*mod3;
 critmin=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*atk/50))/def))*rl))+2)*1.70*itm))*eff*stab*mod3;
 critmax=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*atk/50))/def))*rl))+2)*2.00*itm))*eff*stab*mod3;

 pmin=(mindamage/hp)*100.00;
 pmax=(maxdamage/hp)*100.00;
 cmin=(critmin/hp)*100.00;
 cmax=(critmax/hp)*100.00;

 cout<<"\n\n\n\n\t\tProcessing...";
 delay(1000);

 clrscr();
 cout<<"\n\n\n\t\t    *Xenon's Damage Calculator v1.40*";
 cout<<"\n\nAttacking Pok‚mon\t\t\tDefending Pok‚mon";
 cout<<"\n\nLevel : "<<lvl;
 gotoxy(41,8);
 cout<<"HP : "<<hp;
 cout<<"\nAtk / Sp.Atk : "<<atk;
 if(amod>0)
  cout<<" (after +"<<amod<<")";
 if(amod<0)
  cout<<" (after -"<<amod<<")";
 gotoxy(41,9);
 cout<<"Def / Sp.Def : "<<def;
 if(dmod>0)
  cout<<" (after +"<<dmod<<")";
 if(dmod<0)
  cout<<" (after -"<<dmod<<")";
 cout<<"\nBase Power : "<<bp;
 cout<<"\nSTAB : ";

 if(ch=='y')
  cout<<"Yes";
 else
  cout<<"No";

 gotoxy(41,10);
 cout<<"Effectiveness : "<<eff<<"x";

 cout<<"\n\n\n\n\n\n\n\n\t\tDamage -> "<<mindamage<<" - "<<maxdamage;
 cout<<"\n\t\tWhich is, "<<pmin<<"% - "<<pmax<<"%";

 int damagep,damagepm,f=0,k=0,natk,ndef,aev=0,dev=0;
 natk=atk;

 if(pmax<100.00)
 {
  while(f!=1)
  {
   damagep=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*natk/50))/def))*rl))+2)*1.00*itm))*eff*stab*mod3;
   damagepm=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*natk/50))/def))*rl))+2)*0.85*itm))*eff*stab*mod3;

   if(damagep<hp && k==0)
   {
    ++natk;
    aev=aev+4;
   }
   if(damagepm<hp && k==1)
   {
    ++natk;
    aev=aev+4;
   }
   if(damagepm>=hp && k==1)
   {
    f=1;
    if(aev<=252)
     cout<<"\nThe attacking Pok‚mon needs atmost "<<aev<<" more attack EVs to KO the opponent.";
    if(aev>252)
     cout<<"\n\nThe attacking Pok‚mon might not KO the opponent even with 252 more attack EVs.";
   }
   if(damagep>=hp && k==0)
   {
    k=1;
    if(aev<=252 && aev!=0)
     cout<<"\n\nThe attacking Pok‚mon needs atleast "<<aev<<" more attack EVs to KO the opponent.\n";
    if(aev>252)
    {
     f=1;
     cout<<"\n\nThe attacking Pok‚mon will not KO the opponent even with 252 more attack EVs.";
    }
   }
  }
 }

 f=0;
 k=0;
 ndef=def;

 if(pmax>=100.00)
 {
  while(f!=1)
  {
   damagep=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*atk/50))/ndef))*rl))+2)*1.00*itm))*eff*stab*mod3;
   damagepm=(floor(((floor((floor((floor((floor((lvl*0.40)+2))*bp*atk/50))/ndef))*rl))+2)*0.85*itm))*eff*stab*mod3;
   if(damagepm>=hp && k==0)
   {
    ++ndef;
    dev=dev+4;
   }
   if(damagep>=hp && k==1)
   {
    ++ndef;
    dev=dev+4;
   }
   if(damagep<hp && k==1)
   {
    f=1;
    if(dev<=252)
     cout<<"\nThe defending Pok‚mon needs atmost "<<dev<<" more defence EVs to survive the attack.";
    if(dev>252)
     cout<<"\n\nThe defending Pok‚mon may not survive the attack even with 252 more defence EVs.";
   }
   if(damagepm<hp && k==0)
   {
    k=1;
    if(dev<=252 && dev!=0)
     cout<<"\n\nThe defending Pok‚mon needs atleast "<<dev<<" more defence EVs to survive the attack.\n";
    if(dev>252)
    {
     f=1;
     cout<<"\n\nThe defending Pok‚mon won't survive the attack even with 252 more attack EVs.";
    }
   }
  }
 }


 cout<<"\n\n\t\tCritical Hit -> "<<critmin<<" - "<<critmax;
 cout<<"\n\t\tWhich is, "<<cmin<<"% - "<<cmax<<"%";

 cout<<"\n\n\n\n\n\n\tDo you want do do more calculations (y or n) ?";
 cin>>ch;
 if(ch=='y')
  dcalculator();

 getch();
 menu();
}

void main()
{
 menu();
}
Well, thats it i guess. Any suggestions on features or making the program more efficient are welcome.
Also, please notify me in case of any errors.


Thank You


 
I think we can safely say it doesn't work on linux...

Code:
tim@tim-laptop:~/Desktop$ g++ xenon.c
In file included from /usr/include/c++/4.1.3/backward/iostream.h:31,
                 from xenon.c:1:
/usr/include/c++/4.1.3/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
xenon.c:2:19: error: conio.h: No such file or directory
xenon.c:4:17: error: dos.h: No such file or directory
xenon.c:5:21: error: process.h: No such file or directory
xenon.c: In function ‘void introduction()’:
xenon.c:12: error: ‘clrscr’ was not declared in this scope
xenon.c:22: error: ‘getch’ was not declared in this scope
xenon.c: In function ‘void cred()’:
xenon.c:28: error: ‘clrscr’ was not declared in this scope
xenon.c:35: error: name lookup of ‘a’ changed for new ISO ‘for’ scoping
xenon.c:31: error:   using obsolete binding at ‘a’
xenon.c:38: error: ‘getch’ was not declared in this scope
xenon.c: In function ‘void menu()’:
xenon.c:44: error: ‘clrscr’ was not declared in this scope
xenon.c:70: error: name lookup of ‘a’ changed for new ISO ‘for’ scoping
xenon.c:61: error:   using obsolete binding at ‘a’
xenon.c:87: error: ‘getch’ was not declared in this scope
xenon.c:93: error: ‘getch’ was not declared in this scope
xenon.c: In function ‘void dcalculator()’:
xenon.c:100: error: ‘clrscr’ was not declared in this scope
xenon.c:118: warning: converting to ‘int’ from ‘float’
xenon.c:122: warning: converting to ‘int’ from ‘float’
xenon.c:140: warning: converting to ‘int’ from ‘float’
xenon.c:144: warning: converting to ‘int’ from ‘float’
xenon.c:185: warning: converting to ‘int’ from ‘double’
xenon.c:186: warning: converting to ‘int’ from ‘double’
xenon.c:187: warning: converting to ‘int’ from ‘double’
xenon.c:188: warning: converting to ‘int’ from ‘double’
xenon.c:196: error: ‘delay’ was not declared in this scope
xenon.c:202: error: ‘gotoxy’ was not declared in this scope
xenon.c:236: warning: converting to ‘int’ from ‘double’
xenon.c:237: warning: converting to ‘int’ from ‘double’
xenon.c:279: warning: converting to ‘int’ from ‘double’
xenon.c:280: warning: converting to ‘int’ from ‘double’
xenon.c:322: error: ‘getch’ was not declared in this scope
xenon.c: At global scope:
xenon.c:326: error: ‘::main’ must return ‘int’
 
Actually, Burn would be more accurately accounted for in the Reflect/Light Screen modifier...

Still, for what this is trying to accomplish, it does a nice job of it. I still have to memorize certain stats, however, but that's a personal quip.

Two things about your formula, though:

1. The Critical Hit modifier should be applied before Life Orb (no problem here), but Life Orb should be applied before the random number.

2. STAB should be applied before effectiveness. Also consider splitting the effectiveness into Type1 and Type2 (optional considering this calculator's purpose).



Again, this is a really simple calculator and definitely would be sufficient for most people's needs. If you, Xenon, wish to add to it, I would suggest looking to this damage calculator for ideas, as it also goes the simple route yet doesn't suffer from many of the inherent limitations that your calculator has.
 
timw06 said:
I think we can safely say it doesn't work on linux...
Thanks a lot for posting the error log as well. I thin i get what should be edited to make it work on linux. Will add the Linux version in around 2 days if what i assume is correct.


CardsOfTheHeart said:
Actually, Burn would be more accurately accounted for in the Reflect/Light Screen modifier...

Still, for what this is trying to accomplish, it does a nice job of it. I still have to memorize certain stats, however, but that's a personal quip.

Two things about your formula, though:

1. The Critical Hit modifier should be applied before Life Orb (no problem here), but Life Orb should be applied before the random number.

2. STAB should be applied before effectiveness. Also consider splitting the effectiveness into Type1 and Type2 (optional considering this calculator's purpose).

Well, I'll do these changes mostly by tomorrow, thanks for mentioning these.

This is what X-Act's formula says :

Damage Formula = (((((((Level × 2 ÷ 5) + 2) × BasePower × [Sp]Atk ÷ 50) ÷ [Sp]Def) × Mod1) + 2) × CH × Mod2 × R ÷ 100) × STAB × Type1 × Type2 × Mod3


Since (CH x Mod2 = Mod2 x CH) i don't think it makes a difference, correct me if i am wrong. The same goes to STAB and Effectiveness, i don't understand the difference :(
 
What I would really like to see in a damage calculator is the option to - instead of just entering the (Special) Attack and (Special) Defense - just fill in the pokemon, nature and EVs (possibly IVs, but even without it'd be a huge improvement) and then for the program to calculate the damage.
 
Kindred said:
What I would really like to see in a damage calculator is the option to - instead of just entering the (Special) Attack and (Special) Defense - just fill in the pokemon, nature and EVs (possibly IVs, but even without it'd be a huge improvement) and then for the program to calculate the damage.
It is actually a very tedious work to enter the stats of all the 493 Pokemons in a program and then calculate.

Anyway, check CardsOfTheHeart's signature and download that Pokemon Resource, it does exactly what you want.
 
Since (CH x Mod2 = Mod2 x CH) i don't think it makes a difference, correct me if i am wrong. The same goes to STAB and Effectiveness, i don't understand the difference :(
If the formula wasn't flooring after each operation, than no, it would never be a problem, but...

Ex. 336, Critical Hit, Life Orb

336 * 2 = 672 * 1.3 =873.6-> 873

336 * 1.3 =436.8-> 436 * 2 = 872

Ex. 201, STAB, 2x effective

201 * 1.5 =301.5-> 301 * 2 = 602

201 * 2 = 402 * 1.5 = 603

It's not much of a difference, but accuracy should always be a top priority. You can't fudge too much with the actual formula thanks to all of the flooring because it will change some of the results.


It is actually a very tedious work to enter the stats of all the 493 Pokemons in a program and then calculate.
I can attest to this, as it took quite a bit of time to compile the Base Stats for my Resource. Keep in mind that I did it while the main site was down so I had to cross-reference several resources such as Serebii to make sure that the stats were accurate.
 
CardsOfTheHeart said:
If the formula wasn't flooring after each operation, than no, it would never be a problem, but...

Ex. 336, Critical Hit, Life Orb

336 * 2 = 672 * 1.3 =873.6-> 873

336 * 1.3 =436.8-> 436 * 2 = 872

Ex. 201, STAB, 2x effective

201 * 1.5 =301.5-> 301 * 2 = 602

201 * 2 = 402 * 1.5 = 603

It's not much of a difference, but accuracy should always be a top priority. You can't fudge too much with the actual formula thanks to all of the flooring because it will change some of the results.
I forgot to floor those two, so it doesn't matter in mine, anyway thanks for mentioning this, I'll edit my calculator.
 

Users Who Are Viewing This Thread (Users: 1, Guests: 0)

Top