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.

200 lines
9.2 KiB

11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
11 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. } else if (config.type_ == ConfigType::GuardOnly) {
  108. search = config.identifier_;
  109. }
  110. else if (config.type_ == ConfigType::Constant) {
  111. search = config.identifier_;
  112. }
  113. auto iter = boost::find_nth(str, search, index);
  114. auto end_identifier = config.end_identifier_;
  115. start_pos = std::distance(str.begin(), iter.begin());
  116. size_t end_pos = str.find(end_identifier, start_pos);
  117. if (config.type_ == ConfigType::GuardOnly) {
  118. start_pos += search.length();
  119. } else if (config.type_ == ConfigType::UpdateOnly) {
  120. start_pos = str.find("->", start_pos) + 2;
  121. }
  122. if (end_pos != std::string::npos && end_pos != 0) {
  123. std::string expression = config.expression_;
  124. str.replace(start_pos, end_pos - start_pos , expression);
  125. }
  126. }
  127. }
  128. }
  129. void Grid::printToPrism(std::ostream& os, std::vector<Configuration>& configuration) {
  130. cells northRestriction, eastRestriction, southRestriction, westRestriction;
  131. cells walkable = floor;
  132. walkable.insert(walkable.end(), goals.begin(), goals.end());
  133. walkable.insert(walkable.end(), boxes.begin(), boxes.end());
  134. walkable.insert(walkable.end(), lava.begin(), lava.end());
  135. walkable.insert(walkable.end(), keys.begin(), keys.end());
  136. walkable.insert(walkable.end(), balls.begin(), balls.end());
  137. for(auto const& c : walkable) {
  138. if(isWall(c.getNorth())) northRestriction.push_back(c);
  139. if(isWall(c.getEast())) eastRestriction.push_back(c);
  140. if(isWall(c.getSouth())) southRestriction.push_back(c);
  141. if(isWall(c.getWest())) westRestriction.push_back(c);
  142. }
  143. std::map<std::string, cells> wallRestrictions = {{"North", northRestriction}, {"East", eastRestriction}, {"South", southRestriction}, {"West", westRestriction}};
  144. std::map<std::string, cells> slipperyTiles = {{"North", slipperyNorth}, {"East", slipperyEast}, {"South", slipperySouth}, {"West", slipperyWest}};
  145. std::vector<AgentName> agentNames;
  146. std::transform(agentNameAndPositionMap.begin(),
  147. agentNameAndPositionMap.end(),
  148. std::back_inserter(agentNames),
  149. [](const std::map<AgentNameAndPosition::first_type,AgentNameAndPosition::second_type>::value_type &pair){return pair.first;});
  150. std::string agentName = agentNames.at(0);
  151. prism::PrismFormulaPrinter formulas(os, wallRestrictions, walls, boxes, balls, lockedDoors, unlockedDoors, keys, slipperyTiles, lava, goals);
  152. prism::PrismModulesPrinter modules(os, modelType, maxBoundaries, boxes, balls, lockedDoors, unlockedDoors, keys, slipperyTiles, agentNameAndPositionMap, configuration, probIntended, faultyProbability, !lava.empty(), !goals.empty());
  153. modules.printModelType(modelType);
  154. for(const auto &agentName : agentNames) {
  155. formulas.print(agentName);
  156. }
  157. //std::vector<std::string> constants {"const double prop_zero = 0/9;",
  158. // "const double prop_intended = 6/9;",
  159. // "const double prop_turn_intended = 6/9;",
  160. // "const double prop_displacement = 3/9;",
  161. // "const double prop_turn_displacement = 3/9;",
  162. // "const int width = " + std::to_string(maxBoundaries.first) + ";",
  163. // "const int height = " + std::to_string(maxBoundaries.second) + ";"
  164. // };
  165. //modules.printConstants(os, constants);
  166. modules.print();
  167. //if(!stateRewards.empty()) {
  168. // modules.printRewards(os, agentName, stateRewards, lava, goals, backgroundTiles);
  169. //}
  170. //if (!configuration.empty()) {
  171. // modules.printConfiguration(os, configuration);
  172. //}
  173. }