Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <bitset>
- #include <vector>
- #include <list>
- #include <set>
- #include <map>
- #include <algorithm>
- #include <memory>
- #include <iterator>
- #include <functional>
- using namespace std;
- struct Pos
- {
- int l;
- int c;
- };
- bool operator==(const Pos& p1, const Pos& p2)
- {
- return p1.l == p2.l && p1.c == p2.c;
- }
- int n;
- int m;
- Pos s;
- std::vector<Pos> o; /// obstacles
- std::vector<Pos> c; /// coins
- std::vector<std::pair<Pos, Pos>> p; /// portal
- void f(int d)
- {
- static int coins = 0, isOver = 0, playerEnteredInCyclicPortals = 0, i, j, noObstacleTaken = 0, total = 0;
- char mat[n + 1][m + 1];
- static map<pair<int, int>, int> isTaken, isObstacle, isPortal;
- map<pair<int,int>, vector<pair<int, int> >> adj;
- pair<int, int> tp_pos;
- int obstacleEncountered = 0, isInPortal = 0;
- for (int i = 1; i <= n; ++i) {
- for (int j = 1; j <= m; ++j) {
- mat[i][j] = '.';
- for (Pos coin: c) {
- if (coin.l == i && coin.c == j) {
- mat[i][j] = '$';
- }
- }
- }
- }
- // cout << "Lista initiala de adjaiacenta\n";
- vector<pair<int, int>> ls;
- for (pair<Pos, Pos> portal: p) {
- adj[make_pair(portal.first.l, portal.first.c)].push_back(make_pair(portal.second.l, portal.second.c));
- //cout << portal.first.l << ' ' << portal.first.c << ' ' << portal.second.l << ' ' << portal.second.c << '\n';
- //ls.push_back(make_pair(portal.first.l, portal.first.c));
- }
- //cout << "===========\n";
- //for (pair<int, int> x: adj[make_pair(5, 1)]) {
- // cout << x.first << ' ' << x.second << '\n';
- //}
- auto canTeleport = [&adj](int i, int j){
- pair<int, int> stiva[1000], tp_pos;
- map<pair<int, int>, int> visited;
- int vf = -1;
- // cout << "i = " << i << ';' << "j = " << j << '\n';
- for (pair<Pos, Pos> portal: p) {
- adj[make_pair(portal.first.l, portal.first.c)].push_back(make_pair(portal.second.l, portal.second.c));
- // cout << portal.first.l << ' ' << portal.first.c << ' ' << portal.second.l << ' ' << portal.second.c << '\n';
- //cout << visited[make_pair(portal.first.l, portal.first.c)] << '\n';
- // ls.push_back(make_pair(portal.first.l, portal.first.c));
- }
- stiva[++vf] = make_pair(i, j);
- visited[make_pair(i, j)] = 1;
- while (vf >= 0) {
- pair<int, int> elem_vf = stiva[vf];
- visited[elem_vf] = 1;
- --vf;
- if (adj[elem_vf].size() == 0)
- tp_pos = elem_vf;
- if (i == 5 && j == 1) {
- // cout << elem_vf.first << ' ' << elem_vf.second << '\n';
- //cout << "VECINII ASTORA DE SUS\n";
- }
- for (pair<int, int> vecini: adj[elem_vf]) {
- //cout << elem_vf.first << ' ' << elem_vf.second << ' ' << vecini.first << ' ' << vecini.second << '\n';
- if (!visited[make_pair(vecini.first, vecini.second)]) {
- stiva[++vf] = make_pair(vecini.first, vecini.second);
- visited[make_pair(vecini.first, vecini.second)] = 1;
- } else
- return make_pair(0, 0); // has cycle when (0, 0)
- }
- //cout << "===================\n" << '\n';
- }
- return tp_pos; //return the player teleporting position
- };
- // tp_pos = canTeleport(1, 1);
- //cout << tp_pos.first << ' ' << tp_pos.second;
- for (Pos obstacol: o) {
- mat[obstacol.l][obstacol.c] = '#';
- isObstacle[make_pair(obstacol.l, obstacol.c)] = 1;
- }
- if (!isOver) {
- mat[s.l][s.c] = '.';
- if (d == 1) { //nord
- if (s.l - 1 == 0 || coins < 0) {
- obstacleEncountered = 1;
- --coins;
- } else if (isObstacle[make_pair(s.l - 1, s.c)]) {
- --coins;
- obstacleEncountered = 1;
- }
- else { // check if it is portal
- for (pair<Pos, Pos> portal: p){
- i = portal.first.l;
- j = portal.first.c;
- if (i == s.l - 1 && j == s.c) {
- cout << i << ' ' << j << ' ';
- tp_pos = canTeleport(i, j);
- cout << "alooo";
- cout << tp_pos.first << ' ' << tp_pos.second << '\n';
- if (tp_pos != make_pair(0, 0)) {
- s.l = tp_pos.first;
- s.c = tp_pos.second;
- } else
- playerEnteredInCyclicPortals = 1;
- // cout << i << ' ' << j << ' ';
- //cout << tp_pos.first << ' ' << tp_pos.second << '\n';
- isInPortal = 1;
- }
- break;
- }
- if (!isInPortal)
- --s.l;
- }
- } else if (d == 2) { //vest
- if (s.c - 1 == 0 || coins < 0) {
- --coins;
- obstacleEncountered = 1;
- } else if (isObstacle[make_pair(s.l, s.c - 1)]) {
- --coins;
- obstacleEncountered = 1;
- }
- else {
- for (pair<Pos, Pos> portal: p) {
- i = portal.first.l;
- j = portal.first.c;
- if (i == s.l && j == s.c - 1) {
- cout << i << ' ' << j;
- tp_pos = canTeleport(i, j);
- if (tp_pos != make_pair(0, 0)) {
- s.l = tp_pos.first;
- s.c = tp_pos.second;
- } else
- playerEnteredInCyclicPortals = 1;
- isInPortal = 1;
- // cout << i << ' ' << j << ' ';
- //cout << tp_pos.first << ' ' << tp_pos.second << '\n';
- break;
- }
- }
- if (!isInPortal)
- --s.c;
- }
- } else if (d == 3) { //sud
- if (s.l + 1 == n + 1 || coins < 0) {
- --coins;
- obstacleEncountered = 1;
- } else if (isObstacle[make_pair(s.l + 1, s.c)]) {
- --coins;
- obstacleEncountered = 1;
- }
- else {
- for (pair<Pos, Pos> portal: p) {
- i = portal.first.l;
- j = portal.first.c;
- if (i == s.l + 1 && j == s.c) {
- cout << i << ' ' << j;
- tp_pos = canTeleport(i, j);
- if (tp_pos != make_pair(0, 0)) {
- s.l = tp_pos.first;
- s.c = tp_pos.second;
- } else
- playerEnteredInCyclicPortals = 1;
- // cout << i << ' ' << j << ' ';
- //cout << tp_pos.first << ' ' << tp_pos.second << '\n';
- isInPortal = 1;
- break;
- }
- }
- if (!isInPortal)
- ++s.l;
- }
- } else { // est
- if (s.c + 1 == m + 1 || coins < 0) {
- obstacleEncountered = 1;
- --coins;
- } else if (isObstacle[make_pair(s.l, s.c + 1)]) {
- --coins;
- obstacleEncountered = 1;
- }
- else {
- for (pair<Pos, Pos> portal: p) {
- i = portal.first.l;
- j = portal.first.c;
- if (i == s.l && j == s.c + 1) {
- cout << i << ' ' << j;
- tp_pos = canTeleport(i, j);
- if (tp_pos != make_pair(0, 0)) {
- s.l = tp_pos.first;
- s.c = tp_pos.second;
- } else
- playerEnteredInCyclicPortals = 1;
- isInPortal = 1;
- // cout << i << ' ' << j << ' ';
- //cout << tp_pos.first << ' ' << tp_pos.second << '\n';
- break;
- }
- }
- if (!isInPortal)
- ++s.c;
- }
- }
- if (mat[s.l][s.c] == '$' && !isTaken[make_pair(s.l, s.c)]) {
- mat[s.l][s.c] = 'x';
- isTaken[make_pair(s.l, s.c)] = 1;
- //cout << s.l << ' ' << s.c << ' ' << coins << '\n';
- ++total;
- ++coins;
- }
- }
- cout << s.l << ' ' << s.c << '\n';
- for (int i = 1; i <= n; ++i) {
- for (int j = 1; j <= m; ++j) {
- if (i == s.l && j == s.c) {
- cout << 'x'; /// pozitia jucatorului
- } else if (isObstacle[make_pair(i, j)] == 1) {
- cout << '#';
- } else if (mat[i][j] == '$'){
- if (isTaken[make_pair(i, j)])
- cout << '.';
- else
- cout << '$';
- } else {
- isInPortal = 0;
- for (pair<Pos, Pos> portal: p) {
- if (portal.first.l == i && portal.first.c == j || portal.second.l == i && portal.second.c == j) {
- cout << 'O';
- isInPortal = 1;
- break;
- }
- }
- if (!isInPortal)
- cout << '.';
- }
- }
- cout << '\n';
- }
- // cout << !noObstacleTaken << ' ' << coins << ' ' << (coins == c.size()) << '\n';
- // cout << coins << ' ' << c.size() << '\n';
- if (total == c.size()) {
- cout << "Wow! - Game over: You won!\n";
- isOver = 1;
- }else if (coins >= 0 && obstacleEncountered) {
- cout << "Ups! - Coins: " << coins << '\n';
- ++noObstacleTaken;
- }else if (coins < 0)
- cout << "Ups! - Game over: You lost!\n";
- else if (playerEnteredInCyclicPortals) {
- cout << "Ups! - Game over: Goodbye!\n";
- isOver = 1;
- }else
- cout << "Coins: " << coins << '\n';
- }
- int main(int argc, const char* argv[])
- {
- if (argc == 1)
- {
- cout << "No arguments";
- return 1;
- }
- string inputFile = argv[1];
- ifstream in(inputFile.c_str(), ios::in);
- std::streambuf *cinbuf = std::cin.rdbuf(); // save stdin buffer
- std::cin.rdbuf(in.rdbuf()); // redirect std::cin to input file (.in)
- if (!in.is_open())
- {
- cout << "Cannot open input file";
- return 1;
- }
- string line;
- getline(in, line);
- std::istringstream smn(line);
- smn >> n >> m; /// line coloumn
- getline(in, line);
- std::istringstream ss(line);
- ss >> s.l >> s.c; /// player's position
- getline(in, line);
- int no = atoi(line.c_str()); /// nr obstacole
- for (int i = 0; i < no; i++)
- {
- Pos p;
- getline(in, line);
- std::istringstream sl(line);
- sl >> p.l >> p.c; /// coordonate obstacole
- o.push_back(p); /// obstacolele sunt marcate cu $
- }
- getline(in, line);
- int nc = atoi(line.c_str());
- for (int i = 0; i < nc; i++) /// coins
- {
- Pos p;
- getline(in, line);
- std::istringstream sl(line);
- sl >> p.l >> p.c;
- c.push_back(p);
- }
- getline(in, line);
- int np = atoi(line.c_str()); /// nr puncte
- for (int i = 0; i < np; i++)
- {
- Pos p1, p2;
- getline(in, line);
- std::istringstream sl(line);
- sl >> p1.l >> p1.c >> p2.l >> p2.c;
- p.push_back({ p1, p2 }); /// pozitiile punctelor
- }
- getline(in, line);
- int nm = atoi(line.c_str()); /// nr de mutari al jucatorului
- getline(in, line);
- std::istringstream sm(line);
- for (int i = 0; i < nm; i++) /// citim fiecare mutare
- {
- int d;
- sm >> d;
- f(d);
- }
- std::cin.rdbuf(cinbuf); // reset to stdin again
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement