You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
9.1 KiB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
10 months ago
  1. #include "Grid.h"
  2. #include <boost/algorithm/string/find.hpp>
  3. #include <algorithm>
  4. Grid::Grid(cells gridCells, cells background, const std::map<coordinates, float> &stateRewards, const float probIntended, const float faultyProbability, prism::ModelType mType)
  5. : allGridCells(gridCells), background(background), stateRewards(stateRewards), probIntended(probIntended), faultyProbability(faultyProbability)
  6. {
  7. cell max = allGridCells.at(allGridCells.size() - 1);
  8. maxBoundaries = std::make_pair(max.column - 1, max.row - 1);
  9. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(walls), [](cell c) { return c.type == Type::Wall; });
  10. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(lava), [](cell c) { return c.type == Type::Lava; });
  11. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(floor), [](cell c) { return c.type == Type::Floor; }); // TODO CHECK IF ALL AGENTS ARE ADDED TO FLOOR
  12. std::copy_if(background.begin(), background.end(), std::back_inserter(slipperyNorth), [](cell c) { return c.type == Type::SlipperyNorth; });
  13. std::copy_if(background.begin(), background.end(), std::back_inserter(slipperyEast), [](cell c) { return c.type == Type::SlipperyEast; });
  14. std::copy_if(background.begin(), background.end(), std::back_inserter(slipperySouth), [](cell c) { return c.type == Type::SlipperySouth; });
  15. std::copy_if(background.begin(), background.end(), std::back_inserter(slipperyWest), [](cell c) { return c.type == Type::SlipperyWest; });
  16. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(lockedDoors), [](cell c) { return c.type == Type::LockedDoor; });
  17. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(unlockedDoors), [](cell c) { return c.type == Type::Door; });
  18. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(goals), [](cell c) { return c.type == Type::Goal; });
  19. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(keys), [](cell c) { return c.type == Type::Key; });
  20. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(boxes), [](cell c) { return c.type == Type::Box; });
  21. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(balls), [](cell c) { return c.type == Type::Ball; });
  22. std::copy_if(gridCells.begin(), gridCells.end(), std::back_inserter(adversaries), [](cell c) { return c.type == Type::Adversary; });
  23. agent = *std::find_if(gridCells.begin(), gridCells.end(), [](cell c) { return c.type == Type::Agent; });
  24. floor.push_back(agent);
  25. agentNameAndPositionMap.insert({ "Agent", agent.getCoordinates() });
  26. for(auto const& adversary : adversaries) {
  27. std::string color = adversary.getColor();
  28. color.at(0) = std::toupper(color.at(0));
  29. try {
  30. auto success = agentNameAndPositionMap.insert({ color, adversary.getCoordinates() });
  31. floor.push_back(adversary);
  32. if(!success.second) {
  33. throw std::logic_error("Agent with " + color + " already present\n");
  34. }
  35. } catch(const std::logic_error& e) {
  36. std::cerr << "Expected agents colors to be different. Agent with color : '" << color << "' already present." << std::endl;
  37. throw;
  38. }
  39. }
  40. for(auto const& key : keys) {
  41. std::string color = key.getColor();
  42. try {
  43. auto success = keyNameAndPositionMap.insert({color, key.getCoordinates() });
  44. if (!success.second) {
  45. throw std::logic_error("Multiple keys with same color not supported " + color + "\n");
  46. }
  47. } catch(const std::logic_error& e) {
  48. std::cerr << "Expected key colors to be different. Key with color : '" << color << "' already present." << std::endl;
  49. throw;
  50. }
  51. }
  52. for(auto const& color : allColors) {
  53. cells cellsOfColor;
  54. std::copy_if(background.begin(), background.end(), std::back_inserter(cellsOfColor), [&color](cell c) {
  55. return c.type == Type::Floor && c.color == color;
  56. });
  57. if(cellsOfColor.size() > 0) {
  58. backgroundTiles.emplace(color, cellsOfColor);
  59. }
  60. }
  61. if(mType != prism::ModelType::MDP) {
  62. modelType = mType;
  63. } else if (adversaries.empty()) {
  64. modelType = prism::ModelType::MDP;
  65. } else {
  66. modelType = prism::ModelType::SMG;
  67. }
  68. }
  69. std::ostream& operator<<(std::ostream& os, const Grid& grid) {
  70. int lastRow = 1;
  71. for(auto const& cell : grid.allGridCells) {
  72. if(lastRow != cell.row)
  73. os << std::endl;
  74. os << static_cast<char>(cell.type) << static_cast<char>(cell.color);
  75. lastRow = cell.row;
  76. }
  77. return os;
  78. }
  79. cells Grid::getGridCells() {
  80. return allGridCells;
  81. }
  82. bool Grid::isBlocked(coordinates p) {
  83. return isWall(p);
  84. }
  85. bool Grid::isWall(coordinates p) {
  86. return std::find_if(walls.begin(), walls.end(),
  87. [p](cell cell) {
  88. return cell.row == p.second && cell.column == p.first;
  89. }) != walls.end();
  90. }
  91. void Grid::applyOverwrites(std::string& str, std::vector<Configuration>& configuration) {
  92. for (auto& config : configuration) {
  93. if (!config.overwrite_) {
  94. continue;
  95. }
  96. for (auto& index : config.indexes_) {
  97. size_t start_pos;
  98. std::string search;
  99. if (config.type_ == ConfigType::Formula) {
  100. search = "formula " + config.identifier_;
  101. } else if (config.type_ == ConfigType::Label) {
  102. search = "label " + config.identifier_;
  103. } else if (config.type_ == ConfigType::Module) {
  104. search = config.identifier_;
  105. } else if (config.type_ == ConfigType::UpdateOnly) {
  106. search = config.identifier_;
  107. }
  108. else if (config.type_ == ConfigType::Constant) {
  109. search = config.identifier_;
  110. }
  111. auto iter = boost::find_nth(str, search, index);
  112. auto end_identifier = config.end_identifier_;
  113. start_pos = std::distance(str.begin(), iter.begin());
  114. size_t end_pos = str.find(end_identifier, start_pos);
  115. if (config.type_ == ConfigType::GuardOnly) {
  116. start_pos += search.length();
  117. } else if (config.type_ == ConfigType::UpdateOnly) {
  118. start_pos = str.find("->", start_pos) + 2;
  119. }
  120. if (end_pos != std::string::npos && end_pos != 0) {
  121. std::string expression = config.expression_;
  122. str.replace(start_pos, end_pos - start_pos , expression);
  123. }
  124. }
  125. }
  126. }
  127. void Grid::printToPrism(std::ostream& os, std::vector<Configuration>& configuration) {
  128. cells northRestriction, eastRestriction, southRestriction, westRestriction;
  129. cells walkable = floor;
  130. walkable.insert(walkable.end(), goals.begin(), goals.end());
  131. walkable.insert(walkable.end(), boxes.begin(), boxes.end());
  132. walkable.insert(walkable.end(), lava.begin(), lava.end());
  133. walkable.insert(walkable.end(), keys.begin(), keys.end());
  134. walkable.insert(walkable.end(), balls.begin(), balls.end());
  135. for(auto const& c : walkable) {
  136. if(isWall(c.getNorth())) northRestriction.push_back(c);
  137. if(isWall(c.getEast())) eastRestriction.push_back(c);
  138. if(isWall(c.getSouth())) southRestriction.push_back(c);
  139. if(isWall(c.getWest())) westRestriction.push_back(c);
  140. }
  141. std::map<std::string, cells> wallRestrictions = {{"North", northRestriction}, {"East", eastRestriction}, {"South", southRestriction}, {"West", westRestriction}};
  142. std::map<std::string, cells> slipperyTiles = {{"North", slipperyNorth}, {"East", slipperyEast}, {"South", slipperySouth}, {"West", slipperyWest}};
  143. std::vector<AgentName> agentNames;
  144. std::transform(agentNameAndPositionMap.begin(),
  145. agentNameAndPositionMap.end(),
  146. std::back_inserter(agentNames),
  147. [](const std::map<AgentNameAndPosition::first_type,AgentNameAndPosition::second_type>::value_type &pair){return pair.first;});
  148. std::string agentName = agentNames.at(0);
  149. prism::PrismFormulaPrinter formulas(os, wallRestrictions, walls, boxes, balls, lockedDoors, unlockedDoors, keys, slipperyTiles, lava, goals);
  150. prism::PrismModulesPrinter modules(os, modelType, maxBoundaries, boxes, balls, lockedDoors, unlockedDoors, keys, slipperyTiles, agentNameAndPositionMap, configuration, probIntended, faultyProbability, !lava.empty(), !goals.empty());
  151. modules.printModelType(modelType);
  152. for(const auto &agentName : agentNames) {
  153. formulas.print(agentName);
  154. }
  155. //std::vector<std::string> constants {"const double prop_zero = 0/9;",
  156. // "const double prop_intended = 6/9;",
  157. // "const double prop_turn_intended = 6/9;",
  158. // "const double prop_displacement = 3/9;",
  159. // "const double prop_turn_displacement = 3/9;",
  160. // "const int width = " + std::to_string(maxBoundaries.first) + ";",
  161. // "const int height = " + std::to_string(maxBoundaries.second) + ";"
  162. // };
  163. //modules.printConstants(os, constants);
  164. modules.print();
  165. //if(!stateRewards.empty()) {
  166. // modules.printRewards(os, agentName, stateRewards, lava, goals, backgroundTiles);
  167. //}
  168. //if (!configuration.empty()) {
  169. // modules.printConfiguration(os, configuration);
  170. //}
  171. }