Digging invaders: improved edge cost evaluation.

develop
expwnent 2013-01-04 18:11:38 -05:00
parent 2ca943ae20
commit fd05d30733
4 changed files with 122 additions and 9 deletions

@ -50,7 +50,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
pt1 = pt2; pt1 = pt2;
pt2 = temp; pt2 = temp;
} }
//out.print("first important edge: (%d,%d,%d) -> (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z); out.print("first important edge: (%d,%d,%d) -> (%d,%d,%d)\n", pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z);
int32_t jobId = -1; int32_t jobId = -1;
@ -59,6 +59,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
bool passable1 = block1->walkable[pt1.x&0x0F][pt1.y&0x0F]; bool passable1 = block1->walkable[pt1.x&0x0F][pt1.y&0x0F];
bool passable2 = block2->walkable[pt2.x&0x0F][pt2.y&0x0F]; bool passable2 = block2->walkable[pt2.x&0x0F][pt2.y&0x0F];
df::coord location;
df::building* building = Buildings::findAtTile(pt2); df::building* building = Buildings::findAtTile(pt2);
df::coord buildingPos = pt2; df::coord buildingPos = pt2;
if ( pt1.z > pt2.z ) { if ( pt1.z > pt2.z ) {
@ -84,6 +85,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
firstInvader->path.path.y.clear(); firstInvader->path.path.y.clear();
firstInvader->path.path.z.clear(); firstInvader->path.path.z.clear();
firstInvader->path.dest = destroyFrom; firstInvader->path.dest = destroyFrom;
location = destroyFrom;
firstInvader->job.hunt_target = NULL; firstInvader->job.hunt_target = NULL;
firstInvader->job.destroy_target = NULL; firstInvader->job.destroy_target = NULL;
@ -110,6 +112,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
firstInvader->path.path.y.clear(); firstInvader->path.path.y.clear();
firstInvader->path.path.z.clear(); firstInvader->path.path.z.clear();
firstInvader->path.dest = pt1; firstInvader->path.dest = pt1;
location = pt1;
firstInvader->job.hunt_target = NULL; firstInvader->job.hunt_target = NULL;
firstInvader->job.destroy_target = NULL; firstInvader->job.destroy_target = NULL;
Job::linkIntoWorld(job); Job::linkIntoWorld(job);
@ -123,18 +126,22 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
job->job_type = df::enums::job_type::CarveUpDownStaircase; job->job_type = df::enums::job_type::CarveUpDownStaircase;
job->pos = pt2; job->pos = pt2;
firstInvader->path.dest = pt2; firstInvader->path.dest = pt2;
location = pt2;
} else if ( up && !down ) { } else if ( up && !down ) {
job->job_type = df::enums::job_type::CarveUpwardStaircase; job->job_type = df::enums::job_type::CarveUpwardStaircase;
job->pos = pt2; job->pos = pt2;
firstInvader->path.dest = pt2; firstInvader->path.dest = pt2;
location = pt2;
} else if ( !up && down ) { } else if ( !up && down ) {
job->job_type = df::enums::job_type::CarveDownwardStaircase; job->job_type = df::enums::job_type::CarveDownwardStaircase;
job->pos = pt2; job->pos = pt2;
firstInvader->path.dest = pt2; firstInvader->path.dest = pt2;
location = pt2;
} else { } else {
job->job_type = df::enums::job_type::Dig; job->job_type = df::enums::job_type::Dig;
job->pos = pt2; job->pos = pt2;
firstInvader->path.dest = pt1; firstInvader->path.dest = pt1;
location = pt1;
} }
df::general_ref_unit_workerst* ref = new df::general_ref_unit_workerst; df::general_ref_unit_workerst* ref = new df::general_ref_unit_workerst;
ref->unit_id = firstInvader->id; ref->unit_id = firstInvader->id;
@ -206,5 +213,21 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
Items::moveToInventory(cache, pick, firstInvader, df::unit_inventory_item::T_mode::Weapon, part); Items::moveToInventory(cache, pick, firstInvader, df::unit_inventory_item::T_mode::Weapon, part);
} }
} }
#if 0
//tell EVERYONE to move there
for ( size_t a = 0; a < invaders.size(); a++ ) {
df::unit* invader = invaders[a];
invader->path.path.x.clear();
invader->path.path.y.clear();
invader->path.path.z.clear();
invader->path.dest = location;
//invader->flags1.bits.invades = true;
//invader->flags1.bits.marauder = true;
//invader->flags2.bits.visitor_uninvited = true;
invader->relations.group_leader_id = invader->id;
}
#endif
return firstInvader->id; return firstInvader->id;
} }

