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
|
#include "ground.h"
#include "gst.h"
#include <iostream>
#include <algorithm>
Ground::Ground (int sx, int sy) {
sizex = sx; sizey = sy;
tiles = new int[sx*sy];
for (int i=0; i<sx*sy; i++) tiles[i] = 0;
}
Ground::~Ground () {
}
int Ground::at(int x, int y) {
return x+y*sizex;
}
// areas
std::vector<int> Ground::star (int pos) {
std::vector<int> fs;
int x = pos % sizex, y = pos / sizex;
if (x-1 >= 0) { fs.push_back(at(x-1, y)); }
if (x+1 < sizex) { fs.push_back(at(x+1, y)); }
if (y-1 >= 0) { fs.push_back(at(x, y-1)); }
if (y+1 < sizey) { fs.push_back(at(x, y+1)); }
return fs;
}
class step { public:
step(int pos, int m) : pos(pos), m(m) {};
bool operator==(step oth) { return pos==oth.pos && m==oth.m; }
bool operator==(int p) { return pos==p; }
int pos, m;
};
std::vector<int> Ground::move_area (Gst &gst, Entity &ent) {
std::vector<int> moves;
std::vector<int> visited { at(ent.x, ent.y) };
std::vector<step> frontier { step { at(ent.x, ent.y), ent.info->move } };
int maxcost = 99;
if (gst.info_has_ability(ent.info, "Scout")) maxcost = 2;
int iter=0;
for (; iter<10000; iter++) {
if (frontier.size() == 0) break;
step maxf {-1, -1};
for (step t : frontier) {
if (t.m > maxf.m) {
maxf.pos = t.pos;
maxf.m = t.m;
}
}
frontier.erase(std::remove(frontier.begin(), frontier.end(), maxf),
frontier.end());
auto forward_star = star(maxf.pos);
for (int t : forward_star) {
if (!(std::find(visited.begin(), visited.end(), t) != visited.end())
&& !(std::find(frontier.begin(), frontier.end(), t) != frontier.end())) {
int movecost = gst.tiles[gst.ground.tiles[t]].move_cost;
if (movecost > maxcost) movecost = maxcost;
int walkedm = maxf.m - movecost;
bool obstructed = false;
for (Entity &e : gst.entities) {
if (e.owner != ent.owner && at(e.x, e.y) == t) {
obstructed = true;
break;
}
}
if (walkedm >= 0 && !obstructed) {
frontier.emplace_back(t, walkedm);
moves.push_back(t);
}
}
}
visited.push_back(maxf.pos);
}
std::cout << "iters: " << iter;
return moves;
}
std::vector<int> Ground::attack_targets (Gst &gst, Entity &ent) {
std::vector<int> attacks;
int range = ent.info->range;
range += gst.tiles[gst.ground.tiles[gst.ground.at(ent.x, ent.y)]]
.range_bonus;
bool builds = !gst.info_has_ability(ent.info, "Units Only");
bool units = !gst.info_has_ability(ent.info, "Buildings Only");
for (Entity &e : gst.entities) {
if (!units && e.info->unit == 1) continue;
if (!builds && e.info->unit == 0) continue;
if (e.owner != ent.owner && abs(e.x-ent.x)+abs(e.y-ent.y) <= range) {
attacks.push_back(at(e.x, e.y));
}
}
return attacks;
}
|