TorchCraftAI
A bot for machine learning research on StarCraft: Brood War
debugging.h
1 /*
2  * Copyright (c) 2017-present, Facebook, Inc.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #pragma once
9 
10 #include <fmt/format.h>
11 #include <sstream>
12 #include <torchcraft/client.h>
13 
14 #include "cherrypi.h"
15 #include "state.h"
16 
17 namespace cherrypi {
18 namespace utils {
19 
20 void spawnUnit(State*, PlayerId, BuildType const*, Position);
21 void spawnUnit(State*, PlayerId, int, Position);
22 void killUnit(State*, Unit*);
23 
24 std::string curTimeString(char const* format = "%Y-%d-%m %H:%M:%S");
25 std::string buildTypeString(BuildType const* buildType);
26 std::string commandString(State* s, tc::Client::Command const& command);
27 inline std::string commandString(Command c) {
28  switch (c) {
29  case Command::None:
30  return std::string("None");
31  case Command::Create:
32  return std::string("Create");
33  case Command::Move:
34  return std::string("Move");
35  case Command::Delete:
36  return std::string("Delete");
37  case Command::Gather:
38  return std::string("Gather");
39  case Command::Scout:
40  return std::string("Scout");
41  case Command::Cancel:
42  return std::string("Cancel");
43  case Command::Harass:
44  return std::string("Harass");
45  case Command::Flee:
46  return std::string("Flee");
47  case Command::SetCreatePriority:
48  return std::string("SetCreatePriority");
49  case Command::ReturnCargo:
50  return std::string("ReturnCargo");
51  case Command::MAX:
52  return std::string("MAX");
53  default:
54  return std::string("?");
55  }
56 }
57 
58 template <typename T>
59 std::string positionString(Vec2T<T> position) {
60  std::ostringstream oss;
61  oss << position;
62  return oss.str();
63 }
64 
65 inline std::string unitString(Unit const* unit) {
66  if (!unit)
67  return "nullptr";
68  std::ostringstream oss;
69  // Log units with 'i' prefix so that we'll be able to use 'u' for UPC tuples
70  oss << (unit->isMine ? "Friendly" : unit->isEnemy ? "Enemy" : "Neutral")
71  << " i" << unit->id << " " << unit->type->name << " " << Position(unit);
72  return oss.str();
73 }
74 
75 template <typename Units>
76 inline std::string unitsString(Units&& units) {
77  std::ostringstream oss;
78  oss << "[";
79  for (auto unit : units) {
80  oss << unitString(unit) << ",";
81  }
82  oss << "]";
83  return oss.str();
84 }
85 
86 template <typename T>
87 inline std::string resourcesString(T&& resources) {
88  std::ostringstream oss;
89  oss << resources.ore << " ore, " << resources.gas << " gas, "
90  << resources.used_psi / 2 << "/" << resources.total_psi / 2 << " psi/2";
91  return oss.str();
92 }
93 
94 inline std::string upcString(UpcId id) {
95  std::ostringstream oss;
96  oss << "u" << id;
97  return oss.str();
98 }
99 
100 inline std::string upcString(std::shared_ptr<UPCTuple> const& upc, UpcId id) {
101  if (!upc) {
102  return upcString(id);
103  }
104  std::ostringstream oss;
105  oss << "u" << id << " (";
106  bool first = true;
107  for (const auto& c : upc->command) {
108  if (!first) {
109  oss << ",";
110  }
111  oss << commandString(c.first) << "=" << c.second;
112  first = false;
113  }
114  if (upc->command.empty()) {
115  oss << "no commands";
116  }
117 
118  // TODO Add more relevant information for specific UPcs?
119 
120  oss << ")";
121  return oss.str();
122 }
123 
124 inline std::string upcTaskString(State* state, UpcId upcId) {
125  const auto& task = state->board()->taskForId(upcId);
126  return {task ? task->getName() : "No task"};
127 }
128 
129 // commandType should be a tc::BW::UnitCommandType,
130 // but the conversion is private
131 inline std::string commandBwString(int commandType) {
132  auto uct = tc::BW::UnitCommandType::_from_integral_nothrow(commandType);
133  return uct ? uct->_to_string() : "???";
134 }
135 
136 inline void
137 drawLine(State* state, Position const& a, Position const& b, int color = 255) {
138  state->board()->postCommand(
139  {tc::BW::Command::DrawLine,
140  a.x * tc::BW::XYPixelsPerWalktile,
141  a.y * tc::BW::XYPixelsPerWalktile,
142  b.x * tc::BW::XYPixelsPerWalktile,
143  b.y * tc::BW::XYPixelsPerWalktile,
144  color},
145  kRootUpcId);
146 }
147 
148 inline void
149 drawLine(State* state, Unit const* a, Unit const* b, int color = 255) {
150  state->board()->postCommand(
151  {tc::BW::Command::DrawUnitLine, a->id, b->id, color}, kRootUpcId);
152 }
153 
154 inline void
155 drawLine(State* state, Unit const* a, Position const& b, int color = 255) {
156  state->board()->postCommand(
157  {tc::BW::Command::DrawUnitPosLine,
158  a->id,
159  b.x * tc::BW::XYPixelsPerWalktile,
160  b.y * tc::BW::XYPixelsPerWalktile,
161  color},
162  kRootUpcId);
163 }
164 
165 inline void
166 drawBox(State* state, Position const& a, Position const& b, int color = 255) {
167  drawLine(state, {a.x, a.y}, {a.x, b.y}, color);
168  drawLine(state, {a.x, a.y}, {b.x, a.y}, color);
169  drawLine(state, {a.x, b.y}, {b.x, b.y}, color);
170  drawLine(state, {b.x, a.y}, {b.x, b.y}, color);
171 }
172 
173 inline void drawBox(State* state, Rect const& r, int color = 255) {
174  drawBox(
175  state,
176  Position(r.left(), r.top()),
177  Position(r.right(), r.bottom()),
178  color);
179 }
180 
181 inline void
182 drawCircle(State* state, Position const& a, int radius, int color = 255) {
183  state->board()->postCommand(
184  {tc::BW::Command::DrawCircle,
185  a.x * tc::BW::XYPixelsPerWalktile,
186  a.y * tc::BW::XYPixelsPerWalktile,
187  radius, // in pixels
188  color},
189  kRootUpcId);
190 }
191 
192 inline void
193 drawCircle(State* state, Unit const* u, int radius, int color = 255) {
194  state->board()->postCommand(
195  {tc::BW::Command::DrawUnitCircle,
196  u->id,
197  radius, // in pixels
198  color},
199  kRootUpcId);
200 }
201 
202 constexpr int kLineHeight = 11;
203 constexpr int kCharacterWidthMax = 5;
204 // Approximation: 4.5px per character; most are 5 and some like 'I' are ~2
205 constexpr double kCharacterWidthAvg = 4.5;
206 
207 inline void
208 drawTextPx(State* state, Position const& a, const std::string& text) {
209  state->board()->postCommand(
210  {tc::BW::Command::DrawText, text, a.x, a.y}, kRootUpcId);
211 }
212 
213 inline void drawText(State* state, Position const& a, const std::string& text) {
214  drawTextPx(
215  state,
216  {a.x * tc::BW::XYPixelsPerWalktile, a.y * tc::BW::XYPixelsPerWalktile},
217  text);
218 }
219 
221  State* state,
222  Position const& a,
223  const std::vector<std::string>& lines) {
224  int pixelWidth = 0;
225  int pixelHeight = 0;
226  for (auto line : lines) {
227  int lineWidth = static_cast<int>(kCharacterWidthAvg * line.length());
228  pixelWidth = std::max(pixelWidth, lineWidth);
229  pixelHeight += kLineHeight;
230  }
231  const int x = a.x - pixelWidth / 2;
232  int y = a.y - pixelWidth / 2;
233 
234  for (auto line : lines) {
235  drawTextPx(state, {x, y}, line);
236  y += kLineHeight;
237  }
238 }
239 
240 inline void
241 drawTextCenteredPx(State* state, Position const& a, const std::string& text) {
242  drawTextCenteredLinesPx(state, a, {text});
243 }
244 
245 inline void drawTextScreen(
246  State* state,
247  int xCharacter,
248  int yLine,
249  const std::string& text) {
250  state->board()->postCommand(
251  {tc::BW::Command::DrawTextScreen,
252  text,
253  kCharacterWidthMax * (xCharacter + 1),
254  kCharacterWidthMax + yLine * kLineHeight},
255  kRootUpcId);
256 }
257 
258 inline void drawUnitCommand(
259  State* state,
260  Unit* unit,
261  Command commandCpi,
262  int commandBw, // tc::BW::UnitCommandType
263  UpcId upcId) {
264  std::string taskName = upcTaskString(state, upcId);
265  std::string commandCpiName = commandString(commandCpi);
266  std::string commandBwName = commandBwString(commandBw);
268  state,
269  {unit->x * tc::BW::XYPixelsPerWalktile,
270  unit->y * tc::BW::XYPixelsPerWalktile},
271  {commandCpiName, commandBwName, taskName});
272 }
273 
274 /// Retrieves current gflags values, optionally restricted to a source file
275 std::map<std::string, std::string> gflagsValues(
276  std::string const& sourcePath = std::string());
277 
278 std::string visualizeHeatmap(torch::Tensor);
279 
280 } // namespace utils
281 } // namespace cherrypi
std::string upcTaskString(State *state, UpcId upcId)
Definition: debugging.h:124
Game state.
Definition: state.h:42
T bottom() const
Definition: basetypes.h:221
Command
Abstract "meta" commands for UPCTuples.
Definition: basetypes.h:314
std::string unitsString(Units &&units)
Definition: debugging.h:76
void drawBox(State *state, Position const &a, Position const &b, int color=255)
Definition: debugging.h:166
T right() const
Definition: basetypes.h:215
T y
Definition: basetypes.h:44
std::map< std::string, std::string > gflagsValues(std::string const &sourcePath)
Retrieves current gflags values, optionally restricted to a source file.
Definition: debugging.cpp:95
void drawUnitCommand(State *state, Unit *unit, Command commandCpi, int commandBw, UpcId upcId)
Definition: debugging.h:258
UpcId constexpr kRootUpcId
Definition: basetypes.h:24
void drawTextScreen(State *state, int xCharacter, int yLine, const std::string &text)
Definition: debugging.h:245
std::string curTimeString(char const *format)
Definition: debugging.cpp:107
std::string name
Definition: buildtype.h:44
T left() const
Definition: basetypes.h:212
UnitId id
Definition: unitsinfo.h:36
std::shared_ptr< Task > taskForId(UpcId id) const
Definition: blackboard.cpp:192
Represents a unit in the game.
Definition: unitsinfo.h:35
T top() const
Definition: basetypes.h:218
std::string visualizeHeatmap(torch::Tensor inp)
Definition: debugging.cpp:115
bool isEnemy
Definition: unitsinfo.h:54
constexpr int kLineHeight
Definition: debugging.h:202
Blackboard * board() const
Definition: state.h:99
std::string buildTypeString(BuildType const *buildType)
Definition: algorithms.h:176
void drawLine(State *state, Position const &a, Position const &b, int color=255)
Definition: debugging.h:137
void drawText(State *state, Position const &a, const std::string &text)
Definition: debugging.h:213
std::string upcString(UpcId id)
Definition: debugging.h:94
constexpr int kCharacterWidthMax
Definition: debugging.h:203
void drawTextCenteredLinesPx(State *state, Position const &a, const std::vector< std::string > &lines)
Definition: debugging.h:220
std::string unitString(Unit const *unit)
Definition: debugging.h:65
void killUnit(State *state, Unit *u)
Definition: debugging.cpp:86
void drawTextCenteredPx(State *state, Position const &a, const std::string &text)
Definition: debugging.h:241
constexpr double kCharacterWidthAvg
Definition: debugging.h:205
bool isMine
Definition: unitsinfo.h:53
int PlayerId
Definition: basetypes.h:21
std::string resourcesString(T &&resources)
Definition: debugging.h:87
T x
Definition: basetypes.h:43
Main namespace for bot-related code.
Definition: areainfo.cpp:17
std::string commandBwString(int commandType)
Definition: debugging.h:131
const BuildType * type
Definition: unitsinfo.h:56
void postCommand(tc::Client::Command const &command, UpcId sourceId)
Definition: blackboard.cpp:266
Definition: basetypes.h:41
int x
Definition: unitsinfo.h:37
int UpcId
Definition: basetypes.h:23
void drawTextPx(State *state, Position const &a, const std::string &text)
Definition: debugging.h:208
void spawnUnit(State *state, PlayerId team, BuildType const *typ, Position loc)
Definition: debugging.cpp:66
void drawCircle(State *state, Position const &a, int radius, int color=255)
Definition: debugging.h:182
int y
Definition: unitsinfo.h:38
std::string positionString(Vec2T< T > position)
Definition: debugging.h:59
Vec2T< int > Position
Definition: basetypes.h:178
std::string commandString(State *state, tc::Client::Command const &cmd)
Definition: debugging.cpp:23