@ -266,9 +266,9 @@ command_result diggingInvadersFunc(color_ostream& out, std::vector<std::string>&
} }
int32_t findAndAssignInvasionJob(color_ostream& out) { int32_t findAndAssignInvasionJob(color_ostream& out) {
//returns the job id created //returns the worker id of the job created
CoreSuspender suspend; //CoreSuspender suspend;
unordered_set<df::coord, PointHash> invaderPts; unordered_set<df::coord, PointHash> invaderPts;
unordered_set<df::coord, PointHash> localPts; unordered_set<df::coord, PointHash> localPts;
@ -284,10 +284,8 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
MapExtras::MapCache cache; MapExtras::MapCache cache;
vector<df::unit*> invaders; vector<df::unit*> invaders;
unordered_set<uint16_t> invaderConnectivity; unordered_set<uint16_t> invaderConnectivity;
unordered_set<uint16_t> localConnectivity; unordered_set<uint16_t> localConnectivity;
//TODO: look for invaders with buildingdestroyer:3
//find all locals and invaders //find all locals and invaders
for ( size_t a = 0; a < df::global::world->units.active.size(); a++ ) { for ( size_t a = 0; a < df::global::world->units.active.size(); a++ ) {
@ -340,6 +338,7 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
unordered_set<df::coord,PointHash> closedSet; unordered_set<df::coord,PointHash> closedSet;
unordered_map<df::coord,int32_t,PointHash> workNeeded; //non-walking work needed to get there unordered_map<df::coord,int32_t,PointHash> workNeeded; //non-walking work needed to get there
bool foundTarget = false; bool foundTarget = false;
int32_t edgeCount = 0;
clock_t t0 = clock(); clock_t t0 = clock();
clock_t totalEdgeTime = 0; clock_t totalEdgeTime = 0;
@ -371,6 +370,9 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
totalEdgeTime += (clock() - edgeTime); totalEdgeTime += (clock() - edgeTime);
for ( auto a = myEdges->begin(); a != myEdges->end(); a++ ) { for ( auto a = myEdges->begin(); a != myEdges->end(); a++ ) {
Edge &e = *a; Edge &e = *a;
if ( e.p1 == df::coord() )
break;
edgeCount++;
df::coord& other = e.p1; df::coord& other = e.p1;
if ( other == pt ) if ( other == pt )
other = e.p2; other = e.p2;
@ -392,7 +394,7 @@ int32_t findAndAssignInvasionJob(color_ostream& out) {
delete myEdges; delete myEdges;
} }
clock_t time = clock() - t0; clock_t time = clock() - t0;
//out.print("time = %d, totalEdgeTime = %d\n", time, totalEdgeTime); out.print("time = %d, totalEdgeTime = %d, total points = %d, total edges = %d, time per point = %.3f, time per edge = %.3f\n", time, totalEdgeTime, closedSet.size(), edgeCount, (float)time / closedSet.size(), (float)time / edgeCount);
if ( !foundTarget ) if ( !foundTarget )
return -1; return -1;

@ -12,15 +12,94 @@
#include "df/tiletype_material.h" #include "df/tiletype_material.h"
#include "df/tiletype_shape.h" #include "df/tiletype_shape.h"
#include <iostream>
using namespace std; using namespace std;
int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) { int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) {
int32_t dx = pt2.x - pt1.x;
int32_t dy = pt2.y - pt1.y;
int32_t dz = pt2.z - pt1.z;
int64_t cost = costWeight[CostDimension::Distance];
if ( Maps::canStepBetween(pt1, pt2) ) {
return cost;
}
if ( Maps::getTileBlock(pt2) == NULL )
return -1;
df::tiletype* type2 = Maps::getTileType(pt2);
df::tiletype_shape shape2 = ENUM_ATTR(tiletype, shape, *type2);
if ( shape2 == df::enums::tiletype_shape::EMPTY ) {
return -1;
}
if ( shape2 == df::enums::tiletype_shape::TREE )
return -1;
df::building* building2 = Buildings::findAtTile(pt2);
if ( building2 )
cost += costWeight[CostDimension::DestroyBuilding];
bool construction2 = ENUM_ATTR(tiletype, material, *type2) == df::enums::tiletype_material::CONSTRUCTION;
if ( construction2 )
cost += costWeight[CostDimension::DestroyConstruction];
if ( dz == 0 ) {
if ( !building2 && !construction2 ) {
//it has to be a wall
if ( shape2 != df::enums::tiletype_shape::WALL ) {
//out << "shape = " << (int32_t)shape2 << endl;
//out << __FILE__ << ", line " << __LINE__ << ": WTF?" << endl;
return cost;
}
cost += costWeight[CostDimension::Dig];
}
} else {
if ( dx == 0 && dy == 0 ) {
if ( dz > 0 ) {
bool passable_low2 = ENUM_ATTR(tiletype_shape, passable_low, shape2);
if ( !passable_low2 ) {
if ( building2 || construction2 )
return -1;
cost += costWeight[CostDimension::Dig];
}
} else {
bool passable_high2 = ENUM_ATTR(tiletype_shape, passable_high, shape2);
if ( !passable_high2 ) {
if ( building2 || construction2 )
return -1;
if ( shape2 != df::enums::tiletype_shape::WALL )
return -1;
cost += costWeight[CostDimension::Dig];
}
}
} else {
//nonvertical
//out.print("%s, line %d: (%d,%d,%d)->(%d,%d,%d)\n", __FILE__, __LINE__, pt1.x,pt1.y,pt1.z, pt2.x,pt2.y,pt2.z);
return -1;
}
}
return cost;
}
int64_t getEdgeCostOld(color_ostream& out, df::coord pt1, df::coord pt2) {
//first, list all the facts //first, list all the facts
int32_t dx = pt2.x - pt1.x; int32_t dx = pt2.x - pt1.x;
int32_t dy = pt2.y - pt1.y; int32_t dy = pt2.y - pt1.y;
int32_t dz = pt2.z - pt1.z; int32_t dz = pt2.z - pt1.z;
int64_t cost = costWeight[CostDimension::Distance]; int64_t cost = costWeight[CostDimension::Distance];
if ( false ) {
if ( Maps::canStepBetween(pt1,pt2) )
return cost;
return 100 + cost;
}
Maps::ensureTileBlock(pt1); Maps::ensureTileBlock(pt1);
Maps::ensureTileBlock(pt2); Maps::ensureTileBlock(pt2);
df::tiletype* type1 = Maps::getTileType(pt1); df::tiletype* type1 = Maps::getTileType(pt1);
@ -142,9 +221,10 @@ int64_t getEdgeCost(color_ostream& out, df::coord pt1, df::coord pt2) {
} }
vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int32_t xMax, int32_t yMax, int32_t zMax) { vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCache& cache, int32_t xMax, int32_t yMax, int32_t zMax) {
vector<Edge>* result = new vector<Edge>; vector<Edge>* result = new vector<Edge>(26);
result->reserve(26); //result->reserve(26);
size_t count = 0;
for ( int32_t dx = -1; dx <= 1; dx++ ) { for ( int32_t dx = -1; dx <= 1; dx++ ) {
for ( int32_t dy = -1; dy <= 1; dy++ ) { for ( int32_t dy = -1; dy <= 1; dy++ ) {
for ( int32_t dz = -1; dz <= 1; dz++ ) { for ( int32_t dz = -1; dz <= 1; dz++ ) {
@ -159,7 +239,9 @@ vector<Edge>* getEdgeSet(color_ostream &out, df::coord point, MapExtras::MapCach
if ( cost == -1 ) if ( cost == -1 )
continue; continue;
Edge edge(point, neighbor, cost); Edge edge(point, neighbor, cost);
result->push_back(edge); //result->push_back(edge);
(*result)[count] = edge;
count++;
} }
} }
} }

@ -38,6 +38,12 @@ public:
df::coord p1; df::coord p1;
df::coord p2; df::coord p2;
int64_t cost; int64_t cost;
Edge() {
cost = -1;
}
Edge(const Edge& e): p1(e.p1), p2(e.p2), cost(e.cost) {
}
Edge(df::coord p1In, df::coord p2In, int64_t costIn): cost(costIn) { Edge(df::coord p1In, df::coord p2In, int64_t costIn): cost(costIn) {
if ( p2In < p1In ) { if ( p2In < p1In ) {
p1 = p2In; p1 = p2In;