Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <vector>
- #include <algorithm>
- #include <chrono>
- #include <cmath>
- #include <float.h>
- #include <climits>
- using namespace std::chrono;
- high_resolution_clock::time_point now = high_resolution_clock::now();
- #define TIME duration_cast<duration<double>>(high_resolution_clock::now() - now).count()
- using namespace std;
- const int height = 10;
- const int width = 19;
- const int grid_size = height * width;
- const int robotCount = 10;
- int sim_count = 0;
- struct vec2
- {
- int x;
- int y;
- };
- struct Robot;
- struct Grid;
- template<class T, class U>
- vec2 sum(T a, U b)
- {
- return { a.x + b.x, a.y + b.y };
- }
- template <class T>
- int findIndex(T a)
- {
- return a.y * width + a.x;
- }
- int findIndex(int x, int y)
- {
- return y * width + x;
- }
- enum Type
- {
- Up = 1 << 0,
- Right = 1 << 1,
- Down = 1 << 2,
- Left = 1 << 3,
- Void,
- Empty
- };
- struct Grid : vec2
- {
- Grid()
- {
- for (int &s : states_used)
- s = 0;
- }
- Grid(int x, int y, Type type)
- {
- this->x = x;
- this->y = y;
- this->type = type;
- for (int &s : states_used)
- s = 0;
- }
- void init(int x, int y, Type type)
- {
- this->x = x;
- this->y = y;
- this->type = type;
- }
- Type type;
- int states_used[robotCount];
- };
- struct Robot : vec2
- {
- Robot() {
- alive = false;
- }
- Robot(int x, int y, Type type)
- {
- this->x = x;
- this->y = y;
- this->type = type;
- alive = true;
- }
- void init(int x, int y, Type type, int id)
- {
- this->x = x;
- this->y = y;
- this->type = type;
- this->id = id;
- alive = true;
- }
- Type type;
- int id;
- bool alive;
- };
- struct State
- {
- Grid grid[grid_size];
- Robot robots[robotCount];
- void generate_arrows()
- {
- for (auto & cell : grid)
- {
- if (cell.type != Empty) continue;
- if (rand() % 100 > 10) continue;
- int type_index = rand() % 4;
- Type type;
- switch (type_index)
- {
- case 0:
- type = Up;
- break;
- case 1:
- type = Down;
- break;
- case 2:
- type = Left;
- break;
- case 3:
- type = Right;
- break;
- }
- cell.type = type;
- }
- }
- void simulate_setup()
- {
- for (auto & r : robots)
- {
- if (!r.alive) continue;
- Grid &cell = grid[findIndex(r)];
- if (cell.type != Empty)
- {
- r.type = cell.type;
- }
- cell.states_used[r.id] |= r.type;
- }
- }
- int simulate_game()
- {
- simulate_setup();
- int score = 0;
- int alive = alive_robots();
- while (alive)
- {
- score += alive;
- for (auto &robot : robots)
- {
- if (!robot.alive) continue;
- switch (robot.type)
- {
- case Up:
- robot.y--;
- if (robot.y < 0)
- {
- robot.y = height - 1;
- }
- break;
- case Down:
- robot.y++;
- if (robot.y > height - 1)
- {
- robot.y = 0;
- }
- break;
- case Left:
- robot.x--;
- if (robot.x < 0)
- {
- robot.x = width - 1;
- }
- break;
- case Right:
- robot.x++;
- if (robot.x > width - 1)
- {
- robot.x = 0;
- }
- break;
- }
- Grid &cell = grid[findIndex(robot)];
- if (cell.type == Void || cell.states_used[robot.id] & robot.type)
- {
- robot.alive = false;
- alive--;
- continue;
- }
- //TODO IDETI JEI ROBOTAS I ZENGIA I INFINITE LOOP
- cell.states_used[robot.id] |= robot.type;
- // Robotas vis dar gyvas, izenge i nauja cell
- if (cell.type != Type::Empty)
- {
- robot.type = cell.type;
- }
- }
- }
- return score;
- }
- bool out_of_bounds(vec2 pos)
- {
- return pos.x < 0 || pos.y < 0 || pos.x > width - 1 || pos.y > height - 1;
- }
- int alive_robots()
- {
- int alive = 0;
- for (auto r : robots)
- {
- if (r.alive)
- alive++;
- }
- return alive;
- }
- };
- struct Agent
- {
- State state;
- int bestScore;
- State bestState;
- void read()
- {
- for (int y = 0; y < 10; y++) {
- string line;
- cin >> line; cin.ignore();
- for (int x = 0; x < line.size(); x++)
- {
- Grid &cell = state.grid[findIndex(x, y)];
- Type type;
- if (line[x] == 'U') type = Up;
- else if (line[x] == 'D') type = Down;
- else if (line[x] == 'L') type = Left;
- else if (line[x] == 'R') type = Right;
- else if (line[x] == '#') type = Void;
- else type = Empty;
- cell.init(x, y, type);
- }
- }
- now = high_resolution_clock::now();
- int robotCount;
- cin >> robotCount; cin.ignore();
- for (int i = 0; i < robotCount; i++) {
- int x;
- int y;
- char direction;
- cin >> x >> y >> direction; cin.ignore();
- Type type;
- if (direction == 'U') type = Up;
- else if (direction == 'D') type = Down;
- else if (direction == 'L') type = Left;
- else if (direction == 'R') type = Right;
- state.robots[i].init(x, y, type, i);
- }
- }
- void think()
- {
- bestScore = -INT_MAX;
- while (TIME * 1000 < 998)
- {
- sim_count++;
- State sim_state = state;
- sim_state.generate_arrows();
- int score = sim_state.simulate_game();
- if (score > bestScore)
- {
- bestScore = score;
- bestState = sim_state;
- }
- }
- }
- void output()
- {
- cerr << "SIMULIACIJU PRAEJO " << sim_count << " o score : " << bestScore << endl;
- struct Out { int x; int y; char dir; };
- vector<Out> out;
- for (auto &cell : bestState.grid)
- {
- if (cell.type == Empty || cell.type == Void) continue;
- char dir;
- switch (cell.type)
- {
- case Up:
- dir = 'U';
- break;
- case Down:
- dir = 'D';
- break;
- case Left:
- dir = 'L';
- break;
- case Right:
- dir = 'R';
- break;
- }
- out.push_back({ cell.x , cell.y, dir });
- }
- for (int i = 0; i < out.size(); i++)
- {
- cout << out[i].x << " " << out[i].y << " " << out[i].dir;
- if (i < out.size() - 1) cout << " ";
- }cout << endl;
- }
- };
- int main()
- {
- srand(time(0));
- Agent agent;
- agent.read();
- agent.think();
- agent.output();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement