Include the current addon, terrain integrations, tools, regression tests and recorded development evidence.
75 lines
5.7 KiB
C++
75 lines
5.7 KiB
C++
int main(){
|
|
using Rules=ERR_HQMountedInterceptRules;
|
|
ERR_HQBelief belief;Array<vector> reserved;vector a={1,2,3},b={4,5,6};float score=0,ha=0,hb=0;
|
|
vector origin={1000,10,1000},velocity={0,0,4},seed={1000,10,1300};
|
|
auto pair=[&](Array<vector> p){return Rules::PairFromPolyline(p,origin,velocity,seed,reserved,a,b,score,ha,hb);};
|
|
auto empty=[&](){assert(a==vector::Zero&&b==vector::Zero);};
|
|
// Real arc interpolation over a90-degree bend, not straight interpolation
|
|
// between the road's endpoints (which would put both escorts off the road).
|
|
assert(pair({{900,10,1300},{1000,10,1300},{1000,10,1400}}));
|
|
assert(a==vector(970,10,1300)&&b==vector(1000,10,1330));
|
|
assert(std::abs(ha-90)<.001&&std::abs(hb)<.001);
|
|
assert(vector::DistanceXZ(a,b)>42&&vector::DistanceXZ(a,b)<43);
|
|
// Arc span alone is insufficient on a bend-back/hairpin.
|
|
assert(!pair({{970,10,1300},{1000,10,1300},{1000,10,1301},{970,10,1301}}));empty();
|
|
assert(!pair({{980,10,1300},{1019.9f,10,1300}}));empty();
|
|
assert(pair({{980,10,1300},{1020,10,1300}})&&vector::DistanceXZ(a,b)==40);
|
|
// A road aligned with travel must not push a partner behind the300m floor.
|
|
assert(pair({{1000,10,1250},{1000,10,1450}}));
|
|
assert(a==vector(1000,10,1300)&&b==vector(1000,10,1360));
|
|
assert(pair({{1000,10,1450},{1000,10,1250}}));
|
|
assert(a==vector(1000,10,1300)&&b==vector(1000,10,1360));
|
|
// Actual sloped segment retains height for subsequent bridge validation.
|
|
assert(pair({{900,5,1300},{1100,15,1300}}));
|
|
assert(a==vector(970,8.5,1300)&&b==vector(1030,11.5,1300));
|
|
// Degenerate segments are harmless but a wholly degenerate road has no span.
|
|
assert(pair({{900,10,1300},{900,10,1300},{1100,10,1300}}));
|
|
assert(!pair({{1000,10,1300},{1000,10,1300}}));empty();
|
|
assert(!pair({{900,10,1300},{NAN,10,1300},{1100,10,1300}}));empty();
|
|
assert(!pair(Array<vector>(1025,{1000,10,1300})));empty();
|
|
assert(!pair({}));empty();assert(!pair({{1000,10,1300}}));empty();
|
|
auto good=Array<vector>{{900,10,1300},{1100,10,1300}};
|
|
velocity={0,0,0};assert(!pair(good));empty();velocity={0,0,4};
|
|
seed.x=NAN;assert(!pair(good));empty();seed={1000,10,1300};
|
|
origin.x=NAN;assert(!pair(good));empty();origin={1000,10,1000};
|
|
reserved={{970,10,1380}};assert(pair(good));
|
|
reserved={{970,10,1379.99f}};assert(!pair(good));empty();
|
|
reserved={{NAN,10,1380}};assert(!pair(good));empty();
|
|
reserved=Array<vector>(129,{10000,10,10000});assert(!pair(good));empty();reserved.clear();
|
|
for(float z:{1290.f,1901.f,700.f}){seed.z=z;assert(!pair({{900,10,z},{1100,10,z}}));empty();}seed.z=1300;
|
|
BaseRoad road;road.points=good;game.ai.manager.roads={&road};
|
|
int q=game.ai.manager.queries;
|
|
assert(Rules::SelectPair(&belief,10000,reserved,a,b));assert(game.ai.manager.queries==q+1);
|
|
assert(a==vector(970,10,1300)&&b==vector(1030,10,1300));
|
|
assert(ERR_SettlementSafety::calls==2&&ERR_ConvoyPlacement::calls==2);
|
|
auto select=[&](){a={1,2,3};b={4,5,6};bool ok=Rules::SelectPair(&belief,10000,reserved,a,b);if(!ok)empty();return ok;};
|
|
// Second position cannot escape settlement, water/collision or bridge checks.
|
|
int pc=ERR_ConvoyPlacement::calls;ERR_SettlementSafety::rightClear=false;assert(!select());assert(ERR_ConvoyPlacement::calls==pc);ERR_SettlementSafety::rightClear=true;
|
|
pc=ERR_ConvoyPlacement::calls;ERR_ConvoyPlacement::rightClear=false;assert(!select());assert(ERR_ConvoyPlacement::calls==pc+2);ERR_ConvoyPlacement::rightClear=true;
|
|
pc=ERR_ConvoyPlacement::calls;ERR_ConvoyPlacement::water=true;assert(!select());assert(ERR_ConvoyPlacement::calls==pc+1);ERR_ConvoyPlacement::water=false;
|
|
pc=ERR_ConvoyPlacement::calls;ERR_Actors::rightHeight=7;assert(!select());assert(ERR_ConvoyPlacement::calls==pc);ERR_Actors::rightHeight=10;
|
|
road.points={{900,20,1300},{1100,20,1300}};assert(!select());road.points=good;
|
|
// Reject a pair assembled from two short unrelated roads, even when their
|
|
// endpoints could have formed a geometrically spaced chord.
|
|
BaseRoad left,right;left.points={{960,10,1300},{980,10,1300}};right.points={{1020,10,1300},{1040,10,1300}};game.ai.manager.roads={&left,&right};assert(!select());
|
|
game.ai.manager.roads={&road};road.width=5.99;assert(!select());road.width=NAN;assert(!select());road.width=6;
|
|
// All pre-query gates remain cheap; one permitted pair call is one query.
|
|
q=game.ai.manager.queries;belief.HasVelocity=false;assert(!select());belief.HasVelocity=true;
|
|
Replication::server=false;assert(!select());Replication::server=true;
|
|
reserved.resize(129);assert(!select());reserved.clear();
|
|
assert(game.ai.manager.queries==q);
|
|
game.ai.available=false;assert(!select());game.ai.available=true;assert(game.ai.manager.queries==q);
|
|
// Road count bound refuses before any point arrays are read.
|
|
game.ai.manager.roads=Array<BaseRoad*>(129,&road);int reads=BaseRoad::reads;assert(!select());assert(BaseRoad::reads==reads);
|
|
game.ai.manager.roads=Array<BaseRoad*>(128,&road);assert(select());assert(BaseRoad::reads==reads+128);
|
|
// Total4096 segment allowance includes irrelevant/degenerate vertices; an
|
|
// earlier valid pair cannot leak through once later roads exhaust the cap.
|
|
BaseRoad big,tail;big.points=Array<vector>(1024,{900,10,1300});big.points.back()={1100,10,1300};tail.points=Array<vector>(5,{900,10,1300});tail.points.back()={1100,10,1300};
|
|
game.ai.manager.roads={&big,&big,&big,&big,&tail};assert(select());
|
|
tail.points.insert(tail.points.begin(),{900,10,1300});pc=ERR_ConvoyPlacement::calls;assert(!select());assert(ERR_ConvoyPlacement::calls==pc);
|
|
// Pair failure still permits unchanged singleton selection in a separate
|
|
// call; this explicitly consumes the caller's second survey budget.
|
|
road.points={{995,10,1300},{1005,10,1300}};game.ai.manager.roads={&road};q=game.ai.manager.queries;
|
|
assert(!select());vector singleton;assert(Rules::Select(&belief,10000,reserved,singleton));assert(singleton==vector(1000,10,1300)&&game.ai.manager.queries==q+2);
|
|
}
|