ANTWAR C++ SDK
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1
11#pragma once
12
13#include <iostream>
14#include <vector>
15#include <algorithm>
16#include <cmath>
17#include "optional.hpp"
18
22static constexpr int MAX_ROUND = 512;
23
24/* Map */
25
29enum class BuildingType
30{
31 Empty,
32 Tower,
33 Base
34};
35
40static constexpr int EDGE = 10;
41
46static constexpr int MAP_SIZE = 2 * EDGE - 1;
47
52 Void = -1,
53 Path = 0,
54 Barrier = 1,
57};
58
62static constexpr int MAP_PROPERTY[MAP_SIZE][MAP_SIZE] = {
63 {-1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1},
64 {-1, -1, -1, -1, -1, -1, 0, 0, 1, 0, 1, 0, 0, -1, -1, -1, -1, -1, -1},
65 {-1, -1, -1, -1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, -1, -1, -1, -1},
66 {-1, -1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, -1, -1},
67 {0, 0, 2, 2, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 2, 2, 0, 0},
68 {0, 0, 0, 2, 0, 0, 2, 2, 0, 2, 0, 2, 2, 0, 0, 2, 0, 0, 0},
69 {0, 2, 2, 0, 2, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 0, 2, 2, 0},
70 {0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0},
71 {0, 0, 2, 0, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2, 0, 2, 0, 0},
72 {0, 1, 3, 0, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 3, 0, 3, 1, 0},
73 {0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0},
74 {0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0},
75 {0, 3, 0, 0, 0, 0, 3, 3, 0, 3, 0, 3, 3, 0, 0, 0, 0, 3, 0},
76 {0, 0, 3, 3, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 3, 3, 0, 0},
77 {-1, 0, 0, 3, 0, 1, 1, 0, 0, 3, 0, 0, 1, 1, 0, 3, 0, 0, -1},
78 {-1, -1, -1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, -1, -1, -1},
79 {-1, -1, -1, -1, -1, 0, 0, 1, 1, 0, 1, 1, 0, 0, -1, -1, -1, -1, -1},
80 {-1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1},
81 {-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
82};
83
103static constexpr int OFFSET[2][6][2] = {{{0, 1}, {-1, 0}, {0, -1}, {1, -1}, {1, 0}, {1, 1}},
104 {{-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, 0}, {0, 1}}};
105
114inline int distance(int x0, int y0, int x1, int y1)
115{
116 int dy = abs(y0 - y1);
117 int dx;
118 if (abs(y0 - y1) % 2)
119 {
120 if (x0 > x1)
121 dx = std::max(0, abs(x0 - x1) - abs(y0 - y1) / 2 - (y0 % 2));
122 else
123 dx = std::max(0, abs(x0 - x1) - abs(y0 - y1) / 2 - (1 - (y0 % 2)));
124 }
125 else
126 dx = std::max(0, abs(x0 - x1) - abs(y0 - y1) / 2);
127
128 return dx + dy;
129}
130
137inline bool is_valid_pos(int x, int y)
138{
139 if (x < 0 || x >= MAP_SIZE || y < 0 || y >= MAP_SIZE)
140 return false;
141 return MAP_PROPERTY[x][y] != PointType::Void;
142}
143
150inline bool is_path(int x, int y)
151{
152 if (x < 0 || x >= MAP_SIZE || y < 0 || y >= MAP_SIZE)
153 return false;
154 return MAP_PROPERTY[x][y] == PointType::Path;
155}
156
163inline bool is_highland(int player, int x, int y)
164{
165 if (x < 0 || x >= MAP_SIZE || y < 0 || y >= MAP_SIZE)
166 return false;
168}
169
178inline int get_direction(int x0, int y0, int x1, int y1)
179{
180 int dx = x1 - x0;
181 int dy = y1 - y0;
182 for (int i = 0; i < 6; ++i)
183 {
184 if (OFFSET[y0 % 2][i][0] == dx && OFFSET[y0 % 2][i][1] == dy)
185 return i;
186 }
187 return -1;
188}
189
190/* Coin */
191
192static constexpr int COIN_INIT = 50,
193 BASIC_INCOME = 1;
194static constexpr int TOWER_BUILD_PRICE_BASE = 15,
195 TOWER_BUILD_PRICE_RATIO = 2;
196static constexpr int LEVEL2_TOWER_UPGRADE_PRICE = 60,
197 LEVEL3_TOWER_UPGRADE_PRICE = 200;
198static constexpr double TOWER_DOWNGRADE_REFUND_RATIO = 0.8;
199static constexpr int LEVEL2_BASE_UPGRADE_PRICE = 200,
200 LEVEL3_BASE_UPGRADE_PRICE = 250;
201
202/* Pheromone */
203
204static constexpr double PHEROMONE_INIT = 10,
205 PHEROMONE_MIN = 0,
206 PHEROMONE_ATTENUATING_RATIO = 0.97;
207
208
209/* Entity */
210
218{
219 Alive = 0,
221 Fail = 2,
222 TooOld = 3,
223 Frozen = 4
225
229struct Ant
230{
231 // Attributes
232 int id, player;
233 int x, y;
234 int hp, level, age;
235 AntState state;
236 std::vector<int> path;
237 int evasion; // tag for emergency evasion
238 bool deflector; // tag for deflector
239 // Static info
240 static constexpr int AGE_LIMIT = 32;
241 static constexpr int MAX_HP_INFO[] = {10, 25, 50}; // Max HP of an ant of certain level
242 static constexpr int REWARD_INFO[] = {3, 5, 7}; // Reward for killing an ant of certain level
243
247 Ant(int id, int player, int x, int y, int hp, int level, int age, AntState state)
248 : id(id), player(player), x(x), y(y), hp(hp), level(level), age(age), state(state), evasion(0), deflector(false) {}
249
254 void move(int direction)
255 {
256 path.push_back(direction);
257 x += OFFSET[y % 2][direction][0];
258 y += OFFSET[y % 2][direction][1];
259 }
260
264 int max_hp() const
265 {
266 return MAX_HP_INFO[level];
267 }
268
272 int reward() const
273 {
274 return REWARD_INFO[level];
275 }
276
281 bool is_alive() const
282 {
283 return state == AntState::Alive || state == AntState::Frozen;
284 }
285
293 bool is_in_range(int x, int y, int range) const
294 {
295 return distance(this->x, this->y, x, y) <= range;
296 }
297
305 bool is_attackable_from(int player, int x, int y, int range) const
306 {
307 return this->player != player && is_alive() && is_in_range(x, y, range);
308 }
309};
310
311constexpr int Ant::MAX_HP_INFO[];
312constexpr int Ant::REWARD_INFO[];
313
319{
320 // Basic
321 Basic = 0,
322 // Heavy class
323 Heavy = 1,
324 HeavyPlus = 11,
325 Ice = 12,
326 Cannon = 13,
327 // Quick class
328 Quick = 2,
329 QuickPlus = 21,
330 Double = 22,
331 Sniper = 23,
332 // Mortar class
333 Mortar = 3,
334 MortarPlus = 31,
335 Pulse = 32,
336 Missile = 33
337};
338
343{
344 int attack;
345 double speed;
346 int range;
347};
348
352constexpr TowerInfo TOWER_INFO[] = {
353 {5, 2, 2}, // ID = 0
354 {20, 2, 2}, // ID = 1
355 {6, 1, 3}, // ID = 2
356 {16, 4, 3}, // ID = 3
357 {}, {}, {}, {}, {}, {}, {}, // Padding
358 {35, 2, 3}, // ID = 11
359 {15, 2, 2}, // ID = 12
360 {50, 3, 3}, // ID = 13
361 {}, {}, {}, {}, {}, {}, {}, // Padding
362 {8, 0.5, 3}, // ID = 21
363 {7, 1, 4}, // ID = 22
364 {15, 2, 6}, // ID = 23
365 {}, {}, {}, {}, {}, {}, {}, // Padding
366 {35, 4, 4}, // ID = 31
367 {30, 3, 2}, // ID = 32
368 {45, 6, 5} // ID = 33
369};
370
374struct Tower
375{
376 int id, player;
377 int x, y;
378 TowerType type;
379 int damage, range;
380 int cd;
381 double speed;
382
388 Tower(int id, int player, int x, int y, TowerType type = TowerType::Basic, int cd = -1)
389 : id(id), player(player), x(x), y(y), type(type), cd(cd)
390 {
391 upgrade(type); // CD is reset to the max
392 if (cd != -1) // If CD is given
393 this->cd = cd;
394 }
403 {
404 std::vector<int> attacked_idxs;
405 // Count down CD
406 cd = std::max(cd - 1, 0);
407 if (cd <= 0) // Ready to attack
408 {
409 // How many times the tower will try to find targets in this turn
410 int time = speed >= 1 ? 1 : (1 / speed);
411 // How many targets the tower should find each time (maybe less than required number)
412 int target_num = type == Double ? 2 : 1;
413 // Find and action
414 while (time--)
415 {
416 std::vector<int> target_idxs = find_targets(ants, target_num);
417 std::vector<int> attackable_idxs = find_attackable(ants, target_idxs);
418 for (int idx: attackable_idxs)
419 action(ants[idx]);
420 attacked_idxs.insert(attacked_idxs.end(), attackable_idxs.begin(), attackable_idxs.end());
421 }
422 // Uniquify to prevent multiple occurances of the same ant
423 std::sort(attacked_idxs.begin(), attacked_idxs.end());
424 attacked_idxs.erase(std::unique(attacked_idxs.begin(), attacked_idxs.end()), attacked_idxs.end());
425 // Reset CD if really attacks
426 if (!attacked_idxs.empty())
427 reset_cd();
428 }
429 return attacked_idxs;
430 }
431
441 std::vector<int> find_targets(const std::vector<Ant>& ants, int target_num) const
442 {
443 // Initialize index array for reference
444 std::vector<int> idxs = get_attackable_ants(ants, x, y, range);
445 // Partial sort to get first n elements
446 auto bound = target_num <= idxs.size() ? (idxs.begin() + target_num) : idxs.end();
447 std::partial_sort(idxs.begin(), bound, idxs.end(), [&] (int i, int j) {
448 int dist1 = distance(ants[i].x, ants[i].y, x, y),
449 dist2 = distance(ants[j].x, ants[j].y, x, y);
450 if (dist1 != dist2)
451 return dist1 < dist2;
452 else
453 return i < j;
454 });
455 // Get first n elements
456 if (idxs.size() > target_num)
457 idxs.resize(target_num);
458 return idxs;
459 }
460
470 {
471 std::vector<int> attackable_idxs;
472 for (int idx: target_idxs)
473 {
475 switch (type)
476 {
477 case Mortar:
478 tmp = get_attackable_ants(ants, ants[idx].x, ants[idx].y, 1);
479 break;
480 case MortarPlus:
481 tmp = get_attackable_ants(ants, ants[idx].x, ants[idx].y, 1);
482 break;
483 case Pulse:
484 tmp = get_attackable_ants(ants, x, y, range);
485 break;
486 case Missile:
487 tmp = get_attackable_ants(ants, ants[idx].x, ants[idx].y, 2);
488 break;
489 default:
490 tmp = {idx};
491 }
492 attackable_idxs.insert(attackable_idxs.end(), tmp.begin(), tmp.end());
493 }
494 return attackable_idxs;
495 }
496
501 void action(Ant& ant) const
502 {
503 if (ant.evasion > 0) // evasion effect
504 ant.evasion--; // count down times
505 else if (ant.deflector && damage < ant.max_hp() / 2) // deflector effect
506 return; // get no damage
507 else // normal condition
508 {
509 ant.hp -= damage;
510 if (type == Ice)
511 ant.state = AntState::Frozen;
512 if (ant.hp <= 0)
513 ant.state = AntState::Fail;
514 }
515 }
516
525 std::vector<int> get_attackable_ants(const std::vector<Ant>& ants, int x, int y, int range) const
526 {
527 std::vector<int> idxs;
528 for (int i = 0; i < ants.size(); ++i)
529 if (ants[i].is_attackable_from(player, x, y, range))
530 idxs.push_back(i);
531 return idxs;
532 }
533
538 bool is_ready() const
539 {
540 return cd <= 0;
541 }
542
546 void reset_cd()
547 {
548 cd = speed > 1 ? speed : 1;
549 }
550
555 void upgrade(TowerType new_type)
556 {
557 type = new_type;
558 damage = TOWER_INFO[new_type].attack;
559 speed = TOWER_INFO[new_type].speed;
560 range = TOWER_INFO[new_type].range;
561 reset_cd(); // Reset when `speed` has changed
562 }
563
569 bool is_upgrade_type_valid(int type) const
570 {
571 if (type < TowerType::Basic || type > TowerType::Missile)
572 return false;
573 switch (this->type)
574 {
575 case TowerType::Basic:
576 return type == TowerType::Heavy || type == TowerType::Quick || type == TowerType::Mortar;
577 case TowerType::Heavy:
578 return type == TowerType::HeavyPlus || type == TowerType::Ice || type == TowerType::Cannon;
579 case TowerType::Quick:
580 return type == TowerType::QuickPlus || type == TowerType::Double || type == TowerType::Sniper;
581 case TowerType::Mortar:
582 return type == TowerType::MortarPlus || type == TowerType::Pulse || type == TowerType::Missile;
583 }
584 return false;
585 }
586
591 {
592 type = static_cast<TowerType>(type / 10);
593 damage = TOWER_INFO[type].attack;
594 speed = TOWER_INFO[type].speed;
595 range = TOWER_INFO[type].range;
596 reset_cd(); // Reset when `speed` has changed
597 }
598
604 {
605 return type != TowerType::Basic;
606 }
607};
608
612struct Base
613{
614 // Attributes
615 const int player, x, y;
616 int hp;
619 // Static info
620 static constexpr int MAX_HP = 50;
621 static constexpr int POSITION[2][2] = {{2, EDGE - 1}, {(MAP_SIZE - 1) - 2, EDGE - 1}};
622 static constexpr int GENERATION_CYCLE_INFO[] = {4, 2, 1};
623
624 Base(int player)
625 : player(player), x(POSITION[player][0]), y(POSITION[player][1]), hp(MAX_HP),
626 gen_speed_level(0), ant_level(0) {}
627
634 optional<Ant> generate_ant(int id, int round)
635 {
636 return round % GENERATION_CYCLE_INFO[gen_speed_level] == 0
637 ? make_optional(Ant(
638 id, player, x, y,
639 Ant::MAX_HP_INFO[ant_level], ant_level,
640 0, AntState::Alive
641 ))
642 : nullopt;
643 }
644
649 {
651 }
652
657 {
658 ant_level++;
659 }
660};
661
662constexpr int Base::POSITION[2][2];
663constexpr int Base::GENERATION_CYCLE_INFO[];
664
670{
671 LightningStorm = 1,
672 EmpBlaster = 2,
673 Deflector = 3,
674 EmergencyEvasion = 4,
675 SuperWeaponCount
676};
677
682static constexpr int SUPER_WEAPON_INFO[5][4] = {
683 {}, // Padding
684 {20, 3, 100, 150}, // LightningStorm
685 {20, 3, 100, 150}, // EmpBlaster
686 {10, 3, 50, 100}, // Deflector
687 {1, 3, 50, 100} // Evasion
688};
689
694{
695 SuperWeaponType type;
696 int player;
697 int x, y;
698 int left_time;
699 int range;
700
701 SuperWeapon(SuperWeaponType type, int player, int x, int y) :
702 type(type), player(player), x(x), y(y), left_time(SUPER_WEAPON_INFO[type][0]), range(SUPER_WEAPON_INFO[type][1]) {}
703
710 bool is_in_range(int x, int y) const
711 {
712 return distance(x, y, this->x, this->y) <= range;
713 }
714};
715
716/* Operation */
717
723{
724 // Towers
728 // Super weapons
733 // Base
737
742{
743 OperationType type;
744 int arg0, arg1;
745 static constexpr int INVALID_ARG = -1;
746
753 Operation(OperationType type, int arg0 = INVALID_ARG, int arg1 = INVALID_ARG)
754 : type(type), arg0(arg0), arg1(arg1) {}
755
756 friend std::ostream& operator<<(std::ostream& out, const Operation& op)
757 {
758 out << op.type;
759 if (op.arg0 != INVALID_ARG)
760 out << ' ' << op.arg0;
761 if (op.arg1 != INVALID_ARG)
762 out << ' ' << op.arg1;
763 out << std::endl;
764 return out;
765 }
766};
767
771struct Random
772{
773 unsigned long long seed;
774
775 Random(unsigned long long seed): seed(seed) {}
776
777 unsigned long long get()
778 {
779 seed = (25214903917 * seed) & ((1ll << 48) - 1);
780 return seed;
781 }
782};
T begin(T... args)
static constexpr int EDGE
Length of one edge.
Definition: common.hpp:40
bool is_highland(int player, int x, int y)
Check if a player can build towers at given position.
Definition: common.hpp:163
SuperWeaponType
Tag for the type of a super weapon. The integer values of these enumeration items are also their inde...
Definition: common.hpp:670
PointType
Tag indicating property of points.
Definition: common.hpp:51
@ Path
Ants can pass through here.
Definition: common.hpp:53
@ Void
Out of the map.
Definition: common.hpp:52
@ Barrier
No passing or building here.
Definition: common.hpp:54
@ Player1Highland
Player1 can have buildings here.
Definition: common.hpp:56
@ Player0Highland
Player0 can have buildings here.
Definition: common.hpp:55
static constexpr int SUPER_WEAPON_INFO[5][4]
Static information of all types of super weapons.
Definition: common.hpp:682
TowerType
Tag for the type of a tower. The integer values of these enumeration items are also their indexes.
Definition: common.hpp:319
int get_direction(int x0, int y0, int x1, int y1)
Get the direction of two adjacent points, starting from the first and pointing to the second.
Definition: common.hpp:178
constexpr TowerInfo TOWER_INFO[]
Static information of all types of tower.
Definition: common.hpp:352
static constexpr int MAP_PROPERTY[MAP_SIZE][MAP_SIZE]
Point types of the map.
Definition: common.hpp:62
static constexpr int MAX_ROUND
Max number of rounds.
Definition: common.hpp:22
static constexpr int MAP_SIZE
Size of the map.
Definition: common.hpp:46
static constexpr int OFFSET[2][6][2]
The offsets between the coordinates of the current point and its surrounding 6 points.
Definition: common.hpp:103
OperationType
Tag for the type of an operation. The integer values of these enumeration items are also their indexe...
Definition: common.hpp:723
@ UpgradeTower
Upgrade a tower.
Definition: common.hpp:726
@ UseEmpBlaster
Use an EMP blaster.
Definition: common.hpp:730
@ UpgradeGenerationSpeed
Increase ant producing speed.
Definition: common.hpp:734
@ UpgradeGeneratedAnt
Increase HP of newly generated ants.
Definition: common.hpp:735
@ UseDeflector
Use a deflector.
Definition: common.hpp:731
@ UseEmergencyEvasion
Use an emergency evasion.
Definition: common.hpp:732
@ BuildTower
Build a tower.
Definition: common.hpp:725
@ DowngradeTower
Downgrade/Destroy a tower.
Definition: common.hpp:727
@ UseLightningStorm
Use a lightning storm.
Definition: common.hpp:729
AntState
State of an ant, indicating its life cycle stages.
Definition: common.hpp:218
@ Frozen
Frozen, cannot move.
Definition: common.hpp:223
@ Fail
Non-positive health points (HP)
Definition: common.hpp:221
@ TooOld
Reach age limit.
Definition: common.hpp:222
@ Alive
Normal case.
Definition: common.hpp:219
@ Success
Reach the opponent's camp.
Definition: common.hpp:220
int distance(int x0, int y0, int x1, int y1)
Get the distance between two points on the map (NOT Euclidean distance).
Definition: common.hpp:114
BuildingType
A tag indicating the type of a building on the map.
Definition: common.hpp:30
bool is_path(int x, int y)
Check if the given position is reachable for ants.
Definition: common.hpp:150
bool is_valid_pos(int x, int y)
Check if the given coordinates refers to a valid point on the map.
Definition: common.hpp:137
T empty(T... args)
T end(T... args)
T endl(T... args)
T erase(T... args)
T insert(T... args)
T max(T... args)
T partial_sort(T... args)
T push_back(T... args)
T resize(T... args)
T size(T... args)
T sort(T... args)
Basic attacking unit.
Definition: common.hpp:230
int reward() const
Reward for killing this ant.
Definition: common.hpp:272
bool is_alive() const
Check if the ant is alive, including states AntState::Alive and AntState::Frozen.
Definition: common.hpp:281
bool is_in_range(int x, int y, int range) const
Check if the ant stays in a circle with given point as the center.
Definition: common.hpp:293
Ant(int id, int player, int x, int y, int hp, int level, int age, AntState state)
Construct a new ant with given information.
Definition: common.hpp:247
void move(int direction)
Move the ant in a specified direction.
Definition: common.hpp:254
bool is_attackable_from(int player, int x, int y, int range) const
Check if the ant is attackable by a player from given position and range.
Definition: common.hpp:305
int max_hp() const
HP limit of this ant.
Definition: common.hpp:264
Target to protect or to destroy.
Definition: common.hpp:613
void upgrade_generated_ant()
Upgrade ant generation speed.
Definition: common.hpp:656
int gen_speed_level
Level of production speed.
Definition: common.hpp:617
void upgrade_generation_speed()
Upgrade ant generation speed.
Definition: common.hpp:648
static constexpr int POSITION[2][2]
Positions for both players.
Definition: common.hpp:621
optional< Ant > generate_ant(int id, int round)
Try to generate a new ant.
Definition: common.hpp:634
int ant_level
Level of produced ants.
Definition: common.hpp:618
static constexpr int GENERATION_CYCLE_INFO[]
Ants will be generated when round index can be divided by this value.
Definition: common.hpp:622
Player's operations. It is able to be applied to the map.
Definition: common.hpp:742
Operation(OperationType type, int arg0=INVALID_ARG, int arg1=INVALID_ARG)
Construct a new Operation object with specified type and arguments.
Definition: common.hpp:753
static constexpr int INVALID_ARG
Placeholder for the second argument.
Definition: common.hpp:745
Random noise generator.
Definition: common.hpp:772
unsigned long long seed
Seed for pheromone random initialization.
Definition: common.hpp:773
Great choice to knockout your opponent.
Definition: common.hpp:694
bool is_in_range(int x, int y) const
Check whether given position is in the range of effect.
Definition: common.hpp:710
Structure of static information of a type of towers.
Definition: common.hpp:343
double speed
Number of rounds required for an attack.
Definition: common.hpp:345
int range
Radius of searching range.
Definition: common.hpp:346
Defense unit. Only choice to get yourself armed to the teeth.
Definition: common.hpp:375
void upgrade(TowerType new_type)
Upgrade tower to new type and reset CD, without checking validness.
Definition: common.hpp:555
bool is_downgrade_valid() const
Check if the tower can be downgraded.
Definition: common.hpp:603
std::vector< int > find_attackable(const std::vector< Ant > &ants, const std::vector< int > &target_idxs) const
Find all ants affected by this attack based on given targets.
Definition: common.hpp:469
std::vector< int > get_attackable_ants(const std::vector< Ant > &ants, int x, int y, int range) const
Find all attackable ants based on given position and range.
Definition: common.hpp:525
void reset_cd()
Reset CD value.
Definition: common.hpp:546
std::vector< int > find_targets(const std::vector< Ant > &ants, int target_num) const
Find certain amount of targets and return its reference by index in order.
Definition: common.hpp:441
std::vector< int > attack(std::vector< Ant > &ants)
Try to attack ants around, and update CD time.
Definition: common.hpp:402
Tower(int id, int player, int x, int y, TowerType type=TowerType::Basic, int cd=-1)
Construct a new tower with given information.
Definition: common.hpp:388
bool is_upgrade_type_valid(int type) const
Check if the tower can be upgraded to a certain type.
Definition: common.hpp:569
int cd
Time remaining until next attack (Possibly negative)
Definition: common.hpp:380
bool is_ready() const
Check if the tower is ready to attack.
Definition: common.hpp:538
void action(Ant &ant) const
Cause real damage and other effects on the target.
Definition: common.hpp:501
void downgrade()
Downgrade tower to new type and reset CD, without checking validness.
Definition: common.hpp:590
double speed
Number of rounds required for an attack.
Definition: common.hpp:381
T unique(T... args)