diff options
| author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-06 13:53:20 -0400 |
|---|---|---|
| committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-06-06 13:53:20 -0400 |
| commit | 67a2efe7be6f4872adca8d944ebf403046472a98 (patch) | |
| tree | 63f30a28c2c32ab03f9dfccc1c50567a0f03d3cc /src/tracker_state.cpp | |
| parent | 78ac9905e222c26758e95b098d2e3a3e74a48839 (diff) | |
| download | lingo-ap-tracker-67a2efe7be6f4872adca8d944ebf403046472a98.tar.gz lingo-ap-tracker-67a2efe7be6f4872adca8d944ebf403046472a98.tar.bz2 lingo-ap-tracker-67a2efe7be6f4872adca8d944ebf403046472a98.zip | |
Proper painting reachability detection
Diffstat (limited to 'src/tracker_state.cpp')
| -rw-r--r-- | src/tracker_state.cpp | 67 |
1 files changed, 56 insertions, 11 deletions
| diff --git a/src/tracker_state.cpp b/src/tracker_state.cpp index 187a4a8..46bdbec 100644 --- a/src/tracker_state.cpp +++ b/src/tracker_state.cpp | |||
| @@ -141,6 +141,7 @@ class RequirementCalculator { | |||
| 141 | struct TrackerState { | 141 | struct TrackerState { |
| 142 | std::map<int, bool> reachability; | 142 | std::map<int, bool> reachability; |
| 143 | std::set<int> reachable_doors; | 143 | std::set<int> reachable_doors; |
| 144 | std::set<int> reachable_paintings; | ||
| 144 | std::mutex reachability_mutex; | 145 | std::mutex reachability_mutex; |
| 145 | RequirementCalculator requirements; | 146 | RequirementCalculator requirements; |
| 146 | std::map<int, std::map<std::string, bool>> door_reports; | 147 | std::map<int, std::map<std::string, bool>> door_reports; |
| @@ -170,6 +171,7 @@ class StateCalculator { | |||
| 170 | 171 | ||
| 171 | void Calculate() { | 172 | void Calculate() { |
| 172 | std::list<int> panel_boundary; | 173 | std::list<int> panel_boundary; |
| 174 | std::list<int> painting_boundary; | ||
| 173 | std::list<Exit> flood_boundary; | 175 | std::list<Exit> flood_boundary; |
| 174 | flood_boundary.push_back({.destination_room = options_.start}); | 176 | flood_boundary.push_back({.destination_room = options_.start}); |
| 175 | 177 | ||
| @@ -177,6 +179,8 @@ class StateCalculator { | |||
| 177 | while (reachable_changed) { | 179 | while (reachable_changed) { |
| 178 | reachable_changed = false; | 180 | reachable_changed = false; |
| 179 | 181 | ||
| 182 | std::list<Exit> new_boundary; | ||
| 183 | |||
| 180 | std::list<int> new_panel_boundary; | 184 | std::list<int> new_panel_boundary; |
| 181 | for (int panel_id : panel_boundary) { | 185 | for (int panel_id : panel_boundary) { |
| 182 | if (solveable_panels_.count(panel_id)) { | 186 | if (solveable_panels_.count(panel_id)) { |
| @@ -192,7 +196,33 @@ class StateCalculator { | |||
| 192 | } | 196 | } |
| 193 | } | 197 | } |
| 194 | 198 | ||
| 195 | std::list<Exit> new_boundary; | 199 | std::list<int> new_painting_boundary; |
| 200 | for (int painting_id : painting_boundary) { | ||
| 201 | if (reachable_paintings_.count(painting_id)) { | ||
| 202 | continue; | ||
| 203 | } | ||
| 204 | |||
| 205 | Decision painting_reachable = IsPaintingReachable(painting_id); | ||
| 206 | if (painting_reachable == kYes) { | ||
| 207 | reachable_paintings_.insert(painting_id); | ||
| 208 | reachable_changed = true; | ||
| 209 | |||
| 210 | PaintingExit cur_painting = GD_GetPaintingExit(painting_id); | ||
| 211 | if (AP_GetPaintingMapping().count(cur_painting.internal_id) && | ||
| 212 | AP_GetCheckedPaintings().count(cur_painting.internal_id)) { | ||
| 213 | Exit painting_exit; | ||
| 214 | PaintingExit target_painting = | ||
| 215 | GD_GetPaintingExit(GD_GetPaintingByName( | ||
| 216 | AP_GetPaintingMapping().at(cur_painting.internal_id))); | ||
| 217 | painting_exit.destination_room = target_painting.room; | ||
| 218 | |||
| 219 | new_boundary.push_back(painting_exit); | ||
| 220 | } | ||
| 221 | } else if (painting_reachable == kMaybe) { | ||
| 222 | new_painting_boundary.push_back(painting_id); | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 196 | for (const Exit& room_exit : flood_boundary) { | 226 | for (const Exit& room_exit : flood_boundary) { |
| 197 | if (reachable_rooms_.count(room_exit.destination_room)) { | 227 | if (reachable_rooms_.count(room_exit.destination_room)) { |
| 198 | continue; | 228 | continue; |
| @@ -227,16 +257,8 @@ class StateCalculator { | |||
| 227 | } | 257 | } |
| 228 | 258 | ||
| 229 | if (AP_IsPaintingShuffle()) { | 259 | if (AP_IsPaintingShuffle()) { |
| 230 | for (const PaintingExit& out_edge : room_obj.paintings) { | 260 | for (int out_edge : room_obj.paintings) { |
| 231 | if (AP_GetPaintingMapping().count(out_edge.id) && | 261 | new_painting_boundary.push_back(out_edge); |
| 232 | AP_GetCheckedPaintings().count(out_edge.id)) { | ||
| 233 | Exit painting_exit; | ||
| 234 | painting_exit.destination_room = GD_GetRoomForPainting( | ||
| 235 | AP_GetPaintingMapping().at(out_edge.id)); | ||
| 236 | painting_exit.door = out_edge.door; | ||
| 237 | |||
| 238 | new_boundary.push_back(painting_exit); | ||
| 239 | } | ||
| 240 | } | 262 | } |
| 241 | } | 263 | } |
| 242 | 264 | ||
| @@ -285,6 +307,7 @@ class StateCalculator { | |||
| 285 | 307 | ||
| 286 | flood_boundary = new_boundary; | 308 | flood_boundary = new_boundary; |
| 287 | panel_boundary = new_panel_boundary; | 309 | panel_boundary = new_panel_boundary; |
| 310 | painting_boundary = new_painting_boundary; | ||
| 288 | } | 311 | } |
| 289 | 312 | ||
| 290 | // Now that we know the full reachable area, let's make sure all doors are | 313 | // Now that we know the full reachable area, let's make sure all doors are |
| @@ -302,6 +325,10 @@ class StateCalculator { | |||
| 302 | 325 | ||
| 303 | const std::set<int>& GetSolveablePanels() const { return solveable_panels_; } | 326 | const std::set<int>& GetSolveablePanels() const { return solveable_panels_; } |
| 304 | 327 | ||
| 328 | const std::set<int>& GetReachablePaintings() const { | ||
| 329 | return reachable_paintings_; | ||
| 330 | } | ||
| 331 | |||
| 305 | const std::map<int, std::map<std::string, bool>>& GetDoorReports() const { | 332 | const std::map<int, std::map<std::string, bool>>& GetDoorReports() const { |
| 306 | return door_report_; | 333 | return door_report_; |
| 307 | } | 334 | } |
| @@ -450,6 +477,15 @@ class StateCalculator { | |||
| 450 | return AreRequirementsSatisfied(GetState().requirements.GetPanel(panel_id)); | 477 | return AreRequirementsSatisfied(GetState().requirements.GetPanel(panel_id)); |
| 451 | } | 478 | } |
| 452 | 479 | ||
| 480 | Decision IsPaintingReachable(int painting_id) { | ||
| 481 | const PaintingExit& painting = GD_GetPaintingExit(painting_id); | ||
| 482 | if (painting.door) { | ||
| 483 | return IsDoorReachable(*painting.door); | ||
| 484 | } | ||
| 485 | |||
| 486 | return kYes; | ||
| 487 | } | ||
| 488 | |||
| 453 | Decision IsExitUsable(const Exit& room_exit) { | 489 | Decision IsExitUsable(const Exit& room_exit) { |
| 454 | if (room_exit.type == EntranceType::kPilgrimage) { | 490 | if (room_exit.type == EntranceType::kPilgrimage) { |
| 455 | if (options_.pilgrimage || !AP_IsPilgrimageEnabled()) { | 491 | if (options_.pilgrimage || !AP_IsPilgrimageEnabled()) { |
| @@ -533,6 +569,7 @@ class StateCalculator { | |||
| 533 | std::set<int> reachable_rooms_; | 569 | std::set<int> reachable_rooms_; |
| 534 | std::map<int, Decision> door_decisions_; | 570 | std::map<int, Decision> door_decisions_; |
| 535 | std::set<int> solveable_panels_; | 571 | std::set<int> solveable_panels_; |
| 572 | std::set<int> reachable_paintings_; | ||
| 536 | std::map<int, std::map<std::string, bool>> door_report_; | 573 | std::map<int, std::map<std::string, bool>> door_report_; |
| 537 | }; | 574 | }; |
| 538 | 575 | ||
| @@ -573,6 +610,7 @@ void RecalculateReachability() { | |||
| 573 | } | 610 | } |
| 574 | } | 611 | } |
| 575 | 612 | ||
| 613 | std::set<int> reachable_paintings = state_calculator.GetReachablePaintings(); | ||
| 576 | std::map<int, std::map<std::string, bool>> door_reports = | 614 | std::map<int, std::map<std::string, bool>> door_reports = |
| 577 | state_calculator.GetDoorReports(); | 615 | state_calculator.GetDoorReports(); |
| 578 | 616 | ||
| @@ -580,6 +618,7 @@ void RecalculateReachability() { | |||
| 580 | std::lock_guard reachability_guard(GetState().reachability_mutex); | 618 | std::lock_guard reachability_guard(GetState().reachability_mutex); |
| 581 | std::swap(GetState().reachability, new_reachability); | 619 | std::swap(GetState().reachability, new_reachability); |
| 582 | std::swap(GetState().reachable_doors, new_reachable_doors); | 620 | std::swap(GetState().reachable_doors, new_reachable_doors); |
| 621 | std::swap(GetState().reachable_paintings, reachable_paintings); | ||
| 583 | std::swap(GetState().door_reports, door_reports); | 622 | std::swap(GetState().door_reports, door_reports); |
| 584 | } | 623 | } |
| 585 | } | 624 | } |
| @@ -600,6 +639,12 @@ bool IsDoorOpen(int door_id) { | |||
| 600 | return GetState().reachable_doors.count(door_id); | 639 | return GetState().reachable_doors.count(door_id); |
| 601 | } | 640 | } |
| 602 | 641 | ||
| 642 | bool IsPaintingReachable(int painting_id) { | ||
| 643 | std::lock_guard reachability_guard(GetState().reachability_mutex); | ||
| 644 | |||
| 645 | return GetState().reachable_paintings.count(painting_id); | ||
| 646 | } | ||
| 647 | |||
| 603 | const std::map<std::string, bool>& GetDoorRequirements(int door_id) { | 648 | const std::map<std::string, bool>& GetDoorRequirements(int door_id) { |
| 604 | std::lock_guard reachability_guard(GetState().reachability_mutex); | 649 | std::lock_guard reachability_guard(GetState().reachability_mutex); |
| 605 | 650 | ||
