format code from lcw
Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
parent
97fbd11f8a
commit
45b67a2274
148
processor/.clang-format
Normal file
148
processor/.clang-format
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: Left
|
||||||
|
AlignConsecutiveMacros: None
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignConsecutiveBitFields: None
|
||||||
|
AlignConsecutiveDeclarations: None
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
AttributeMacros: []
|
||||||
|
BinPackArguments: false
|
||||||
|
BinPackParameters: false
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: All
|
||||||
|
BreakBeforeConceptDeclarations: true
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 80
|
||||||
|
QualifierAlignment: Left
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: Always
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
PackConstructorInitializers: NextLine
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
AllowAllConstructorInitializersOnNextLine: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros: []
|
||||||
|
IfMacros: []
|
||||||
|
IncludeBlocks: Merge
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentRequires: false
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertTrailingCommas: Wrapped
|
||||||
|
InsertBraces: false
|
||||||
|
InsertNewlineAtEOF: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PointerAlignment: Left
|
||||||
|
PPIndentWidth: -1
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: false
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterOverloadedOperator: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
Standard: Latest
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Always
|
||||||
|
|
@ -1,194 +1,280 @@
|
|||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include <random>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <random>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
BadImportTerrainConfig::BadImportTerrainConfig(size_t pt):pt(pt){}
|
BadImportTerrainConfig::BadImportTerrainConfig(size_t pt): pt(pt) {}
|
||||||
|
|
||||||
const char* BadImportTerrainConfig::what() const noexcept{
|
const char* BadImportTerrainConfig::what() const noexcept {
|
||||||
return ("ImportTerrainConfig "+to_string(pt)).c_str();
|
return ("ImportTerrainConfig " + to_string(pt)).c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* BadCapitalAssign::what() const noexcept{
|
const char* BadCapitalAssign::what() const noexcept {
|
||||||
return "Bad Capital Assign";
|
return "Bad Capital Assign";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline namespace{
|
inline namespace {
|
||||||
mt19937 rnd(19260817);
|
|
||||||
enum class VertexType:std::uint8_t{
|
mt19937 rnd(19260817);
|
||||||
Ordinary,Mountain,Capital,Cut
|
enum class VertexType : std::uint8_t {
|
||||||
};
|
Ordinary,
|
||||||
bool ban(VertexType t){return t==VertexType::Mountain||t==VertexType::Capital;}
|
Mountain,
|
||||||
template<typename T> void upmin(T &x,const T &y){if(y<x)x=y;}
|
Capital,
|
||||||
pair<bool,vector<Point>> generateCapital(pos_t w,pos_t h,vector<vector<VertexType>> &vertex_type,int r){
|
Cut
|
||||||
auto findCut=[&](){
|
};
|
||||||
int idx=0; vector<vector<int>> dfn(h,vector<int>(w)),low=dfn;
|
|
||||||
function<void(int,int,int,int,bool)> tarjan=[&](int x,int y,int fx,int fy,bool rt){
|
bool ban(VertexType t) {
|
||||||
dfn[x][y]=low[x][y]=++idx;
|
return t == VertexType::Mountain || t == VertexType::Capital;
|
||||||
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<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;
|
|
||||||
};
|
|
||||||
vector<Point> res(r);
|
|
||||||
for(int i=0;i<=r;i++){
|
|
||||||
if(!findCut()) return {false,vector<Point>()};
|
|
||||||
if(i==r) break;
|
|
||||||
vector<Point> options;
|
|
||||||
for(pos_t x=0;x<h;x++){
|
|
||||||
for(pos_t y=0;y<w;y++){
|
|
||||||
if(vertex_type[x][y]==VertexType::Ordinary) options.emplace_back(x,y);
|
|
||||||
if(vertex_type[x][y]==VertexType::Cut) vertex_type[x][y]=VertexType::Ordinary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(options.empty()) return {false,vector<Point>()};
|
|
||||||
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){
|
template <typename T>
|
||||||
auto perm=[](std::uint8_t n){
|
void upmin(T& x, const T& y) {
|
||||||
vector<std::uint8_t> vec(n);
|
if (y < x)
|
||||||
iota(vec.begin(),vec.end(),0);
|
x = y;
|
||||||
shuffle(vec.begin(),vec.end(),rnd);
|
|
||||||
return vec;
|
|
||||||
};
|
|
||||||
GameBoard g(w,h,init_info);
|
|
||||||
for(pos_t i=0;i<h;i++){
|
|
||||||
for(pos_t j=0;j<w;j++){
|
|
||||||
g.at(i,j).type=tiles[i][j].type;
|
|
||||||
g.at(i,j).unit=tiles[i][j].unit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto arrange=[&perm,&g](const vector<Player> &players,const vector<vector<Point>> &capitals,vector<Player> &rest){
|
|
||||||
vector<Point> 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<C.size();j++)
|
|
||||||
rest.push_back(players[C[j]]);
|
|
||||||
for(size_t j=0;j<min(C.size(),D.size());j++){
|
|
||||||
g.at(caps[D[j]].x,caps[D[j]].y).type=TileType::Capital;
|
|
||||||
g.at(caps[D[j]].x,caps[D[j]].y).owner=players[C[j]];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
vector<vector<Player>> 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<Player> rest1;
|
|
||||||
for(size_t i=B.size();i<A.size();i++)
|
|
||||||
for(auto id:players[A[i]]) rest1.push_back(id);
|
|
||||||
for(size_t i=0;i<min(A.size(),B.size());i++)
|
|
||||||
arrange(players[A[i]],capitals[B[i]],rest1);
|
|
||||||
vector<Player> rest2;
|
|
||||||
arrange(rest1,capitals.back(),rest2);
|
|
||||||
int T=5;
|
|
||||||
while(T--){
|
|
||||||
vector<vector<VertexType>> vertex_type(h,vector<VertexType>(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) vertex_type[i][j]=VertexType::Mountain;
|
|
||||||
if(g.at(i,j).type==TileType::Capital) vertex_type[i][j]=VertexType::Capital;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto pr=generateCapital(w,h,vertex_type,rest2.size());
|
|
||||||
if(!pr.first) continue;
|
|
||||||
for(size_t i=0;i<rest2.size();i++){
|
|
||||||
g.at(pr.second[i].x,pr.second[i].y).type=TileType::Capital;
|
|
||||||
g.at(pr.second[i].x,pr.second[i].y).owner=rest2[i];
|
|
||||||
}
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
throw BadCapitalAssign();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportedTerrain importTerrain(const ImportTerrainConfig &in){
|
pair<bool, vector<Point>> generateCapital(
|
||||||
ImportedTerrain t;
|
pos_t w,
|
||||||
t.w=in.w,t.h=in.h;
|
pos_t h,
|
||||||
t.tiles.resize(t.h,vector<ImportedTerrain::TerrainTile>(t.w));
|
vector<vector<VertexType>>& vertex_type,
|
||||||
size_t pt=0;
|
int r) {
|
||||||
auto error=[&](){throw BadImportTerrainConfig(pt);};
|
auto findCut = [&]() {
|
||||||
auto view=[&](char c){return pt<in.value.size()&&in.value[pt]==c?(pt++,true):false;};
|
int idx = 0;
|
||||||
auto jump=[&](char c){if(!view(c)) error();};
|
vector<vector<int>> dfn(h, vector<int>(w)), low = dfn;
|
||||||
auto read=[&](int l=-99999,int r=99999){
|
function<void(int, int, int, int, bool)> tarjan =
|
||||||
bool neg=view('-');
|
[&](int x, int y, int fx, int fy, bool rt) {
|
||||||
if(!(pt<in.value.size()&&isdigit(in.value[pt]))) error();
|
dfn[x][y] = low[x][y] = ++idx;
|
||||||
std::int32_t x=0;
|
int ch = 0;
|
||||||
while(pt<in.value.size()&&isdigit(in.value[pt])){
|
for (int i = 0; i < 4; i++) {
|
||||||
x=x*10+(in.value[pt]^'0');
|
static const int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0};
|
||||||
if(x>99999) error(); pt++;
|
const int xx = x + dx[i], yy = y + dy[i];
|
||||||
}
|
if (xx < 0 || xx >= h || yy < 0 || yy >= w)
|
||||||
if(neg) x=-x;
|
continue;
|
||||||
if(x<l||x>r) error();
|
|
||||||
return x;
|
if (vertex_type[xx][yy] == VertexType::Capital)
|
||||||
};
|
vertex_type[x][y] = VertexType::Cut;
|
||||||
static vector<Point> vec[27][101];
|
|
||||||
for(pos_t i=0;i<t.h;i++){
|
if (ban(vertex_type[xx][yy]) || (xx == fx && yy == fy))
|
||||||
for(pos_t j=0;j<t.w;j++){
|
continue;
|
||||||
auto &p=t.tiles[i][j];
|
|
||||||
if(view(' ')) p.type=TileType::Blank;
|
if (!dfn[xx][yy]) {
|
||||||
else if(view('m')) p.type=TileType::Mountain;
|
ch++;
|
||||||
else if(view('n')){
|
tarjan(xx, yy, x, y, 0);
|
||||||
p.type=TileType::Blank;
|
upmin(low[x][y], low[xx][yy]);
|
||||||
p.unit=read();
|
if (!rt && low[xx][yy] >= dfn[x][y])
|
||||||
}
|
vertex_type[x][y] = VertexType::Cut;
|
||||||
else if(view('s')) p.type=TileType::Swamp;
|
} else {
|
||||||
else if(view('g')){
|
upmin(low[x][y], dfn[xx][yy]);
|
||||||
p.type=TileType::Blank;
|
}
|
||||||
bool tag=1;
|
}
|
||||||
int team=(pt<in.value.size()&&isupper(in.value[pt])?in.value[pt++]-'A':(tag=view(' '),26));
|
|
||||||
int priority=(tag&&pt<in.value.size()&&isdigit(in.value[pt])?read(1,99):100);
|
if (rt && ch >= 2)
|
||||||
vec[team][priority].emplace_back(i,j);
|
vertex_type[x][y] = VertexType::Cut;
|
||||||
}
|
};
|
||||||
else{
|
|
||||||
p.type=TileType::Stronghold;
|
bool flag = false;
|
||||||
p.unit=read();
|
for (pos_t i = 0; i < h; i++) {
|
||||||
}
|
for (pos_t j = 0; j < w; j++) {
|
||||||
if(i+1<t.h||j+1<t.w) jump(',');
|
if (!ban(vertex_type[i][j]) && !dfn[i][j]) {
|
||||||
}
|
if (flag)
|
||||||
}
|
return false;
|
||||||
if(pt!=in.value.size()) error();
|
flag = 1, tarjan(i, j, -1, -1, 1);
|
||||||
t.capitals.emplace_back();
|
}
|
||||||
for(int i=0;i<=26;i++){
|
}
|
||||||
for(int j=100;j>=1;j--){
|
}
|
||||||
if(!vec[i][j].empty()){
|
return true;
|
||||||
t.capitals.back().emplace_back().swap(vec[i][j]);
|
};
|
||||||
}
|
|
||||||
}
|
vector<Point> res(r);
|
||||||
if(!t.capitals.back().empty()&&i!=26){
|
for (int i = 0; i <= r; i++) {
|
||||||
t.capitals.emplace_back();
|
if (!findCut())
|
||||||
}
|
return {false, vector<Point>()};
|
||||||
}
|
|
||||||
return t;
|
if (i == r)
|
||||||
|
break;
|
||||||
|
vector<Point> options;
|
||||||
|
for (pos_t x = 0; x < h; x++) {
|
||||||
|
for (pos_t y = 0; y < w; y++) {
|
||||||
|
if (vertex_type[x][y] == VertexType::Ordinary)
|
||||||
|
options.emplace_back(x, y);
|
||||||
|
if (vertex_type[x][y] == VertexType::Cut)
|
||||||
|
vertex_type[x][y] = VertexType::Ordinary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.empty())
|
||||||
|
return {false, {}};
|
||||||
|
|
||||||
|
res[i] = options[rnd() % options.size()];
|
||||||
|
vertex_type[res[i].x][res[i].y] = VertexType::Capital;
|
||||||
|
}
|
||||||
|
return {true, res};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
GameBoard ImportedTerrain::makeGameBoard(const InitInfo& init_info) {
|
||||||
|
auto perm = [](std::uint8_t n) {
|
||||||
|
vector<std::uint8_t> 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 < h; i++) {
|
||||||
|
for (pos_t j = 0; j < w; j++) {
|
||||||
|
g.at(i, j).type = tiles[i][j].type;
|
||||||
|
g.at(i, j).unit = tiles[i][j].unit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto arrange = [&perm, &g](const vector<Player>& players,
|
||||||
|
const vector<vector<Point>>& capitals,
|
||||||
|
vector<Player>& rest) {
|
||||||
|
vector<Point> 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 < C.size(); j++)
|
||||||
|
rest.push_back(players[C[j]]);
|
||||||
|
for (size_t j = 0; j < min(C.size(), D.size()); j++) {
|
||||||
|
g.at(caps[D[j]].x, caps[D[j]].y).type = TileType::Capital;
|
||||||
|
g.at(caps[D[j]].x, caps[D[j]].y).owner = players[C[j]];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<vector<Player>> 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<Player> rest1;
|
||||||
|
for (size_t i = B.size(); i < A.size(); i++) {
|
||||||
|
for (auto id : players[A[i]])
|
||||||
|
rest1.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < min(A.size(), B.size()); i++)
|
||||||
|
arrange(players[A[i]], capitals[B[i]], rest1);
|
||||||
|
|
||||||
|
vector<Player> rest2;
|
||||||
|
arrange(rest1, capitals.back(), rest2);
|
||||||
|
int T = 5;
|
||||||
|
|
||||||
|
while (T--) {
|
||||||
|
vector<vector<VertexType>> vertex_type(h
|
||||||
|
, vector<VertexType>(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)
|
||||||
|
vertex_type[i][j] = VertexType::Mountain;
|
||||||
|
if (g.at(i, j).type == TileType::Capital)
|
||||||
|
vertex_type[i][j] = VertexType::Capital;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pr = generateCapital(w, h, vertex_type, rest2.size());
|
||||||
|
if (!pr.first)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < rest2.size(); i++) {
|
||||||
|
g.at(pr.second[i].x, pr.second[i].y).type = TileType::Capital;
|
||||||
|
g.at(pr.second[i].x, pr.second[i].y).owner = rest2[i];
|
||||||
|
}
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw BadCapitalAssign();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImportedTerrain importTerrain(const ImportTerrainConfig& in) {
|
||||||
|
ImportedTerrain t;
|
||||||
|
t.w = in.w;
|
||||||
|
t.h = in.h;
|
||||||
|
t.tiles.resize(t.h, vector<ImportedTerrain::TerrainTile>(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])))
|
||||||
|
error();
|
||||||
|
|
||||||
|
std::int32_t x = 0;
|
||||||
|
while (pt < in.value.size() && isdigit(in.value[pt])) {
|
||||||
|
x = x * 10 + (in.value[pt] ^ '0');
|
||||||
|
if (x > 99999)
|
||||||
|
error();
|
||||||
|
pt++;
|
||||||
|
}
|
||||||
|
if (neg)
|
||||||
|
x = -x;
|
||||||
|
if (x < l || x > r)
|
||||||
|
error();
|
||||||
|
return x;
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<vector<vector<Point>>> vec(27, vector<vector<Point>>(101));
|
||||||
|
for (pos_t i = 0; i < t.h; i++) {
|
||||||
|
for (pos_t j = 0; j < t.w; j++) {
|
||||||
|
auto& p = t.tiles[i][j];
|
||||||
|
if (view(' '))
|
||||||
|
p.type = TileType::Blank;
|
||||||
|
else if (view('m'))
|
||||||
|
p.type = TileType::Mountain;
|
||||||
|
else if (view('n')) {
|
||||||
|
p.type = TileType::Blank;
|
||||||
|
p.unit = read();
|
||||||
|
} else if (view('s'))
|
||||||
|
p.type = TileType::Swamp;
|
||||||
|
else if (view('g')) {
|
||||||
|
p.type = TileType::Blank;
|
||||||
|
bool tag = 1;
|
||||||
|
int team = (pt < in.value.size() && isupper(in.value[pt])
|
||||||
|
? in.value[pt++] - 'A'
|
||||||
|
: (tag = view(' '), 26));
|
||||||
|
|
||||||
|
int priority
|
||||||
|
= (tag && pt < in.value.size() && isdigit(in.value[pt])
|
||||||
|
? read(1, 99)
|
||||||
|
: 100);
|
||||||
|
vec[team][priority].emplace_back(i, j);
|
||||||
|
} else {
|
||||||
|
p.type = TileType::Stronghold;
|
||||||
|
p.unit = read();
|
||||||
|
}
|
||||||
|
if (i + 1 < t.h || j + 1 < t.w)
|
||||||
|
jump(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pt != in.value.size())
|
||||||
|
error();
|
||||||
|
t.capitals.emplace_back();
|
||||||
|
|
||||||
|
for (int i = 0; i <= 26; i++) {
|
||||||
|
for (int j = 100; j >= 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;
|
||||||
}
|
}
|
@ -1,42 +1,45 @@
|
|||||||
#ifndef OGLG_TERRAIN_H_
|
#ifndef OGLG_TERRAIN_H_
|
||||||
#define OGLG_TERRAIN_H_
|
#define OGLG_TERRAIN_H_
|
||||||
|
|
||||||
#include "pc/Point.h"
|
|
||||||
#include "pc/pctypes.h"
|
|
||||||
#include "pc/commcode.h"
|
|
||||||
#include "logic/GameBoard.h"
|
#include "logic/GameBoard.h"
|
||||||
#include <vector>
|
#include "pc/Point.h"
|
||||||
|
#include "pc/commcode.h"
|
||||||
|
#include "pc/pctypes.h"
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class BadImportTerrainConfig:std::exception{
|
class BadImportTerrainConfig : std::exception {
|
||||||
public:
|
public:
|
||||||
BadImportTerrainConfig(size_t);
|
BadImportTerrainConfig(size_t);
|
||||||
~BadImportTerrainConfig()=default;
|
virtual ~BadImportTerrainConfig() = default;
|
||||||
const char* what() const noexcept;
|
virtual const char* what() const noexcept override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t pt;
|
size_t pt;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BadCapitalAssign:std::exception{
|
class BadCapitalAssign : std::exception {
|
||||||
public:
|
public:
|
||||||
~BadCapitalAssign()=default;
|
virtual ~BadCapitalAssign() = default;
|
||||||
const char* what() const noexcept;
|
virtual const char* what() const noexcept override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImportedTerrain{
|
class ImportedTerrain {
|
||||||
public:
|
public:
|
||||||
friend ImportedTerrain importTerrain(const ImportTerrainConfig &in);
|
friend ImportedTerrain importTerrain(const ImportTerrainConfig& in);
|
||||||
GameBoard makeGameBoard(const InitInfo &init_info);
|
GameBoard makeGameBoard(const InitInfo& init_info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TerrainTile{
|
struct TerrainTile {
|
||||||
TileType type;
|
TileType type;
|
||||||
std::int32_t unit;
|
std::int32_t unit;
|
||||||
};
|
};
|
||||||
pos_t w,h;
|
pos_t w, h;
|
||||||
std::vector<std::vector<TerrainTile>> tiles;
|
std::vector<std::vector<TerrainTile>> tiles;
|
||||||
std::vector<std::vector<std::vector<Point>>> capitals;
|
std::vector<std::vector<std::vector<Point>>> capitals;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImportedTerrain importTerrain(const ImportTerrainConfig &in);
|
ImportedTerrain importTerrain(const ImportTerrainConfig& in);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user