summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--App/Main.cpp6
-rw-r--r--Installer/Installer.vdproj6
-rw-r--r--Source/Panel.cpp178
-rw-r--r--Source/Panel.h30
-rw-r--r--Test/PanelExtractionTests.cpp119
5 files changed, 239 insertions, 100 deletions
diff --git a/App/Main.cpp b/App/Main.cpp index ab3e88a..6ebef7e 100644 --- a/App/Main.cpp +++ b/App/Main.cpp
@@ -19,8 +19,8 @@
19#define IDT_RANDOMIZED 0x409 19#define IDT_RANDOMIZED 0x409
20 20
21HWND hwndSeed, hwndRandomize; 21HWND hwndSeed, hwndRandomize;
22int panel = 0x18AF; 22// int panel = 0x18AF;
23// int panel = 0x33D4; 23int panel = 0x33D4;
24std::shared_ptr<Panel> _panel; 24std::shared_ptr<Panel> _panel;
25std::shared_ptr<Randomizer> randomizer = std::make_shared<Randomizer>(); 25std::shared_ptr<Randomizer> randomizer = std::make_shared<Randomizer>();
26 26
@@ -94,7 +94,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
94 _panel->Write(panel); 94 _panel->Write(panel);
95 break; 95 break;
96 case IDC_DUMP: 96 case IDC_DUMP:
97 // _panel->Serialize(); 97 _panel->Serialize();
98 break; 98 break;
99 } 99 }
100 } 100 }
diff --git a/Installer/Installer.vdproj b/Installer/Installer.vdproj index 9b05e20..19d6036 100644 --- a/Installer/Installer.vdproj +++ b/Installer/Installer.vdproj
@@ -125,7 +125,7 @@
125 } 125 }
126 "{3C67513D-01DD-4637-8A68-80971EB9504F}:_8E9D847124D34D9D9008762077D816DE" 126 "{3C67513D-01DD-4637-8A68-80971EB9504F}:_8E9D847124D34D9D9008762077D816DE"
127 { 127 {
128 "DefaultLocation" = "8:[ProgramFilesFolder][Manufacturer]\\[ProductName]" 128 "DefaultLocation" = "8:[ProgramFiles64Folder][Manufacturer]\\[ProductName]"
129 "Name" = "8:#1925" 129 "Name" = "8:#1925"
130 "AlwaysCreate" = "11:FALSE" 130 "AlwaysCreate" = "11:FALSE"
131 "Condition" = "8:" 131 "Condition" = "8:"
@@ -163,7 +163,7 @@
163 "Name" = "8:Microsoft Visual Studio" 163 "Name" = "8:Microsoft Visual Studio"
164 "ProductName" = "8:Witness Randomizer" 164 "ProductName" = "8:Witness Randomizer"
165 "ProductCode" = "8:{7DD620CA-9593-4E32-9D60-9D12069DA33C}" 165 "ProductCode" = "8:{7DD620CA-9593-4E32-9D60-9D12069DA33C}"
166 "PackageCode" = "8:{90B5567A-BE63-4F98-A6C8-5FAC1942075A}" 166 "PackageCode" = "8:{BBA8F7F1-52D8-44B0-BC53-9AC3F0181E3D}"
167 "UpgradeCode" = "8:{4CB5496B-A47E-41D3-B4A7-677E29AB7513}" 167 "UpgradeCode" = "8:{4CB5496B-A47E-41D3-B4A7-677E29AB7513}"
168 "AspNetVersion" = "8:2.0.50727.0" 168 "AspNetVersion" = "8:2.0.50727.0"
169 "RestartWWWService" = "11:FALSE" 169 "RestartWWWService" = "11:FALSE"
@@ -184,7 +184,7 @@
184 "ARPIconIndex" = "3:0" 184 "ARPIconIndex" = "3:0"
185 "SearchPath" = "8:" 185 "SearchPath" = "8:"
186 "UseSystemSearchPath" = "11:TRUE" 186 "UseSystemSearchPath" = "11:TRUE"
187 "TargetPlatform" = "3:0" 187 "TargetPlatform" = "3:1"
188 "PreBuildEvent" = "8:" 188 "PreBuildEvent" = "8:"
189 "PostBuildEvent" = "8:" 189 "PostBuildEvent" = "8:"
190 "RunPostBuildEvent" = "3:0" 190 "RunPostBuildEvent" = "3:0"
diff --git a/Source/Panel.cpp b/Source/Panel.cpp index b6aa504..c0fb7ec 100644 --- a/Source/Panel.cpp +++ b/Source/Panel.cpp
@@ -13,8 +13,9 @@ int find(const std::vector<T> &data, T search, size_t startIndex = 0) {
13} 13}
14 14
15Panel::Panel(int id) { 15Panel::Panel(int id) {
16 _width = 2 * _memory.ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1; 16 _memory = std::make_shared<Memory>("witness64_d3d11.exe");
17 _height = 2 * _memory.ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1; 17 _width = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_X, 1)[0] - 1;
18 _height = 2 * _memory->ReadPanelData<int>(id, GRID_SIZE_Y, 1)[0] - 1;
18 _grid.resize(_width); 19 _grid.resize(_width);
19 for (auto& row : _grid) row.resize(_height); 20 for (auto& row : _grid) row.resize(_height);
20 21
@@ -22,15 +23,12 @@ Panel::Panel(int id) {
22 ReadDecorations(id); 23 ReadDecorations(id);
23} 24}
24 25
25// For testing
26Panel::Panel() {}
27
28void Panel::Write(int id) { 26void Panel::Write(int id) {
29 WriteIntersections(id); 27 WriteIntersections(id);
30 WriteDecorations(id); 28 WriteDecorations(id);
31 29
32 _memory.WritePanelData<int>(id, GRID_SIZE_X, {(_width + 1)/2}); 30 _memory->WritePanelData<int>(id, GRID_SIZE_X, {(_width + 1)/2});
33 _memory.WritePanelData<int>(id, GRID_SIZE_Y, {(_height + 1)/2}); 31 _memory->WritePanelData<int>(id, GRID_SIZE_Y, {(_height + 1)/2});
34} 32}
35 33
36nlohmann::json Panel::Serialize() { 34nlohmann::json Panel::Serialize() {
@@ -49,6 +47,9 @@ nlohmann::json Panel::Serialize() {
49 if (x%2 == 1 && y%2 == 1) { 47 if (x%2 == 1 && y%2 == 1) {
50 puzzle["grid"][x][y] = Decoration::to_json(_grid[x][y]); 48 puzzle["grid"][x][y] = Decoration::to_json(_grid[x][y]);
51 } else { 49 } else {
50 if (_grid[x][y] & IntersectionFlags::HAS_DOT) {
51 puzzle["dots"].emplace_back(nlohmann::json({{"x", x}, {"y", y}}));
52 }
52 puzzle["grid"][x][y] = false; 53 puzzle["grid"][x][y] = false;
53 } 54 }
54 } 55 }
@@ -80,65 +81,52 @@ void Panel::Random() {
80} 81}
81 82
82void Panel::ReadDecorations(int id) { 83void Panel::ReadDecorations(int id) {
83 int numDecorations = _memory.ReadPanelData<int>(id, NUM_DECORATIONS, 1)[0]; 84 int numDecorations = _memory->ReadPanelData<int>(id, NUM_DECORATIONS, 1)[0];
84 std::vector<int> decorations = _memory.ReadArray<int>(id, DECORATIONS, numDecorations); 85 std::vector<int> decorations = _memory->ReadArray<int>(id, DECORATIONS, numDecorations);
85 86
86 int x = 1; 87 for (int i=0; i<numDecorations; i++) {
87 int y = _height - 2; 88 auto [x, y] = dloc_to_xy(i);
88 for (int decoration : decorations) { 89 _grid[x][y] = decorations[i];
89 _grid[x][y] = decoration;
90 x += 2;
91 if (x > _width - 1) {
92 x = 1;
93 y -= 2;
94 }
95 } 90 }
96} 91}
97 92
98void Panel::WriteDecorations(int id) { 93void Panel::WriteDecorations(int id) {
99 std::vector<int> decorations; 94 std::vector<int> decorations;
100 for (int y=_height - 2; y>0; y-=2) { 95 for (int y=_height-2; y>0; y-=2) {
101 for (int x=1; x<_width - 1; x+=2) { 96 for (int x=1; x<_width - 1; x+=2) {
102 decorations.push_back(_grid[x][y]); 97 decorations.push_back(_grid[x][y]);
103 } 98 }
104 } 99 }
105 100
106 _memory.WritePanelData<int>(id, NUM_DECORATIONS, {static_cast<int>(decorations.size())}); 101 _memory->WritePanelData<int>(id, NUM_DECORATIONS, {static_cast<int>(decorations.size())});
107 _memory.WriteArray<int>(id, DECORATIONS, decorations); 102 _memory->WriteArray<int>(id, DECORATIONS, decorations);
108} 103}
109 104
110void Panel::ReadIntersections(int id) { 105void Panel::ReadIntersections(int id) {
111 int numIntersections = _memory.ReadPanelData<int>(id, NUM_DOTS, 1)[0]; 106 int numIntersections = _memory->ReadPanelData<int>(id, NUM_DOTS, 1)[0];
112 std::vector<int> intersectionFlags = _memory.ReadArray<int>(id, DOT_FLAGS, numIntersections); 107 std::vector<int> intersectionFlags = _memory->ReadArray<int>(id, DOT_FLAGS, numIntersections);
113 108
114 int x = 0;
115 int y = _height - 1;
116 int i = 0; 109 int i = 0;
117 for (;; i++) { 110 for (;; i++) {
111 auto [x, y] = loc_to_xy(i);
112 if (y < 0) break;
118 if (intersectionFlags[i] & IntersectionFlags::IS_STARTPOINT) { 113 if (intersectionFlags[i] & IntersectionFlags::IS_STARTPOINT) {
119 _startpoints.push_back({x, y}); 114 _startpoints.push_back({x, y});
120 } 115 }
121 x += 2;
122 if (x > _width) {
123 x = 0;
124 y -= 2;
125 }
126 if (y < 0) break;
127 } 116 }
128 117
129 std::pair<std::vector<int>, std::vector<int>> connections; 118 int numConnections = _memory->ReadPanelData<int>(id, NUM_CONNECTIONS, 1)[0];
130 int numConnections = _memory.ReadPanelData<int>(id, NUM_CONNECTIONS, 1)[0]; 119 std::vector<int> connections_a = _memory->ReadArray<int>(id, DOT_CONNECTION_A, numConnections);
131 connections.first = _memory.ReadArray<int>(id, DOT_CONNECTION_A, numConnections); 120 std::vector<int> connections_b = _memory->ReadArray<int>(id, DOT_CONNECTION_B, numConnections);
132 connections.second = _memory.ReadArray<int>(id, DOT_CONNECTION_B, numConnections); 121 std::vector<float> intersections = _memory->ReadArray<float>(id, DOT_POSITIONS, numIntersections*2);
133 std::vector<float> intersections = _memory.ReadArray<float>(id, DOT_POSITIONS, numIntersections*2);
134 122
135 // Iterate the remaining intersections (either endpoints or gaps) 123 // Iterate the remaining intersections (endpoints, dots, gaps)
136 for (; i < numIntersections; i++) { 124 for (; i < numIntersections; i++) {
137 if (intersectionFlags[i] & IntersectionFlags::IS_ENDPOINT) { 125 if (intersectionFlags[i] & IntersectionFlags::IS_ENDPOINT) {
138 for (int j=0; j<numConnections; j++) { 126 for (int j=0; j<numConnections; j++) {
139 int location = 0; 127 int location = 0;
140 if (connections.first[j] == i) location = connections.second[j]; 128 if (connections_a[j] == i) location = connections_b[j];
141 if (connections.second[j] == i) location = connections.first[j]; 129 if (connections_b[j] == i) location = connections_a[j];
142 if (location != 0) { 130 if (location != 0) {
143 Endpoint::Direction dir; 131 Endpoint::Direction dir;
144 if (intersections[2*i] < intersections[2*location]) { // Our (i) x coordinate is less than the target's (location) 132 if (intersections[2*i] < intersections[2*location]) { // Our (i) x coordinate is less than the target's (location)
@@ -152,6 +140,34 @@ void Panel::ReadIntersections(int id) {
152 } 140 }
153 auto [x, y] = loc_to_xy(location); 141 auto [x, y] = loc_to_xy(location);
154 _endpoints.push_back(Endpoint(x, y, dir)); 142 _endpoints.push_back(Endpoint(x, y, dir));
143 break;
144 }
145 }
146 } else if (intersectionFlags[i] & IntersectionFlags::HAS_DOT) {
147 for (int j=0; j<numConnections; j++) {
148 int location = 0;
149 if (connections_a[j] == i) location = connections_b[j];
150 if (connections_b[j] == i) location = connections_a[j];
151 if (location != 0) {
152 auto [x, y] = loc_to_xy(location);
153 float x1 = intersections[2*i];
154 float y1 = intersections[2*i+1];
155 float x2 = intersections[2*location];
156 float y2 = intersections[2*location+1];
157 if (intersections[2*i] < intersections[2*location]) {
158 // Our (i) x coordinate is less than the target's (location), so we are to the left
159 x--;
160 } else if (intersections[2*i] > intersections[2*location]) { // To the right
161 x++;
162 } else if (intersections[2*i + 1] > intersections[2*location + 1]) {
163 // y coordinate is 0 (bottom) 1 (top), so this check is reversed. We are above the target (location)
164 y--;
165 } else { // Beleow the target
166 y++;
167 }
168
169 _grid[x][y] |= IntersectionFlags::HAS_DOT;
170 break;
155 } 171 }
156 } 172 }
157 } 173 }
@@ -161,34 +177,41 @@ void Panel::ReadIntersections(int id) {
161void Panel::WriteIntersections(int id) { 177void Panel::WriteIntersections(int id) {
162 std::vector<float> intersections; 178 std::vector<float> intersections;
163 std::vector<int> intersectionFlags; 179 std::vector<int> intersectionFlags;
164 std::pair<std::vector<int>, std::vector<int>> connections; 180 std::vector<int> connections_a;
181 std::vector<int> connections_b;
165 182
166 double min = 0.1; 183 double min = 0.1;
167 double max = 0.9; 184 double max = 0.9;
168 double width_interval = (max - min) / (_width/2); 185 double width_interval = (max - min) / (_width/2);
169 double height_interval = (max - min) / (_height/2); 186 double height_interval = (max - min) / (_height/2);
170 187
171 for (int y=0; y<_height/2; y++) { 188 // TODO(future): Stop using push_back and set these into explicit locations, unrequires loop iteration order
172 for (int x=0; x<_width/2; x++) { 189 for (int y=_height-1; y>=0; y-=2) {
173 intersections.push_back(static_cast<float>(min + x * width_interval)); 190 for (int x=0; x<_width; x+=2) {
174 intersections.push_back(static_cast<float>(min + y * height_interval)); 191 intersections.push_back(static_cast<float>(min + (x/2) * width_interval));
192 intersections.push_back(static_cast<float>(max - (y/2) * height_interval));
175 int flags = 0; 193 int flags = 0;
176 if (find(_startpoints, {2*x, 2*y}) != -1) flags |= IntersectionFlags::IS_STARTPOINT; 194 if (find(_startpoints, {x, y}) != -1) flags |= IntersectionFlags::IS_STARTPOINT;
177 intersectionFlags.push_back(flags); 195 intersectionFlags.push_back(flags);
196
197 // Create connections for this intersection -- always write low -> high
178 if (y > 0) { 198 if (y > 0) {
179 connections.first.push_back(y * _width + x); 199 connections_a.push_back(xy_to_loc(x, y-2));
180 connections.second.push_back((y - 1) * _width + x); 200 connections_b.push_back(xy_to_loc(x, y));
181 } 201 }
182 if (x > 0) { 202 if (x > 0) {
183 connections.first.push_back(y * _width + x); 203 connections_a.push_back(xy_to_loc(x-2, y));
184 connections.second.push_back(y * _width + (x - 1)); 204 connections_b.push_back(xy_to_loc(x, y));
185 } 205 }
186 } 206 }
187 } 207 }
188 208
189 for (Endpoint endpoint : _endpoints) { 209 for (Endpoint endpoint : _endpoints) {
190 double xPos = min + endpoint.GetX() * width_interval; 210 connections_a.push_back(xy_to_loc(endpoint.GetX(), endpoint.GetY())); // Target to connect to
191 double yPos = min + endpoint.GetY() * height_interval; 211 connections_b.push_back(static_cast<int>(intersectionFlags.size())); // This endpoint
212
213 double xPos = min + (endpoint.GetX()/2) * width_interval;
214 double yPos = max - (endpoint.GetY()/2) * height_interval;
192 if (endpoint.GetDir()== Endpoint::Direction::LEFT) { 215 if (endpoint.GetDir()== Endpoint::Direction::LEFT) {
193 xPos -= .05; 216 xPos -= .05;
194 } else if (endpoint.GetDir() == Endpoint::Direction::RIGHT) { 217 } else if (endpoint.GetDir() == Endpoint::Direction::RIGHT) {
@@ -200,18 +223,49 @@ void Panel::WriteIntersections(int id) {
200 } 223 }
201 intersections.push_back(static_cast<float>(xPos)); 224 intersections.push_back(static_cast<float>(xPos));
202 intersections.push_back(static_cast<float>(yPos)); 225 intersections.push_back(static_cast<float>(yPos));
203
204 connections.first.push_back(endpoint.GetY() * _width + endpoint.GetX()); // Target to connect to
205 connections.second.push_back(static_cast<int>(intersectionFlags.size())); // This endpoint
206 intersectionFlags.push_back(IntersectionFlags::IS_ENDPOINT); 226 intersectionFlags.push_back(IntersectionFlags::IS_ENDPOINT);
207 } 227 }
208 228
209 _memory.WritePanelData<int>(id, NUM_DOTS, {static_cast<int>(intersectionFlags.size())}); 229 // Dots
210 _memory.WriteArray<float>(id, DOT_POSITIONS, intersections); 230 for (int y=0; y<_height; y++) {
211 _memory.WriteArray<int>(id, DOT_FLAGS, intersectionFlags); 231 for (int x=0; x<_width; x++) {
212 _memory.WritePanelData<int>(id, NUM_CONNECTIONS, {static_cast<int>(connections.first.size())}); 232 if (!(_grid[x][y] & IntersectionFlags::HAS_DOT)) continue;
213 _memory.WriteArray<int>(id, DOT_CONNECTION_A, connections.first); 233 if (x%2 == 1 && y%2 == 1) continue;
214 _memory.WriteArray<int>(id, DOT_CONNECTION_B, connections.second); 234 if (x%2 == 0 && y%2 == 0) {
215 _memory.WritePanelData<int>(id, NEEDS_REDRAW, {1}); 235 intersectionFlags[xy_to_loc(x, y)] |= _grid[x][y];
236 continue;
237 }
238
239 // Locate the segment we're breaking
240 for (int i=0; i<connections_a.size(); i++) {
241 auto [x1, y1] = loc_to_xy(connections_a[i]);
242 auto [x2, y2] = loc_to_xy(connections_b[i]);
243 if ((x1+1 == x && x2-1 == x && y1 == y && y2 == y) ||
244 (y1+1 == y && y2-1 == y && x1 == x && x2 == x)) {
245 int other_connection = connections_b[i];
246 connections_b[i] = static_cast<int>(intersectionFlags.size()); // This endpoint
247
248 connections_a.push_back(static_cast<int>(intersectionFlags.size())); // This endpoint
249 connections_b.push_back(other_connection);
250 break;
251 }
252 }
253 // Add this dot to the end
254 double xPos = min + (x/2.0) * width_interval;
255 double yPos = max - (y/2.0) * height_interval;
256 intersections.push_back(static_cast<float>(xPos));
257 intersections.push_back(static_cast<float>(yPos));
258 intersectionFlags.push_back(_grid[x][y]);
259 }
260 }
261
262
263 _memory->WritePanelData<int>(id, NUM_DOTS, {static_cast<int>(intersectionFlags.size())});
264 _memory->WriteArray<float>(id, DOT_POSITIONS, intersections);
265 _memory->WriteArray<int>(id, DOT_FLAGS, intersectionFlags);
266 _memory->WritePanelData<int>(id, NUM_CONNECTIONS, {static_cast<int>(connections_a.size())});
267 _memory->WriteArray<int>(id, DOT_CONNECTION_A, connections_a);
268 _memory->WriteArray<int>(id, DOT_CONNECTION_B, connections_b);
269 _memory->WritePanelData<int>(id, NEEDS_REDRAW, {1});
216} 270}
217 271
diff --git a/Source/Panel.h b/Source/Panel.h index 565b4c3..b8e67df 100644 --- a/Source/Panel.h +++ b/Source/Panel.h
@@ -45,7 +45,7 @@ enum IntersectionFlags {
45 IS_ENDPOINT = 0x1, 45 IS_ENDPOINT = 0x1,
46 IS_STARTPOINT = 0x2, 46 IS_STARTPOINT = 0x2,
47 IS_GAP = 0x10000, 47 IS_GAP = 0x10000,
48 HAS_DOT = 0x20, 48 HAS_DOT = 0x40020,
49 DOT_IS_BLUE = 0x100, 49 DOT_IS_BLUE = 0x100,
50 DOT_IS_ORANGE = 0x200, 50 DOT_IS_ORANGE = 0x200,
51 DOT_IS_INVISIBLE = 0x1000, 51 DOT_IS_INVISIBLE = 0x1000,
@@ -110,7 +110,7 @@ public:
110 110
111private: 111private:
112 // For testing 112 // For testing
113 Panel(); 113 Panel() = default;
114 114
115 void ReadIntersections(int id); 115 void ReadIntersections(int id);
116 void WriteIntersections(int id); 116 void WriteIntersections(int id);
@@ -121,8 +121,11 @@ private:
121 // TODO: Decoration colors 121 // TODO: Decoration colors
122 122
123 std::tuple<int, int> loc_to_xy(int location) { 123 std::tuple<int, int> loc_to_xy(int location) {
124 int x = 2 * (location % ((_width + 1) / 2)); 124 int height2 = (_height - 1) / 2;
125 int y = (_height - 1) - 2 * (location / ((_width + 1) / 2)); 125 int width2 = (_width + 1) / 2;
126
127 int x = 2 * (location % width2);
128 int y = 2 * (height2 - location / width2);
126 return {x, y}; 129 return {x, y};
127 } 130 }
128 131
@@ -134,7 +137,24 @@ private:
134 return rowsFromBottom * width2 + x/2; 137 return rowsFromBottom * width2 + x/2;
135 } 138 }
136 139
137 Memory _memory = Memory("witness64_d3d11.exe"); 140 std::tuple<int, int> dloc_to_xy(int location) {
141 int height2 = (_height - 3) / 2;
142 int width2 = (_width - 1) / 2;
143
144 int x = 2 * (location % width2) + 1;
145 int y = 2 * (height2 - location / width2) + 1;
146 return {x, y};
147 }
148
149 int xy_to_dloc(int x, int y) {
150 int height2 = (_height - 3) / 2;
151 int width2 = (_width - 1) / 2;
152
153 int rowsFromBottom = height2 - (y - 1)/2;
154 return rowsFromBottom * width2 + (x - 1)/2;
155 }
156
157 std::shared_ptr<Memory> _memory;
138 158
139 int _width, _height; 159 int _width, _height;
140 160
diff --git a/Test/PanelExtractionTests.cpp b/Test/PanelExtractionTests.cpp index dfb9b9e..099fab2 100644 --- a/Test/PanelExtractionTests.cpp +++ b/Test/PanelExtractionTests.cpp
@@ -4,7 +4,8 @@
4class PanelExtractionTests : public testing::Test 4class PanelExtractionTests : public testing::Test
5{ 5{
6protected: 6protected:
7 Panel _panel; 7 // Test constructor, does not attach to process
8 Panel _panel = Panel();
8 // std::shared_ptr<Panel> _panel; 9 // std::shared_ptr<Panel> _panel;
9 10
10 void SetPanelSize(int width, int height) { 11 void SetPanelSize(int width, int height) {
@@ -13,22 +14,88 @@ protected:
13 _panel._height = height; 14 _panel._height = height;
14 } 15 }
15 16
16 std::tuple<int, int> loc_to_xy(int location) { 17 std::tuple<int, int> loc_to_xy(int location) {return _panel.loc_to_xy(location);}
17 return _panel.loc_to_xy(location); 18 int xy_to_loc(int x, int y) {return _panel.xy_to_loc(x, y);}
18 } 19 std::tuple<int, int> dloc_to_xy(int location) {return _panel.dloc_to_xy(location);}
19 20 int xy_to_dloc(int x, int y) {return _panel.xy_to_dloc(x, y);}
20 int xy_to_loc(int x, int y) {
21 return _panel.xy_to_loc(x, y);
22 }
23}; 21};
24 22
25TEST_F(PanelExtractionTests, LocToXY_7x5) { 23TEST_F(PanelExtractionTests, 1x1) {
24 SetPanelSize(1, 1);
25 /* Here's the panel, with the correct location order
26 0(_width = 1)
27 (_height = 1)
28 */
29 ASSERT_EQ(0, xy_to_loc(0, 0));
30 ASSERT_EQ((std::tuple<int, int>{0, 0}), loc_to_xy(0));
31}
32
33TEST_F(PanelExtractionTests, 7x1) {
34 SetPanelSize(7, 1);
35 /* Here's the panel, with the correct location order
36 3 . 2 . 1 . 0(_width = 7)
37 (_height = 1)
38 */
39 ASSERT_EQ(0, xy_to_loc(0, 0));
40 ASSERT_EQ(1, xy_to_loc(2, 0));
41 ASSERT_EQ(2, xy_to_loc(4, 0));
42 ASSERT_EQ(3, xy_to_loc(6, 0));
43 ASSERT_EQ((std::tuple<int, int>{0, 0}), loc_to_xy(0));
44 ASSERT_EQ((std::tuple<int, int>{2, 0}), loc_to_xy(1));
45 ASSERT_EQ((std::tuple<int, int>{4, 0}), loc_to_xy(2));
46 ASSERT_EQ((std::tuple<int, int>{6, 0}), loc_to_xy(3));
47}
48
49TEST_F(PanelExtractionTests, 1x7) {
50 SetPanelSize(1, 7);
51 /* Here's the panel, with the correct location order
52 3(_width = 1)
53 .
54 2
55 .
56 1
57 .
58 0
59 (_height = 7)
60 */
61 ASSERT_EQ(0, xy_to_loc(0, 6));
62 ASSERT_EQ(1, xy_to_loc(0, 4));
63 ASSERT_EQ(2, xy_to_loc(0, 2));
64 ASSERT_EQ(3, xy_to_loc(0, 0));
65 ASSERT_EQ((std::tuple<int, int>{0, 6}), loc_to_xy(0));
66 ASSERT_EQ((std::tuple<int, int>{0, 4}), loc_to_xy(1));
67 ASSERT_EQ((std::tuple<int, int>{0, 2}), loc_to_xy(2));
68 ASSERT_EQ((std::tuple<int, int>{0, 0}), loc_to_xy(3));
69}
70
71TEST_F(PanelExtractionTests, 3x3) {
72 SetPanelSize(3, 3);
73 /* Here's the panel, with the correct location order
74 2 . 3 (_width = 3)
75 . A .
76 0 . 1
77 (_height = 3)
78 */
79 ASSERT_EQ(0, xy_to_loc(0, 2));
80 ASSERT_EQ(1, xy_to_loc(2, 2));
81 ASSERT_EQ(2, xy_to_loc(0, 0));
82 ASSERT_EQ(3, xy_to_loc(2, 0));
83 ASSERT_EQ((std::tuple<int, int>{0, 2}), loc_to_xy(0));
84 ASSERT_EQ((std::tuple<int, int>{2, 2}), loc_to_xy(1));
85 ASSERT_EQ((std::tuple<int, int>{0, 0}), loc_to_xy(2));
86 ASSERT_EQ((std::tuple<int, int>{2, 0}), loc_to_xy(3));
87
88 ASSERT_EQ(0, xy_to_dloc(1, 1));
89 ASSERT_EQ((std::tuple<int, int>{1, 1}), dloc_to_xy(0));
90}
91
92TEST_F(PanelExtractionTests, 7x5) {
26 SetPanelSize(7, 5); 93 SetPanelSize(7, 5);
27 /* Here's the panel, with the correct location order 94 /* Here's the panel, with the correct location order
28 8 . 9 . 10. 11 (_width = 7) 95 8 . 9 . 10. 11 (_width = 7)
29 . . . . . . . 96 . D . E . F .
30 4 . 5 . 6 . 7 97 4 . 5 . 6 . 7
31 . . . . . . . 98 . A . B . C .
32 0 . 1 . 2 . 3 99 0 . 1 . 2 . 3
33 (_height = 5) 100 (_height = 5)
34 */ 101 */
@@ -36,28 +103,26 @@ TEST_F(PanelExtractionTests, LocToXY_7x5) {
36 ASSERT_EQ(1, xy_to_loc(2, 4)); 103 ASSERT_EQ(1, xy_to_loc(2, 4));
37 ASSERT_EQ(2, xy_to_loc(4, 4)); 104 ASSERT_EQ(2, xy_to_loc(4, 4));
38 ASSERT_EQ(3, xy_to_loc(6, 4)); 105 ASSERT_EQ(3, xy_to_loc(6, 4));
106 ASSERT_EQ((std::tuple<int, int>{0, 4}), loc_to_xy(0));
107 ASSERT_EQ((std::tuple<int, int>{2, 4}), loc_to_xy(1));
108 ASSERT_EQ((std::tuple<int, int>{4, 4}), loc_to_xy(2));
109 ASSERT_EQ((std::tuple<int, int>{6, 4}), loc_to_xy(3));
39 110
40 ASSERT_EQ(4, xy_to_loc(0, 2)); 111 ASSERT_EQ(4, xy_to_loc(0, 2));
41 ASSERT_EQ(5, xy_to_loc(2, 2)); 112 ASSERT_EQ(5, xy_to_loc(2, 2));
42 ASSERT_EQ(6, xy_to_loc(4, 2)); 113 ASSERT_EQ(6, xy_to_loc(4, 2));
43 ASSERT_EQ(7, xy_to_loc(6, 2)); 114 ASSERT_EQ(7, xy_to_loc(6, 2));
115 ASSERT_EQ((std::tuple<int, int>{0, 2}), loc_to_xy(4));
116 ASSERT_EQ((std::tuple<int, int>{2, 2}), loc_to_xy(5));
117 ASSERT_EQ((std::tuple<int, int>{4, 2}), loc_to_xy(6));
118 ASSERT_EQ((std::tuple<int, int>{6, 2}), loc_to_xy(7));
44 119
45 ASSERT_EQ(8, xy_to_loc(0, 0)); 120 ASSERT_EQ(8, xy_to_loc(0, 0));
46 ASSERT_EQ(9, xy_to_loc(2, 0)); 121 ASSERT_EQ(9, xy_to_loc(2, 0));
47 ASSERT_EQ(10, xy_to_loc(4, 0)); 122 ASSERT_EQ(10, xy_to_loc(4, 0));
48 ASSERT_EQ(11, xy_to_loc(6, 0)); 123 ASSERT_EQ(11, xy_to_loc(6, 0));
124 ASSERT_EQ((std::tuple<int, int>{0, 0}), loc_to_xy(8));
125 ASSERT_EQ((std::tuple<int, int>{2, 0}), loc_to_xy(9));
126 ASSERT_EQ((std::tuple<int, int>{4, 0}), loc_to_xy(10));
127 ASSERT_EQ((std::tuple<int, int>{6, 0}), loc_to_xy(11));
49} 128}
50
51TEST_F(PanelExtractionTests, LocToXY_3x3) {
52 SetPanelSize(3, 3);
53 /* Here's the panel, with the correct location order
54 2 . 3 (_width = 3)
55 . . .
56 0 . 1
57 (_height = 3)
58 */
59 ASSERT_EQ(0, xy_to_loc(0, 2));
60 ASSERT_EQ(1, xy_to_loc(2, 2));
61 ASSERT_EQ(2, xy_to_loc(0, 0));
62 ASSERT_EQ(3, xy_to_loc(2, 0));
63} \ No newline at end of file