Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Simulates the KOL Crimbo 2014 factory. Poorly...
- //This source code is in the public domain.
- #include <iostream>
- #include <vector>
- #include <map>
- #include <thread>
- #include <random>
- #include <chrono> //! crono! wake up, crono!
- #include <queue>
- const bool setting_simulate_schematics_as_well = false;
- const int setting_simulate_floor_min = 1;
- const int setting_simulate_floor_max = 3;
- enum class robot_capability
- {
- blam,
- light,
- pow,
- roll,
- run,
- zap,
- hover,
- lube,
- pinch,
- decode,
- freeze,
- MAX_CAPABILITY
- };
- //This should be changed to use a fixed array, from 0 to MAX_CAPABILITY. Much faster that way, but slightly unsafe.
- class RobotCapabilities
- {
- public:
- void addCapability(const robot_capability & capability);
- void addCapabilities(const RobotCapabilities & capabilities_other);
- bool hasCapability(const robot_capability & capability) const;
- int capabilityAmount(const robot_capability & capability) const;
- bool capabilityWillFulfillOurs(const RobotCapabilities & capabilities_other) const;
- private:
- std::map <robot_capability,int> capabilities_map;
- };
- void RobotCapabilities::addCapability(const robot_capability & capability)
- {
- capabilities_map[capability] += 1;
- }
- void RobotCapabilities::addCapabilities(const RobotCapabilities & capabilities_other)
- {
- for (auto & iterator : capabilities_other.capabilities_map)
- {
- capabilities_map[iterator.first] += iterator.second;
- }
- }
- bool RobotCapabilities::hasCapability(const robot_capability & capability) const
- {
- return capabilityAmount(capability) > 0;
- }
- int RobotCapabilities::capabilityAmount(const robot_capability & capability) const
- {
- if (capabilities_map.count(capability) == 0)
- return 0;
- return capabilities_map.find(capability)->second;
- }
- bool RobotCapabilities::capabilityWillFulfillOurs(const RobotCapabilities & capabilities_other) const
- {
- for (auto & iterator : capabilities_map)
- {
- if (capabilities_other.capabilityAmount(iterator.first) < iterator.second)
- return false;
- }
- return true;
- }
- struct SimulationStateMutable
- {
- SimulationStateMutable() : current_hp(0), schematics_recovered(0), items_recovered(0), room(0) {}
- int current_hp;
- int schematics_recovered;
- int items_recovered;
- int room;
- };
- struct SimulationStateFixed
- {
- template <typename ... T>
- SimulationStateFixed(const int base_hp_in, const T & ... capabilities); //capabilities must be of type robot_capability
- int base_hp;
- RobotCapabilities capabilities;
- int chosen_floor;
- int chosen_maze_strategy_1; //for floor 2, 1 means up, 2 means down
- bool choose_parts_over_schematics;
- void addToCapabilities(const SimulationStateFixed & other);
- };
- template <typename ... T>
- SimulationStateFixed::SimulationStateFixed(const int base_hp_in, const T & ... capabilities_in) : base_hp(base_hp_in)
- {
- chosen_maze_strategy_1 = 1;
- choose_parts_over_schematics = false;
- const robot_capability capabilities_in_array[] = { capabilities_in... };
- for (robot_capability capability : capabilities_in_array)
- {
- capabilities.addCapability(capability);
- }
- }
- void SimulationStateFixed::addToCapabilities(const SimulationStateFixed & other)
- {
- base_hp += other.base_hp;
- capabilities.addCapabilities(other.capabilities);
- }
- struct RoomOption
- {
- RoomOption() : schematics_given(0), parts_given(0), minimum_hp_damage_dealt(0), maximum_hp_damage_dealt(0) {}
- template <typename ... T>
- RoomOption(int schematics_given_in, int parts_given_in, int hp_damage_dealt_in, T ... capabilities); //capabilities must be of type robot_capability
- template <typename ... T>
- RoomOption(int schematics_given_in, int parts_given_in, int minimum_hp_damage_dealt_in, int maximum_hp_damage_dealt_in, T ... capabilities);
- RobotCapabilities required_capabilities;
- int schematics_given;
- int parts_given;
- int minimum_hp_damage_dealt;
- int maximum_hp_damage_dealt;
- bool capableOfChoosingChoice(const RobotCapabilities & with_capabilities) const;
- int capabilities[static_cast<int>(robot_capability::MAX_CAPABILITY)];
- };
- template <typename ... T>
- RoomOption::RoomOption(int schematics_given_in, int parts_given_in, int hp_damage_dealt_in, T ... capabilities_in) : schematics_given(schematics_given_in), parts_given(parts_given_in), minimum_hp_damage_dealt(hp_damage_dealt_in), maximum_hp_damage_dealt(hp_damage_dealt_in)
- {
- const robot_capability capabilities_in_array[] = { capabilities_in... };
- for (robot_capability capability : capabilities_in_array)
- {
- required_capabilities.addCapability(capability);
- }
- }
- template <typename ... T>
- RoomOption::RoomOption(int schematics_given_in, int parts_given_in, int minimum_hp_damage_dealt_in, int maximum_hp_damage_dealt_in, T ... capabilities_in) : schematics_given(schematics_given_in), parts_given(parts_given_in), minimum_hp_damage_dealt(minimum_hp_damage_dealt_in), maximum_hp_damage_dealt(maximum_hp_damage_dealt_in)
- {
- const robot_capability capabilities_in_array[] = { capabilities_in... };
- for (robot_capability capability : capabilities_in_array)
- {
- required_capabilities.addCapability(capability);
- }
- }
- bool RoomOption::capableOfChoosingChoice(const RobotCapabilities & with_capabilities) const
- {
- return required_capabilities.capabilityWillFulfillOurs(with_capabilities);
- }
- struct Room
- {
- Room();
- Room(std::string name_in, const std::vector <RoomOption> & options_in) : name(name_in), options(options_in) {}
- std::vector <RoomOption> options;
- std::string name;
- };
- struct RoomCollection
- {
- std::vector <Room> potential_rooms;
- };
- struct FactoryLayout
- {
- std::map <int, RoomCollection> first_area_layout; //room number - 2 is the start
- std::map <int, RoomCollection> second_area_layout_up_path;
- std::map <int, RoomCollection> second_area_layout_down_path;
- std::map <int, RoomCollection> third_area_layout;
- };
- enum class robot_part_location
- {
- left_arm,
- right_arm,
- torso,
- propulsion
- };
- struct RobotPart
- {
- RobotPart(const std::string & name_in, const robot_part_location & location_in, const SimulationStateFixed & capability_modifiers_in) : name(name_in), location(location_in), capability_modifiers(capability_modifiers_in) {}
- std::string name;
- robot_part_location location;
- SimulationStateFixed capability_modifiers;
- };
- struct possible_outcome
- {
- double probability;
- int hp;
- double schematics;
- double items;
- };
- void simulateOnce(std::mt19937 & rng_generator, const FactoryLayout & factory_layout, const SimulationStateFixed & fixed_state, int * parts_found_out, int * schematics_found_out, int * room_ended_at_out)
- {
- //Note that it would be much faster to replace area_layout with a pre-computed vector that already knows which options we can choose. By around 30%.
- //But, that can cause simulation error if not done properly, so...
- SimulationStateMutable state = SimulationStateMutable();
- state.current_hp = fixed_state.base_hp;
- state.room = 2;
- const std::map <int, RoomCollection> * area_layout = &factory_layout.first_area_layout;
- if (fixed_state.chosen_floor == 2)
- {
- if (fixed_state.chosen_maze_strategy_1 == 1)
- area_layout = &factory_layout.second_area_layout_up_path;
- else
- area_layout = &factory_layout.second_area_layout_down_path;
- }
- if (fixed_state.chosen_floor == 3)
- area_layout = &factory_layout.third_area_layout;
- const bool output_debug = false;
- if (output_debug)
- printf("-\n");
- while (state.current_hp > 0)
- {
- if (area_layout->count(state.room) == 0)
- {
- break;
- }
- const RoomCollection & room_collection = area_layout->find(state.room)->second;
- if (room_collection.potential_rooms.size() == 0)
- {
- printf("INTERNAL ERROR: Room collection too small.\n");
- break;
- }
- //Generate a room:
- //int picked_id = random() % room_collection.potential_rooms.size();
- int picked_id = std::uniform_int_distribution<>(0, (int)room_collection.potential_rooms.size() - 1)(rng_generator);
- const Room & current_room = room_collection.potential_rooms[picked_id];
- const RoomOption * chosen_option = 0;
- int chosen_option_score = 0;
- for (const RoomOption & option : current_room.options)
- {
- if (!option.capableOfChoosingChoice(fixed_state.capabilities))
- continue;
- bool is_better = false;
- int score = 0;
- if (fixed_state.choose_parts_over_schematics)
- {
- score += option.parts_given * 100;
- score += option.schematics_given * 10;
- }
- else
- {
- score += option.parts_given * 10;
- score += option.schematics_given * 100;
- }
- score -= (option.minimum_hp_damage_dealt + option.maximum_hp_damage_dealt);
- //Is this better?
- if (!chosen_option)
- is_better = true;
- else if (score > chosen_option_score)
- is_better = true;
- if (is_better)
- {
- chosen_option = &option;
- chosen_option_score = score;
- }
- }
- if (output_debug)
- printf("\tOn room %i. HP is %i.\n", state.room, state.current_hp);
- if (!chosen_option)
- {
- printf("INTERNAL ERROR: No option.\n");
- break;
- }
- if (chosen_option->parts_given > 0)
- *parts_found_out += chosen_option->parts_given;
- if (chosen_option->schematics_given > 0)
- *schematics_found_out += chosen_option->schematics_given;
- if (chosen_option->maximum_hp_damage_dealt != 0)
- {
- if (output_debug)
- printf("\t\tGenerating random HP damage in range [%i, %i]\n", chosen_option->minimum_hp_damage_dealt, chosen_option->maximum_hp_damage_dealt);
- int damage_done = std::uniform_int_distribution<>(chosen_option->minimum_hp_damage_dealt, chosen_option->maximum_hp_damage_dealt)(rng_generator);
- state.current_hp -= damage_done;
- if (output_debug)
- printf("\t\tTook %i damage.\n", damage_done);
- }
- if (state.current_hp > 0)
- state.room += 1;
- }
- *room_ended_at_out = state.room;
- }
- std::vector<possible_outcome> estimateRoom( const FactoryLayout & factory_layout, const SimulationStateFixed & fixed_state, int room, possible_outcome currentState)
- {
- //Note that it would be much faster to replace area_layout with a pre-computed vector that already knows which options we can choose. By around 30%.
- //But, that can cause simulation error if not done properly, so...
- std::vector<possible_outcome> ret;
- bool output_debug=false;
- SimulationStateMutable state = SimulationStateMutable();
- state.current_hp = fixed_state.base_hp;
- state.room = room+2;
- const std::map <int, RoomCollection> * area_layout = &factory_layout.first_area_layout;
- if (fixed_state.chosen_floor == 2)
- {
- if (fixed_state.chosen_maze_strategy_1 == 1)
- area_layout = &factory_layout.second_area_layout_up_path;
- else
- area_layout = &factory_layout.second_area_layout_down_path;
- }
- if (fixed_state.chosen_floor == 3)
- area_layout = &factory_layout.third_area_layout;
- const RoomCollection & room_collection = area_layout->find(state.room)->second;
- if (area_layout->count(state.room) == 0)
- {
- return ret;
- }
- if (room_collection.potential_rooms.size() == 0)
- {
- printf("INTERNAL ERROR: Room collection too small.\n");
- return ret;
- }
- double room_probability=1.0/(double)room_collection.potential_rooms.size();
- for(unsigned int i=0;i<room_collection.potential_rooms.size();i++)
- {
- const Room & current_room = room_collection.potential_rooms[i];
- int chosen_option_score = 0;
- const RoomOption * chosen_option = 0;
- for (const RoomOption & option : current_room.options)
- {
- if (!option.capableOfChoosingChoice(fixed_state.capabilities))
- continue;
- bool is_better = false;
- int score = 0;
- if (fixed_state.choose_parts_over_schematics)
- {
- score += option.parts_given * 100;
- score += option.schematics_given * 10;
- }
- else
- {
- score += option.parts_given * 10;
- score += option.schematics_given * 100;
- }
- score -= (option.minimum_hp_damage_dealt + option.maximum_hp_damage_dealt);
- //Is this better?
- if (!chosen_option)
- is_better = true;
- else if (score > chosen_option_score)
- is_better = true;
- if (is_better)
- {
- chosen_option = &option;
- chosen_option_score = score;
- }
- }
- if (output_debug)
- printf("\tOn room %i. HP is %i.\n", state.room, state.current_hp);
- if (!chosen_option)
- {
- printf("INTERNAL ERROR: No option.\n");
- return ret;
- }
- double num_damages=1.0/(double)(chosen_option->maximum_hp_damage_dealt-chosen_option->minimum_hp_damage_dealt+1);
- for(int i=chosen_option->minimum_hp_damage_dealt;i<=chosen_option->maximum_hp_damage_dealt;i++)
- {
- possible_outcome newOutcome=possible_outcome();
- newOutcome.hp=currentState.hp-i;
- newOutcome.probability=currentState.probability*room_probability*num_damages;
- newOutcome.schematics=currentState.schematics+chosen_option->schematics_given;
- newOutcome.items=currentState.items+chosen_option->parts_given;
- ret.push_back(newOutcome);
- }
- }
- return ret;
- }
- std::vector<possible_outcome> collapseTreeByHP(std::vector<possible_outcome> tree)
- {
- std::map <int,possible_outcome> temp;
- std::vector <possible_outcome> ret;
- for(std::vector<possible_outcome>::size_type i = 0; i != tree.size(); i++)
- {
- std::map<int,possible_outcome>::iterator fnd=temp.find(tree[i].hp);
- if(fnd==temp.end())//not found
- {
- possible_outcome nil;
- nil.hp=tree[i].hp;
- nil.probability=0;
- nil.schematics=0;
- nil.items=0;
- temp[tree[i].hp]=nil;
- }
- temp[tree[i].hp].probability+=tree[i].probability;
- temp[tree[i].hp].schematics+=tree[i].probability*tree[i].schematics;
- temp[tree[i].hp].items+=tree[i].probability*tree[i].items;
- }
- for( std::map <int,possible_outcome> ::iterator it = temp.begin(); it != temp.end(); ++it ) {
- possible_outcome to_adj=it->second;
- to_adj.items/=to_adj.probability;
- to_adj.schematics/=to_adj.probability;
- ret.push_back(to_adj );
- }
- return ret;
- }
- void simulateAllAndOutput(const FactoryLayout & factory_layout, const unsigned int simulation_count, const RobotPart & part_left_arm, const RobotPart & part_right_arm, const RobotPart & part_torso, const RobotPart & part_propulsion, const int floor_in, const int maze_strategy_in, const bool pick_parts_over_schematics)
- {
- //Create state for this set of parts:
- SimulationStateFixed fixed_state = SimulationStateFixed(0);
- fixed_state.addToCapabilities(part_left_arm.capability_modifiers);
- fixed_state.addToCapabilities(part_right_arm.capability_modifiers);
- fixed_state.addToCapabilities(part_torso.capability_modifiers);
- fixed_state.addToCapabilities(part_propulsion.capability_modifiers);
- fixed_state.chosen_floor = floor_in;
- fixed_state.chosen_maze_strategy_1 = maze_strategy_in;
- fixed_state.choose_parts_over_schematics = pick_parts_over_schematics;
- if (fixed_state.chosen_floor == 2 && !fixed_state.capabilities.hasCapability(robot_capability::pinch))
- {
- return;
- }
- if (fixed_state.chosen_floor == 3 && !fixed_state.capabilities.hasCapability(robot_capability::decode))
- {
- return;
- }
- std::vector <int> total_rooms_ended_at_frequency;
- std::mt19937 rng_generator = std::mt19937(std::chrono::high_resolution_clock::now().time_since_epoch().count());
- uint64_t total_parts_found = 0;
- uint64_t total_schematics_found = 0;
- uint64_t total_rooms_ended_at = 0;
- //Run simulation:
- std::vector <possible_outcome> tree;
- possible_outcome root;
- root.probability=1;
- root.hp=fixed_state.base_hp;
- root.schematics=0;
- root.items=0;
- tree.push_back(root);
- int croom=0;
- double average_parts_found = 0;
- double average_schematics_found = 0;
- double average_rooms_ended_at = 0;
- int furtherest_room_ended_at = 0;
- double chance_of_last_room =0;
- while(tree.size()>0)
- {
- furtherest_room_ended_at++;
- croom++;
- std::vector <possible_outcome> newTree;
- chance_of_last_room =0;
- //go forward one room, checking for all possibilities
- for(std::vector<possible_outcome>::size_type i = 0; i != tree.size(); i++)
- {
- chance_of_last_room+=tree[i].probability;
- std::vector<possible_outcome> newOnes=estimateRoom( factory_layout, fixed_state, croom, tree[i]);
- // printf("NewSize: %d\n",newOnes.size());
- newTree.insert(newTree.end(),newOnes.begin(),newOnes.end());
- }
- newTree=collapseTreeByHP(newTree);
- tree.clear();
- for(std::vector<possible_outcome>::size_type i = 0; i != newTree.size(); i++)
- {
- if(newTree[i].hp<=0)//we are dead, collect results
- {
- average_parts_found+=newTree[i].items*newTree[i].probability;
- average_schematics_found+=newTree[i].schematics*newTree[i].probability;
- average_rooms_ended_at=croom*newTree[i].probability;
- }
- else //still ok, go to next round
- {
- tree.push_back(newTree[i]);
- }
- }
- }
- std::string strategy_string = "N/A";
- if (fixed_state.chosen_floor == 2)
- {
- if (fixed_state.chosen_maze_strategy_1 == 1)
- strategy_string = "ascend";
- else
- strategy_string = "descend";
- }
- std::string parts_or_schematics;
- if (fixed_state.choose_parts_over_schematics)
- parts_or_schematics = "parts";
- else
- parts_or_schematics = "schematics";
- printf("%i\t%s\t%s\t%s\t%s\t%s\t%s\t%f\t%f\t%f\t%i\t%f\n", fixed_state.chosen_floor, strategy_string.c_str(), parts_or_schematics.c_str(), part_left_arm.name.c_str(), part_right_arm.name.c_str(), part_torso.name.c_str(), part_propulsion.name.c_str(), average_parts_found, average_schematics_found, average_rooms_ended_at, furtherest_room_ended_at, chance_of_last_room);
- }
- int main(int argc, const char * argv[])
- {
- auto start_time = std::chrono::high_resolution_clock::now();
- std::map <robot_part_location, std::vector <RobotPart> > parts_list;
- for (robot_part_location location : {robot_part_location::left_arm, robot_part_location::right_arm, robot_part_location::torso, robot_part_location::propulsion})
- {
- parts_list[location] = std::vector<RobotPart>();
- }
- {
- std::vector <RobotPart> parts_list_creating;
- parts_list_creating.push_back(RobotPart("Tiny Fist", robot_part_location::left_arm, SimulationStateFixed(0, robot_capability::pow)));
- parts_list_creating.push_back(RobotPart("Bug Zapper", robot_part_location::left_arm, SimulationStateFixed(1,robot_capability::zap)));
- parts_list_creating.push_back(RobotPart("Rodent Gun", robot_part_location::left_arm, SimulationStateFixed(0,robot_capability::blam)));
- parts_list_creating.push_back(RobotPart("Rivet Shocker", robot_part_location::left_arm, SimulationStateFixed(0,robot_capability::zap,robot_capability::pow)));
- parts_list_creating.push_back(RobotPart("Mega Vise", robot_part_location::left_arm, SimulationStateFixed(0,robot_capability::pow,robot_capability::pow)));
- parts_list_creating.push_back(RobotPart("Mobile Girder", robot_part_location::left_arm, SimulationStateFixed(3)));
- parts_list_creating.push_back(RobotPart("Swiss Arm", robot_part_location::left_arm, SimulationStateFixed(0, robot_capability::pow, robot_capability::blam, robot_capability::zap)));
- parts_list_creating.push_back(RobotPart("Ball-Bearing Dispenser", robot_part_location::right_arm, SimulationStateFixed(0, robot_capability::blam)));
- parts_list_creating.push_back(RobotPart("Power Arm", robot_part_location::right_arm, SimulationStateFixed(0,robot_capability::zap)));
- parts_list_creating.push_back(RobotPart("Wrecking Ball", robot_part_location::right_arm, SimulationStateFixed(1,robot_capability::pow)));
- parts_list_creating.push_back(RobotPart("Ribbon Manipulator", robot_part_location::right_arm, SimulationStateFixed(0,robot_capability::pinch)));
- parts_list_creating.push_back(RobotPart("Grease / Regular Gun", robot_part_location::right_arm, SimulationStateFixed(0,robot_capability::lube,robot_capability::blam)));
- parts_list_creating.push_back(RobotPart("Grease Gun", robot_part_location::right_arm, SimulationStateFixed(0,robot_capability::lube)));
- parts_list_creating.push_back(RobotPart("Power Stapler", robot_part_location::right_arm, SimulationStateFixed(0,robot_capability::zap, robot_capability::pinch)));
- parts_list_creating.push_back(RobotPart("Snow Blower", robot_part_location::right_arm, SimulationStateFixed(0,robot_capability::freeze)));
- parts_list_creating.push_back(RobotPart("Basic Head", robot_part_location::torso, SimulationStateFixed(3)));
- parts_list_creating.push_back(RobotPart("Gun Face", robot_part_location::torso, SimulationStateFixed(3,robot_capability::blam)));
- parts_list_creating.push_back(RobotPart("Big Head", robot_part_location::torso, SimulationStateFixed(4)));
- parts_list_creating.push_back(RobotPart("Security Chassis", robot_part_location::torso, SimulationStateFixed(3,robot_capability::light)));
- parts_list_creating.push_back(RobotPart("Military Chassis", robot_part_location::torso, SimulationStateFixed(3,robot_capability::light,robot_capability::blam)));
- parts_list_creating.push_back(RobotPart("Crab Core", robot_part_location::torso, SimulationStateFixed(4,robot_capability::pinch)));
- parts_list_creating.push_back(RobotPart("Cyclopean Torso", robot_part_location::torso, SimulationStateFixed(4,robot_capability::light)));
- parts_list_creating.push_back(RobotPart("Dynamo Head", robot_part_location::torso, SimulationStateFixed(4,robot_capability::zap)));
- parts_list_creating.push_back(RobotPart("Regular Legs", robot_part_location::propulsion, SimulationStateFixed(0, robot_capability::run)));
- parts_list_creating.push_back(RobotPart("Heavy-Duty Legs", robot_part_location::propulsion, SimulationStateFixed(1, robot_capability::run)));
- parts_list_creating.push_back(RobotPart("Tripod Legs", robot_part_location::propulsion, SimulationStateFixed(0,robot_capability::run,robot_capability::run)));
- parts_list_creating.push_back(RobotPart("Rollerfeet", robot_part_location::propulsion, SimulationStateFixed(0,robot_capability::run,robot_capability::roll)));
- parts_list_creating.push_back(RobotPart("Hoverjack", robot_part_location::propulsion, SimulationStateFixed(2,robot_capability::hover)));
- parts_list_creating.push_back(RobotPart("Sim-Simian Feet", robot_part_location::propulsion, SimulationStateFixed(0,robot_capability::run, robot_capability::pinch)));
- parts_list_creating.push_back(RobotPart("High-Speed Fan", robot_part_location::propulsion, SimulationStateFixed(1,robot_capability::hover)));
- parts_list_creating.push_back(RobotPart("Big Wheel", robot_part_location::propulsion, SimulationStateFixed(0, robot_capability::roll, robot_capability::roll)));
- for (RobotPart part : parts_list_creating)
- {
- parts_list[part.location].push_back(part);
- }
- }
- FactoryLayout factory_layout = FactoryLayout();
- {
- RoomCollection collection_bot;
- RoomCollection collection_obstacle_t1;
- RoomCollection collection_obstacle_t2;
- RoomCollection collection_reward;
- collection_bot.potential_rooms.push_back(Room("Zippybot", {RoomOption(0, 0, 0, robot_capability::zap), RoomOption(0, 0, 1)}));
- collection_bot.potential_rooms.push_back(Room("Turretbot", {RoomOption(0, 0, 0, robot_capability::blam), RoomOption(0, 0, 1)}));
- collection_bot.potential_rooms.push_back(Room("Mookbot", {RoomOption(0, 0, 0, robot_capability::blam), RoomOption(0, 0, 0, robot_capability::pow), RoomOption(0, 0, 1)}));
- collection_bot.potential_rooms.push_back(Room("Doorbot", {RoomOption(0, 0, 0, robot_capability::pow), RoomOption(0, 0, 0, robot_capability::zap), RoomOption(0, 0, 1)}));
- collection_bot.potential_rooms.push_back(Room("Bulkybot", {RoomOption(0, 0, 0, robot_capability::pow), RoomOption(0, 0, 1)}));
- collection_bot.potential_rooms.push_back(Room("Security Drone", {RoomOption(0, 0, 0, robot_capability::blam), RoomOption(0, 0, 0, robot_capability::zap), RoomOption(0, 0, 1)}));
- //FIXME which schematic?
- collection_reward.potential_rooms.push_back(Room("The Dilemma", {RoomOption(1, 0, 0), RoomOption(0, 1, 0)}));
- collection_reward.potential_rooms.push_back(Room("Locker Room", {RoomOption(0, 1, 0)}));
- collection_reward.potential_rooms.push_back(Room("The Unhurt Locker", {RoomOption(0, 1, 0)}));
- collection_reward.potential_rooms.push_back(Room("Office Space", {RoomOption(0, 1, 0), RoomOption(1, 0, 0, robot_capability::pow, robot_capability::pow)})); //office space
- collection_reward.potential_rooms.push_back(Room("The Dark Closet Returns", {RoomOption(0, 1, 0), RoomOption(0, 2, 0, robot_capability::light)}));
- collection_reward.potential_rooms.push_back(Room("Inadequate Copy Room Security", {RoomOption(1, 0, 0)}));
- collection_reward.potential_rooms.push_back(Room("Paperchase", {RoomOption(1, 0, 0)}));
- collection_obstacle_t1.potential_rooms.push_back(Room("Conveyor, Convey Thyself", {RoomOption(0, 0, 0, robot_capability::blam, robot_capability::blam), RoomOption(0, 0, 1)}));
- collection_obstacle_t1.potential_rooms.push_back(Room("The Monster Masher!", {RoomOption(0, 0, 0, robot_capability::zap, robot_capability::zap), RoomOption(0, 0, 1)}));
- collection_obstacle_t1.potential_rooms.push_back(Room("Some People Call It A Giant Slingblade", {RoomOption(0, 0, 0, robot_capability::run, robot_capability::run), RoomOption(0, 0, 1)}));
- collection_obstacle_t1.potential_rooms.push_back(Room("War of Gears", {RoomOption(0, 0, 0, robot_capability::pow, robot_capability::pow), RoomOption(1,0,0,robot_capability::hover), RoomOption(0, 0, 2)}));
- collection_obstacle_t1.potential_rooms.push_back(Room("Crate Expectations", {RoomOption(0, 0, 0, robot_capability::pow, robot_capability::pow), RoomOption(0, 0, 2)}));
- collection_obstacle_t1.potential_rooms.push_back(Room("Tin Door. Rusted.", {RoomOption(0, 0, 0, robot_capability::blam, robot_capability::blam), RoomOption(0,2,0,robot_capability::lube), RoomOption(0, 0, 2)})); //free is 2 damage, lube gives 2 items
- collection_obstacle_t2.potential_rooms.push_back(Room("Closing Time", {RoomOption(0, 0, 1, robot_capability::run, robot_capability::run), RoomOption(0, 0, 2)}));
- collection_obstacle_t2.potential_rooms.push_back(Room("Gone With the Wind", {RoomOption(0, 0, 1, robot_capability::pow, robot_capability::pow), RoomOption(0, 0, 2)}));
- collection_obstacle_t2.potential_rooms.push_back(Room("Getting Your Bearings", {RoomOption(0, 0, 1, robot_capability::roll), RoomOption(0, 0, 2)}));
- collection_obstacle_t2.potential_rooms.push_back(Room("Down In Flames", {RoomOption(0, 0, 1, robot_capability::blam, robot_capability::blam), RoomOption(0, 0, 2)}));
- for (int room_number = 2; room_number < 100; room_number += 4)
- {
- factory_layout.first_area_layout[room_number] = collection_bot;
- factory_layout.first_area_layout[room_number + 1] = collection_obstacle_t1;
- factory_layout.first_area_layout[room_number + 2] = collection_reward;
- factory_layout.first_area_layout[room_number + 3] = collection_obstacle_t2;
- }
- //more, but unlikely to reach
- }
- {
- //Second floor:
- RoomCollection collection_bot;
- RoomCollection collection_obstacle;
- RoomCollection collection_up_ladder;
- RoomCollection collection_down_ladder;
- RoomCollection collection_ladder;
- //Many data points for the bots:
- collection_bot.potential_rooms.push_back(Room("Bot Your Shield", {RoomOption(0, 0, 0, robot_capability::blam, robot_capability::blam), RoomOption(0, 0, 2, 2)}));
- collection_bot.potential_rooms.push_back(Room("Whatcha Thinkin'?", {RoomOption(0, 0, 0, robot_capability::zap, robot_capability::zap), RoomOption(0, 0, 2, 2)}));
- collection_bot.potential_rooms.push_back(Room("Festively Armed", {RoomOption(0, 0, 0, robot_capability::lube), RoomOption(0, 0, 1, 1)}));
- collection_bot.potential_rooms.push_back(Room("Compugilist", {RoomOption(0, 0, 0, robot_capability::pow, robot_capability::pow), RoomOption(0, 0, 2, 2)}));
- collection_bot.potential_rooms.push_back(Room("I See You", {RoomOption(0, 0, 0, robot_capability::light), RoomOption(0, 0, 1, 1)}));
- collection_obstacle.potential_rooms.push_back(Room("A Vent Horizon", {RoomOption(0, 0, 2, 2, robot_capability::freeze), RoomOption(0, 0, 3, 4)}));
- collection_obstacle.potential_rooms.push_back(Room("Off The Rails", {RoomOption(0, 0, 2, 2, robot_capability::roll, robot_capability::roll), RoomOption(0, 0, 3, 4)}));
- collection_obstacle.potential_rooms.push_back(Room("The Floor is Like Lava", {RoomOption(0, 0, 2, 2, robot_capability::hover), RoomOption(0, 0, 3, 4)}));
- collection_obstacle.potential_rooms.push_back(Room("A Pressing Concern", {RoomOption(0, 0, 2, 2, robot_capability::run,robot_capability::run), RoomOption(0, 0, 3, 4)}));
- //FIXME rewards need more precise
- collection_up_ladder.potential_rooms.push_back(Room("Still Life With Despair", {RoomOption(0, 1, 0, robot_capability::pinch), RoomOption(1, 0, 0, robot_capability::zap, robot_capability::zap)}));
- collection_up_ladder.potential_rooms.push_back(Room("Hope You Have A Beretta", {RoomOption(1, 0, 0, robot_capability::pinch), RoomOption(0, 1, 0, robot_capability::blam, robot_capability::blam)}));
- collection_up_ladder.potential_rooms.push_back(Room("This Gym Is Much Nicer", {RoomOption(0, 1, 0, robot_capability::pinch), RoomOption(1, 0, 0, robot_capability::pinch)}));
- //FIXME unsure about damage:
- collection_down_ladder.potential_rooms.push_back(Room("Pants in High Places", {RoomOption(1, 0, 0, robot_capability::blam, robot_capability::blam), RoomOption(0, 0, 2, 3)}));
- collection_down_ladder.potential_rooms.push_back(Room("Humpster Dumpster", {RoomOption(0, 1, 0, robot_capability::lube), RoomOption(0, 0, 2, 3)}));
- collection_down_ladder.potential_rooms.push_back(Room("Cage Match", {RoomOption(1, 0, 0, robot_capability::zap, robot_capability::zap), RoomOption(0, 0, 2, 3)}));
- collection_down_ladder.potential_rooms.push_back(Room("Birdbot is the Wordbot", {RoomOption(0, 1, 0, robot_capability::blam, robot_capability::blam), RoomOption(0, 0, 2, 3)}));
- collection_ladder.potential_rooms.push_back(Room("The Corporate Ladder", {RoomOption(0, 0, 0), RoomOption(0, 0, 0)}));
- for (int room_number = 2; room_number < 100; room_number += 4)
- {
- factory_layout.second_area_layout_up_path[room_number] = collection_bot;
- factory_layout.second_area_layout_up_path[room_number + 1] = collection_ladder;
- factory_layout.second_area_layout_up_path[room_number + 2] = collection_up_ladder;
- factory_layout.second_area_layout_up_path[room_number + 3] = collection_obstacle;
- factory_layout.second_area_layout_down_path[room_number] = collection_bot;
- factory_layout.second_area_layout_down_path[room_number + 1] = collection_ladder;
- factory_layout.second_area_layout_down_path[room_number + 2] = collection_down_ladder;
- factory_layout.second_area_layout_down_path[room_number + 3] = collection_obstacle;
- }
- }
- printf("Floor\tStrategy\tChoose parts or schematics?\tLeft arm\tRight arm\tTorso\tPropulsion\tAverage parts found\tAverage schematics found\tAverage rooms ended at\tFurthest room ended at\tLikelyhood of reaching that room\n");
- unsigned int simulation_count = 10000000;
- simulation_count = 1000000;
- //simulation_count = 100000000;
- if (false)
- {
- //Former debug:
- simulation_count = 10000000;
- //Bug Zapper Wrecking Ball Military Chassis Regular Legs
- simulateAllAndOutput(factory_layout, simulation_count, parts_list[robot_part_location::left_arm][1], parts_list[robot_part_location::right_arm][2], parts_list[robot_part_location::torso][4], parts_list[robot_part_location::propulsion][0], 1, 1, true);
- return 0;
- }
- if (true) //individualised threading, faster
- {
- unsigned int wanted_thread_count = std::thread::hardware_concurrency() + 8; //HACK to use full CPU because we're not using a work queue (and should)
- //essentially, a bunch of these executions terminate early and show up in our queue and count against our limit
- //doing this correctly requires a proper work queue, but honestly I am not familiar enough with C++ to implement that the correct way, and pthread's semaphores didn't work too well on OS X last I tried
- //so instead, we just spawn a bunch of extra threads we don't need to, to saturate the CPU. this will likely affect performance and is a bad decision
- std::queue <std::thread> active_threads;
- for (RobotPart part_left_arm : parts_list[robot_part_location::left_arm])
- {
- for (RobotPart part_right_arm : parts_list[robot_part_location::right_arm])
- {
- for (RobotPart part_torso : parts_list[robot_part_location::torso])
- {
- for (RobotPart part_propulsion : parts_list[robot_part_location::propulsion])
- {
- for (int floor = setting_simulate_floor_min; floor <= setting_simulate_floor_max; floor++)
- {
- int max_strategy = 1;
- if (floor == 2)
- max_strategy = 2;
- for (int strategy = 1; strategy <= max_strategy; strategy++)
- {
- if (active_threads.size() >= wanted_thread_count)
- {
- active_threads.front().join();
- active_threads.pop();
- }
- if (setting_simulate_schematics_as_well)
- active_threads.push(std::thread(simulateAllAndOutput, factory_layout, simulation_count, part_left_arm, part_right_arm, part_torso, part_propulsion, floor, strategy, false));
- active_threads.push(std::thread(simulateAllAndOutput, factory_layout, simulation_count, part_left_arm, part_right_arm, part_torso, part_propulsion, floor, strategy, true));
- }
- }
- }
- }
- }
- }
- while (active_threads.size() > 0)
- {
- active_threads.front().join();
- active_threads.pop();
- }
- }
- else
- {
- for (RobotPart part_left_arm : parts_list[robot_part_location::left_arm])
- {
- for (RobotPart part_right_arm : parts_list[robot_part_location::right_arm])
- {
- for (RobotPart part_torso : parts_list[robot_part_location::torso])
- {
- for (RobotPart part_propulsion : parts_list[robot_part_location::propulsion])
- {
- for (int floor = 1; floor < 3; floor++)
- {
- if (setting_simulate_schematics_as_well)
- simulateAllAndOutput(factory_layout, simulation_count, part_left_arm, part_right_arm, part_torso, part_propulsion, floor, 1, false);
- simulateAllAndOutput(factory_layout, simulation_count, part_left_arm, part_right_arm, part_torso, part_propulsion, floor, 1, true);
- }
- }
- }
- }
- }
- }
- auto end_time = std::chrono::high_resolution_clock::now();
- double computation_time = std::chrono::duration_cast<std::chrono::duration<double>>(end_time - start_time).count();
- printf("Computed in %f seconds.\n", computation_time);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement