yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
gui_action_generator.cc
Go to the documentation of this file.
2
3#include "absl/strings/str_cat.h"
4#include "absl/strings/str_format.h"
5
6namespace yaze {
7namespace cli {
8namespace gui {
9
10absl::StatusOr<std::string> GuiActionGenerator::GenerateTestScript(
11 const std::vector<ai::AIAction>& actions) {
12#ifdef YAZE_WITH_JSON
13 auto json_result = GenerateTestJSON(actions);
14 if (!json_result.ok()) {
15 return json_result.status();
16 }
17 return json_result->dump(2); // Pretty-print with 2-space indent
18#else
19 return absl::UnimplementedError(
20 "JSON support required for test script generation");
21#endif
22}
23
24#ifdef YAZE_WITH_JSON
25absl::StatusOr<nlohmann::json> GuiActionGenerator::GenerateTestJSON(
26 const std::vector<ai::AIAction>& actions) {
27 nlohmann::json test_script;
28 test_script["test_name"] = "ai_generated_test";
29 test_script["description"] = "Automatically generated from AI actions";
30 test_script["steps"] = nlohmann::json::array();
31
32 for (size_t i = 0; i < actions.size(); ++i) {
33 nlohmann::json step = ActionToJSON(actions[i]);
34 step["step_number"] = i + 1;
35 test_script["steps"].push_back(step);
36 }
37
38 return test_script;
39}
40
41nlohmann::json GuiActionGenerator::ActionToJSON(const ai::AIAction& action) {
42 nlohmann::json step;
43
44 switch (action.type) {
46 step["action"] = "click";
47 auto it = action.parameters.find("editor");
48 if (it != action.parameters.end()) {
49 step["target"] = absl::StrCat("button:", it->second, " Editor");
50 step["wait_after"] = 500; // Wait 500ms for editor to open
51 }
52 break;
53 }
54
56 step["action"] = "click";
57 auto it = action.parameters.find("tile_id");
58 if (it != action.parameters.end()) {
59 int tile_id = std::stoi(it->second);
60 // Calculate position in tile selector (8 tiles per row, 16x16 pixels
61 // each)
62 int tile_x = (tile_id % 8) * 16 + 8; // Center of tile
63 int tile_y = (tile_id / 8) * 16 + 8;
64
65 step["target"] = "canvas:tile16_selector";
66 step["position"] = {{"x", tile_x}, {"y", tile_y}};
67 step["wait_after"] = 200;
68 }
69 break;
70 }
71
73 step["action"] = "click";
74 auto x_it = action.parameters.find("x");
75 auto y_it = action.parameters.find("y");
76
77 if (x_it != action.parameters.end() && y_it != action.parameters.end()) {
78 // Convert map coordinates to screen coordinates
79 // Assuming 16x16 tile size and some offset for the canvas
80 int screen_x = std::stoi(x_it->second) * 16 + 8;
81 int screen_y = std::stoi(y_it->second) * 16 + 8;
82
83 step["target"] = "canvas:overworld_map";
84 step["position"] = {{"x", screen_x}, {"y", screen_y}};
85 step["wait_after"] = 200;
86 }
87 break;
88 }
89
91 step["action"] = "click";
92 step["target"] = "button:Save to ROM";
93 step["wait_after"] = 300;
94 break;
95 }
96
98 step["action"] = "click";
99 auto it = action.parameters.find("button");
100 if (it != action.parameters.end()) {
101 step["target"] = absl::StrCat("button:", it->second);
102 step["wait_after"] = 200;
103 }
104 break;
105 }
106
108 step["action"] = "wait";
109 auto it = action.parameters.find("duration_ms");
110 int duration =
111 it != action.parameters.end() ? std::stoi(it->second) : 500;
112 step["duration_ms"] = duration;
113 break;
114 }
115
117 step["action"] = "screenshot";
118 auto it = action.parameters.find("filename");
119 if (it != action.parameters.end()) {
120 step["filename"] = it->second;
121 } else {
122 step["filename"] = "verification.png";
123 }
124 break;
125 }
126
128 step["action"] = "verify";
129 step["target"] = "tile_placement";
130 // Add verification parameters from action.parameters
131 for (const auto& [key, value] : action.parameters) {
132 step[key] = value;
133 }
134 break;
135 }
136
138 step["action"] = "error";
139 step["message"] = "Invalid action type";
140 break;
141 }
142
143 return step;
144}
145#endif
146
148 int step_number) {
149 switch (action.type) {
151 return GenerateOpenEditorStep(action);
153 return GenerateSelectTileStep(action);
155 return GeneratePlaceTileStep(action);
157 return GenerateSaveTileStep(action);
159 return GenerateClickButtonStep(action);
161 return GenerateWaitStep(action);
163 return GenerateScreenshotStep(action);
164 default:
165 return absl::StrFormat("# Step %d: Unknown action", step_number);
166 }
167}
168
170 const ai::AIAction& action) {
171 auto it = action.parameters.find("editor");
172 if (it != action.parameters.end()) {
173 return absl::StrFormat("Click button:'%s Editor'\nWait 500ms", it->second);
174 }
175 return "Click button:'Editor'\nWait 500ms";
176}
177
179 const ai::AIAction& action) {
180 auto it = action.parameters.find("tile_id");
181 if (it != action.parameters.end()) {
182 int tile_id = std::stoi(it->second);
183 int tile_x = (tile_id % 8) * 16 + 8;
184 int tile_y = (tile_id / 8) * 16 + 8;
185 return absl::StrFormat(
186 "Click canvas:'tile16_selector' at (%d, %d)\nWait 200ms", tile_x,
187 tile_y);
188 }
189 return "Click canvas:'tile16_selector'\nWait 200ms";
190}
191
193 const ai::AIAction& action) {
194 auto x_it = action.parameters.find("x");
195 auto y_it = action.parameters.find("y");
196
197 if (x_it != action.parameters.end() && y_it != action.parameters.end()) {
198 int screen_x = std::stoi(x_it->second) * 16 + 8;
199 int screen_y = std::stoi(y_it->second) * 16 + 8;
200 return absl::StrFormat(
201 "Click canvas:'overworld_map' at (%d, %d)\nWait 200ms", screen_x,
202 screen_y);
203 }
204 return "Click canvas:'overworld_map'\nWait 200ms";
205}
206
208 const ai::AIAction& action) {
209 return "Click button:'Save to ROM'\nWait 300ms";
210}
211
213 const ai::AIAction& action) {
214 auto it = action.parameters.find("button");
215 if (it != action.parameters.end()) {
216 return absl::StrFormat("Click button:'%s'\nWait 200ms", it->second);
217 }
218 return "Click button\nWait 200ms";
219}
220
222 auto it = action.parameters.find("duration_ms");
223 int duration = it != action.parameters.end() ? std::stoi(it->second) : 500;
224 return absl::StrFormat("Wait %dms", duration);
225}
226
228 const ai::AIAction& action) {
229 auto it = action.parameters.find("filename");
230 if (it != action.parameters.end()) {
231 return absl::StrFormat("Screenshot '%s'", it->second);
232 }
233 return "Screenshot 'verification.png'";
234}
235
236} // namespace gui
237} // namespace cli
238} // namespace yaze
std::string GenerateSelectTileStep(const ai::AIAction &action)
std::string GenerateOpenEditorStep(const ai::AIAction &action)
std::string ActionToTestStep(const ai::AIAction &action, int step_number)
std::string GeneratePlaceTileStep(const ai::AIAction &action)
std::string GenerateClickButtonStep(const ai::AIAction &action)
absl::StatusOr< std::string > GenerateTestScript(const std::vector< ai::AIAction > &actions)
std::string GenerateSaveTileStep(const ai::AIAction &action)
std::string GenerateScreenshotStep(const ai::AIAction &action)
std::string GenerateWaitStep(const ai::AIAction &action)
Represents a single action to be performed in the GUI.
std::map< std::string, std::string > parameters