#include "terrain.h" #include #include #include using namespace std; BadImportTerrainConfig::BadImportTerrainConfig(size_t pt):pt(pt){} const char* BadImportTerrainConfig::what() const noexcept{ return ("ImportTerrainConfig "+to_string(pt)).c_str(); } const char* BadCapitalAssign::what() const noexcept{ return "Bad Capital Assign"; } inline namespace{ mt19937 rnd(19260817); enum class VertexType:std::uint8_t{ Ordinary,Mountain,Capital,Cut }; bool ban(VertexType t){return t==VertexType::Mountain||t==VertexType::Capital;} template void upmin(T &x,const T &y){if(y> generateCapital(pos_t w,pos_t h,vector> &vertex_type,int r){ auto findCut=[&](){ 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++){ static const int dx[]={0,0,-1,1},dy[]={-1,1,0,0}; 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(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(rt&&ch>=2) vertex_type[x][y]=VertexType::Cut; }; bool flag=0; for(pos_t i=0;i res(r); for(int i=0;i<=r;i++){ if(!findCut()) return {false,vector()}; if(i==r) break; vector options; for(pos_t x=0;x()}; res[i]=options[rnd()%options.size()]; vertex_type[res[i].x][res[i].y]=VertexType::Capital; } return {true,res}; } } GameBoard ImportedTerrain::makeGameBoard(const InitInfo &init_info){ auto perm=[](std::uint8_t n){ vector vec(n); iota(vec.begin(),vec.end(),0); shuffle(vec.begin(),vec.end(),rnd); return vec; }; GameBoard g(w,h,init_info); for(pos_t i=0;i &players,const vector> &capitals,vector &rest){ vector caps; for(const auto &v:capitals){ for(const auto &p:v) caps.push_back(p); if(caps.size()>=players.size()) break; } auto C=perm(players.size()),D=perm(caps.size()); for(size_t j=D.size();j> players(g.numTeams()); for(int i=1,n=g.numPlayers();i<=n;i++) players[g.teamOf(i)-1].push_back(i); auto A=perm(players.size()),B=perm(capitals.size()-1); vector rest1; for(size_t i=B.size();i rest2; arrange(rest1,capitals.back(),rest2); int T=5; while(T--){ vector> vertex_type(h,vector(w,VertexType::Ordinary)); for(pos_t i=0;i(t.w)); size_t pt=0; auto error=[&](){throw BadImportTerrainConfig(pt);}; auto view=[&](char c){return pt99999) error(); pt++; } if(neg) x=-x; if(xr) error(); return x; }; static vector vec[27][101]; for(pos_t i=0;i=1;j--){ if(!vec[i][j].empty()){ t.capitals.back().emplace_back().swap(vec[i][j]); } } if(!t.capitals.back().empty()&&i!=26){ t.capitals.emplace_back(); } } return t; }