diff --git a/processor/logic/terrain.cpp b/processor/logic/terrain.cpp index 6c4aa22..deea5a2 100644 --- a/processor/logic/terrain.cpp +++ b/processor/logic/terrain.cpp @@ -28,59 +28,57 @@ bool ban(VertexType t) { return t == VertexType::Mountain || t == VertexType::Capital; } -template +template void upmin(T& x, const T& y) { if (y < x) x = y; } -const int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0}; +bool findCut(pos_t w, pos_t h, vector>& vertex_type) { + int idx = 0; + vector> dfn(h, vector(w)), low = dfn; + function tarjan + = [&](int x, int y, int fx, int fy, bool rt) { + dfn[x][y] = low[x][y] = ++idx; + int ch = 0; + for (int i = 0; i < 4; i++) { + const int xx = x + direction_dx[i], yy = y + direction_dy[i]; + if (xx < 0 || xx >= h || yy < 0 || yy >= w) + continue; -bool findCut(pos_t w, pos_t h, vector> &vertex_type) { - int idx = 0; - vector> dfn(h, vector(w)), low = dfn; - function tarjan = - [&](int x, int y, int fx, int fy, bool rt) { - dfn[x][y] = low[x][y] = ++idx; - int ch = 0; - for (int i = 0; i < 4; i++) { - const int xx = x + dx[i], yy = y + dy[i]; - if (xx < 0 || xx >= h || yy < 0 || yy >= w) - continue; + if (vertex_type[xx][yy] == VertexType::Capital) + vertex_type[x][y] = VertexType::Cut; - if (vertex_type[xx][yy] == VertexType::Capital) - vertex_type[x][y] = VertexType::Cut; + if (ban(vertex_type[xx][yy]) || (xx == fx && yy == fy)) + continue; - if (ban(vertex_type[xx][yy]) || (xx == fx && yy == fy)) - continue; + if (!dfn[xx][yy]) { + ch++; + tarjan(xx, yy, x, y, 0); + upmin(low[x][y], low[xx][yy]); + if (!rt && low[xx][yy] >= dfn[x][y]) + vertex_type[x][y] = VertexType::Cut; + } else { + upmin(low[x][y], dfn[xx][yy]); + } + } - if (!dfn[xx][yy]) { - ch++; - tarjan(xx, yy, x, y, 0); - upmin(low[x][y], low[xx][yy]); - if (!rt && low[xx][yy] >= dfn[x][y]) - vertex_type[x][y] = VertexType::Cut; - } else { - upmin(low[x][y], dfn[xx][yy]); - } - } + if (rt && ch >= 2) + vertex_type[x][y] = VertexType::Cut; + }; - if (rt && ch >= 2) - vertex_type[x][y] = VertexType::Cut; - }; - - bool flag = false; - for (pos_t i = 0; i < h; i++) { - for (pos_t j = 0; j < w; j++) { - if (!ban(vertex_type[i][j]) && !dfn[i][j]) { - if (flag) - return false; - flag = 1; - tarjan(i, j, -1, -1, 1); - } - } - } - return true; + bool flag = false; + for (pos_t i = 0; i < h; i++) { + for (pos_t j = 0; j < w; j++) { + if (!ban(vertex_type[i][j]) && !dfn[i][j]) { + if (flag) + return false; + flag = 1; + tarjan(i, j, -1, -1, 1); + } + } + } + return true; }; pair> generateCapital( @@ -88,7 +86,6 @@ pair> generateCapital( pos_t h, vector>& vertex_type, int r) { - vector res(r); for (int i = 0; i <= r; i++) { if (!findCut(w, h, vertex_type)) @@ -168,25 +165,27 @@ GameBoard ImportedTerrain::makeGameBoard(const InitInfo& init_info) { vector rest2; arrange(rest1, capitals.back(), rest2); - for (pos_t x = 0; x < h; x++) { - for (pos_t y = 0; y < w; y++) { - if (g.at(x, y).type == TileType::Capital) { - for (int i = 0; i < 4; i++) { - const int xx = x + dx[i], yy = y + dy[i]; - if (xx < 0 || xx >= h || yy < 0 || yy >= w) - continue; - if (g.at(xx, yy).type == TileType::Capital) - throw BadCapitalAssign(); - } - } - } - } + for (pos_t x = 0; x < h; x++) { + for (pos_t y = 0; y < w; y++) { + if (g.at(x, y).type == TileType::Capital) { + for (int i = 0; i < 4; i++) { + const int xx = x + direction_dx[i], + yy = y + direction_dy[i]; + if (xx < 0 || xx >= h || yy < 0 || yy >= w) + continue; + if (g.at(xx, yy).type == TileType::Capital) + throw BadCapitalAssign(); + } + } + } + } int T = 5; while (T--) { - vector> vertex_type(h - , vector(w, VertexType::Ordinary)); + vector> vertex_type( + h, + vector(w, VertexType::Ordinary)); for (pos_t i = 0; i < h; i++) { for (pos_t j = 0; j < w; j++) { if (g.at(i, j).type == TileType::Mountain) @@ -215,18 +214,18 @@ ImportedTerrain importTerrain(const ImportTerrainConfig& in) { t.w = in.w; t.h = in.h; t.tiles.resize(t.h, vector(t.w)); - + size_t pt = 0; auto error = [&]() { throw BadImportTerrainConfig(pt); }; auto view = [&](char c) { return pt < in.value.size() && in.value[pt] == c ? (pt++, true) : false; }; - + auto jump = [&](char c) { if (!view(c)) error(); }; - + auto read = [&](int l = -99999, int r = 99999) { bool neg = view('-'); if (!(pt < in.value.size() && isdigit(in.value[pt]))) @@ -250,8 +249,9 @@ ImportedTerrain importTerrain(const ImportTerrainConfig& in) { error(); vector>> vec(27, vector>(101)); - vector> vertex_type(t.h - , vector(t.w, VertexType::Ordinary)); + vector> vertex_type( + t.h, + vector(t.w, VertexType::Ordinary)); for (pos_t i = 0; i < t.h; i++) { for (pos_t j = 0; j < t.w; j++) { auto& p = t.tiles[i][j]; @@ -259,7 +259,7 @@ ImportedTerrain importTerrain(const ImportTerrainConfig& in) { p.type = TileType::Blank; } else if (view('m')) { p.type = TileType::Mountain; - vertex_type[i][j] = VertexType::Mountain; + vertex_type[i][j] = VertexType::Mountain; } else if (view('n')) { p.type = TileType::Blank; p.unit = read(); @@ -288,8 +288,8 @@ ImportedTerrain importTerrain(const ImportTerrainConfig& in) { if (pt != in.value.size()) error(); - if (!findCut(t.w, t.h, vertex_type)) - error(); + if (!findCut(t.w, t.h, vertex_type)) + error(); t.capitals.emplace_back(); for (int i = 0; i <= 26; i++) { diff --git a/processor/logic/terrain.h b/processor/logic/terrain.h index 504bc2d..c8c4851 100644 --- a/processor/logic/terrain.h +++ b/processor/logic/terrain.h @@ -42,4 +42,3 @@ private: ImportedTerrain importTerrain(const ImportTerrainConfig& in); #endif - diff --git a/processor/utility/log.cpp b/processor/utility/log.cpp new file mode 100644 index 0000000..eb48dbc --- /dev/null +++ b/processor/utility/log.cpp @@ -0,0 +1,51 @@ +#include "log.h" +#include +#include + +Logger* Logger::getInstance() { + return instance_; +} + +void Logger::debug(const std::string& s) const { + _log(LogLevel::Debug, s); +} + +void Logger::info(const std::string& s) const { + _log(LogLevel::Info, s); +} + +void Logger::warn(const std::string& s) const { + _log(LogLevel::Warn, s); +} + +void Logger::error(const std::string& s) const { + _log(LogLevel::Error, s); +} + +void Logger::fatal(const std::string& s) const { + _log(LogLevel::Fatal, s); +} + +void Logger::setLogLeval(LogLevel v) { + filter = v; +} + +Logger::Logger() { + filter = LogLevel::Warn; +} + +Logger* const Logger::instance_ = new Logger(); + +void Logger::_log(LogLevel v, const std::string& s) const { + if (v >= filter) { + time_t now = time(NULL); + static char buff[100]; + strftime(buff, sizeof(buff), "%Y-%m-%d %H:%M:%S", localtime(&now)); + const char* mp = "DIWEF"; + fprintf(stderr, "%s [%c] %s\n", buff, mp[(int)v], s.c_str()); + } +} + +Logger* Log() { + return Logger::getInstance(); +} diff --git a/processor/utility/log.h b/processor/utility/log.h index 1611ac2..d5efc94 100644 --- a/processor/utility/log.h +++ b/processor/utility/log.h @@ -1,27 +1,30 @@ #ifndef OG_LOG_H_ #define OG_LOG_H_ +#include "pc/commcode.h" #include #include -#include "pc/commcode.h" class Logger { -public: - Logger *getInstance() const; +public: + static Logger* getInstance(); - void debug(const std::string &) const; - void info(const std::string &) const; - void warn(const std::string &) const; - void error(const std::string &) const; - void fatal(const std::string &) const; + void debug(const std::string&) const; + void info(const std::string&) const; + void warn(const std::string&) const; + void error(const std::string&) const; + void fatal(const std::string&) const; + void setLogLeval(LogLevel v); private: Logger(); - void _log(LogLevel v, const std::string &) const; + static Logger* const instance_; + + void _log(LogLevel v, const std::string&) const; LogLevel filter; }; -Logger *Log(); +Logger* Log(); #endif