-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBattle_Implementation.cpp
More file actions
114 lines (91 loc) · 3.69 KB
/
Copy pathBattle_Implementation.cpp
File metadata and controls
114 lines (91 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//
// Battle_Implementation.cpp
//
// Created by MAQ on 07/08/25.
#include "pokemon_game.hpp"
// function to calculate type effectiveness multiplier
double BattleTurn::calculateTypeEffectiveness(Type moveType, const Pokemon& defender)
{
double effectiveness = 1.0;
vector<Type> weaknesses = defender.getWeakness(); // Pokemons weakness
for (Type weak : weaknesses)
{
if (moveType == weak)
{
effectiveness *= 2.0;
}
}
return effectiveness;
// Say if a pokemon is water and flying, then it's (2*2) weak to electric
}
// function to calculate damage using standard Pokemon formula ( basically the move selected by attacking pokemon will damage the defender)
int BattleTurn::calculateDamage(const Pokemon& attacker, const Pokemon& defender, const Moves& move)
{
double effectiveness = calculateTypeEffectiveness(move.getType(), defender);
double stab = (move.getType() == attacker.getType()) ? 1.5 : 1.0;
double random = (rand() % (100 - 80 + 1) + 80)/100.0; // Random number from 0.80 to 1.00
// This formula is actually a modification (simplification) of the offical damage formula
int damage = ((2 * attacker.getLevel() / 5 + 2) *
move.getDamage() *
attacker.getAttack() /
defender.getDefence() /
50 + 2) * stab * effectiveness * random;
/*
the formula:
<[((2 x level / 5) + 2) x (damage x attack / defence) / 50 + 2] x stab x effective x rand>
*/
return damage;
}
// function to check if move hits based on accuracy
bool BattleTurn::checkAccuracy(const Moves& move)
{
return ((rand() % 100) < move.getAccuracy());
}
// function to execute player's turn
void BattleTurn::playerTurn(Player& player, AI& ai)
{
Pokemon& playerPokemon = player.getFirstUsablePokemon();
Pokemon& aiPokemon = ai.getFirstUsablePokemon();
int moveIndex = player.selectMove(playerPokemon);
vector<Moves>& playerMoves = playerPokemon.getMoves(); // Reference to original vector
Moves& move = playerMoves[moveIndex]; // Reference to original move
if (!checkAccuracy(move))
{
cout << playerPokemon.getNickname() << "'s attack missed!\n";
return;
}
move.decrementUses(); //reduce the PP
TextForBattle::displayMoveUsed(playerPokemon, move.getName());
int damage = calculateDamage(playerPokemon, aiPokemon, move);
TextForBattle::displayTypeEffectiveness(calculateTypeEffectiveness(move.getType(), aiPokemon));
aiPokemon.takeDamage(damage); // since its player's turn so the AI's pokemon gets damaged
TextForBattle::displayDamageDealt(aiPokemon, damage);
if (aiPokemon.isFainted())
{
TextForBattle::displayPokemonFainted(aiPokemon);
}
}
// function to execute AI's turn
void BattleTurn::aiTurn(Player& player, AI& ai)
{
Pokemon& playerPokemon = player.getFirstUsablePokemon();
Pokemon& aiPokemon = ai.getFirstUsablePokemon();
int moveIndex = ai.selectMove(aiPokemon);
vector<Moves>& aiMoves = aiPokemon.getMoves();
Moves& move = aiMoves[moveIndex];
if (!checkAccuracy(move))
{
cout << aiPokemon.getNickname() << "'s attack missed!\n";
return;
}
move.decrementUses();
TextForBattle::displayMoveUsed(aiPokemon, move.getName());
int damage = calculateDamage(aiPokemon, playerPokemon, move);
TextForBattle::displayTypeEffectiveness(calculateTypeEffectiveness(move.getType(), playerPokemon));
playerPokemon.takeDamage(damage);
TextForBattle::displayDamageDealt(playerPokemon, damage);
if (playerPokemon.isFainted())
{
TextForBattle::displayPokemonFainted(playerPokemon);
}
}