Follow-up
http://www.bay12forums.com/smf/index.php?topic=66525.msg3773408#msg3773408Here's me loading up roles into DT via a csv file... (csv file consists of these entries role_name, labor_id, priority_weight, num_to_assign)
void MainWindow::initializeSuperStruct()
{
QList<Dwarf*> m_selected_dwarfs = m_view_manager->get_selected_dwarfs();
int d_count = m_selected_dwarfs.size();
//get labors per dwarf
bool ok;
QString labors_p = QInputDialog::getText(0, tr("Labors per dwarf"),
tr("How many dwarves do you want to assign per labor?"), QLineEdit::Normal,"", &ok);
if (!ok)
return;
int labors_per = labors_p.toInt();
//get csv filename
ok = 0;
QString file_name = QInputDialog::getText(0, tr("CSV input file"),
tr("Name of input file for assigning labors?"), QLineEdit::Normal,"", &ok);
if (!ok)
return;
//int file_name = csv_n.toInt();
using namespace std;
//dwarf count, to be pulled from selection
//labor count, to be pulled from init .csv
int role_count = 0;
//does not work
string st;
//SUPERSTRUCT!
QVector <superStruct> sorter;
QVector <roles> ListOfRolesV;
//ifstream f( filename.c_str() );
//ifstream f("role_labor_list.csv");
string f_holder = file_name.toStdString();
ifstream f(f_holder.c_str());
//ifstream f (file_name.c_str());
//loops through each line in the file
while (getline (f, st))
{
int pos = 1;
//placeholder
roles p_holder;
//gets the line for processing
istringstream iss( st );
//loops through each , in one line
while (getline (iss, st, ','))
{
//role_name, labor_id, priority_weight, num_to_assign
if (pos == 1)
{
p_holder.role_name = QString::fromStdString(st);
}
else if (pos == 2)
{
int fieldValue = 0;
istringstream (st) >> fieldValue;
p_holder.labor_id = fieldValue;
}
else if (pos == 3)
{
float fieldValue = 0.0f;
istringstream (st) >> fieldValue;
p_holder.priority = fieldValue;
}
else if (pos == 4)
{
int fieldValue = 0;
istringstream (st) >> fieldValue;
p_holder.numberToAssign = fieldValue;
}
p_holder.numberAssigned = 0;
pos++;
}
ListOfRolesV.push_back(p_holder);
pos = 1;
}
f.close();
role_count = ListOfRolesV.size();
//now time to initialize the superStruct
//count # dwarf's
//foreach(Dwarf *d, m_view_manager->get_selected_dwarfs()) {d_count++;}
//resize based on # dwarfs * # of roles
sorter.resize(d_count*role_count);
QString *temp;
int sstruct_pos = 0;
//for(int sstruct_pos = 0; sstruct_pos < sorter.size(); sstruct_pos++)
{
//cycle through each Dwarf,
foreach (Dwarf *d, m_view_manager->get_selected_dwarfs())
{
int dwarf_count = 0;
//cycle through each Role in ListOfRolesV
for (int role_entry = 0; role_entry < ListOfRolesV.size(); role_entry++)
{
//problem here... need a role per dwarf which I have, but Dwarf doesn't have anywhere to save a w_percent...
//Could just load into superStruct, but it won't be a pointer...
sorter[sstruct_pos].d_id = d->id();
sorter[sstruct_pos].labor_id = ListOfRolesV[role_entry].p_l_id();
//QString role_name = ListOfRolesV[role_entry].p_r_name();
//not sure if this is what I want
sorter[sstruct_pos].role_name = ListOfRolesV[role_entry].p_r_name();
//can't use pointers with this
sorter[sstruct_pos].r_percent = d->get_role_rating(ListOfRolesV[role_entry].role_name);
sorter[sstruct_pos].w_percent = ListOfRolesV[role_entry].priority * d->get_role_rating(ListOfRolesV[role_entry].role_name);
sstruct_pos++;
}
//probably not needed
dwarf_count ++;
}
}
//used for debug pause
int test = 0;
//sort superstruct by w_percent
//runs through list
for (int i = 0; i < sorter.size(); i++)
{
//checks against lower element
//cout << *s->at(i).pPercent << endl;
for (int j = 1; j < (sorter.size()-i); j++)
{
//using pointer dereferences messed this up, but, not using them doesn't sort right
if (sorter[j-1].w_percent < sorter[j].w_percent)
{
swap(sorter[j-1], sorter[j]);
}
}
}
//now to assign labors!
//vs running through each labor, and assigning up to max # dwarf's...
//1. need to start from top of allRoles
//2. see what labor is, see if goal is met.
//DONE (via csv input) for DEPLOY APP, need to change this to see if labor is asked for
//3. Y - Skip (use while statement)
//4. N -
//a. Check Dwarf to see if he is available (again, while Statement),
//not available if has conflicting labor
// Y - Assign
// N - Skip
//start from top of list.
for (int sPos = 0; sPos < sorter.size(); sPos++)
{
//dwarf position (used for searching of name)
//I would like to set these to pointers, but I was getting out of bound issues...
int dPos = 0;
//role position
int rPos = 0;
//cycle through each dwarf? I should, but, I can use the *s->at(x).name to find the Dwarf #
//no, need to compare roleName to dwarfName
//search for Dwarf (y) for that role
for (int d = 0; d < d_count; d++)
{
//dPos is never getting updated.
//int temp = d->id();
if (sorter[sPos].d_id == m_selected_dwarfs.at(d)->id())
{
dPos = d;
//break;
};
//dPos++;
}
//match superStruct roleName to myRoles name position (to check if filled up)
for (int r = 0; r < ListOfRolesV.size(); r++)
{
if (sorter[r].role_name == ListOfRolesV[r].role_name)
{
rPos = r;
//break;
};
};
//search if role @ rPos is filled up
//role check started...
if (ListOfRolesV[rPos].numberAssigned < *ListOfRolesV[rPos].n_assign())
{
//need to compare to total_assigned_labors,
//this will be used for Custom Professions
int currentAssigned = m_selected_dwarfs.at(dPos)->total_assigned_labors();
//is Dwarf (d) laborsAssigned full? Used in proto-type
if (currentAssigned < labors_per)
{
//another check to check for conflicting laborid's,
//AND
//to see if labor_id flag is checked in Options.
int debug = ListOfRolesV[rPos].labor_id;
//m_selected_dwarfs.at(dPos)->toggle_labor(ListOfRolesV[rPos].labor_id);
m_selected_dwarfs.at(dPos)->toggle_labor(debug);
//assign labor (z) to Dwarf @ dPos
//add labor (z?) to Dwarf's (d) labor vector
//m_selected_dwarfs.at(dPos).laborsAssigned.push_back(r->at(rPos).name);
//increase labors assigned to roles vector
//role check completed
ListOfRolesV[rPos].numberAssigned++;
}
}
}
m_model->calculate_pending();
};
If I didn't have kids, I could probably finish it tonight... but they crawl all over me likes monkeys and I'm made out of banana's...
But... I am making progress... I think by next weekend I'll have a version to post up that people can try out that will optimize labors...
I only need to do two more things to get it to work
1. Clear labors - check
2. Load roles from CSV - check
3. Load dwarf values into superStruct & sort by weighted_percent - started... the dwarf ID is loaded at the moment...
4. Assign Labors by going through superStruct weighted_percent descending...
btw, loading all your libraries/ide onto an ssd, and building on a ramdrive SERIOUSLY decreases the build time of DT. I can go to the bathroom and rebuild all vs waiting 15-20 minutes.
Update:
step 3 looks like it's completely loaded
46 roles were completely loaded, and my superstruct was completely setup for a ton of dwarfs and all values were present, there was a minor bug I fixed in a loop operation where it skipped the first role, but that was fixed
Just need to sort by w_percent, and then optimize the labors! I'll have to have a flag to check for the Miner, Ambusher/Hunter, Woodcutter labors, but that should be REALLY easy since I only have to do simple checks for laborID's
there is a good chance this will be completed this weekend!
Update:
I don't have much time this morning before my Pathfinder game, but... I was able to ask the player for how many labors per dwarf once he clicks optimize, as well as the name of the .csv input file (that contains all the roles, labors, priority, number to assign per labor).
Maybe before I leave, I can get it to sort...
Update:
fyi, if you've been following the spreadsheet version... this actually does some things that the spreadsheet can't, such as sort by role % vs sort by roles.
Example... before, each labor was assigned as such
x = labor colum
y = dwarf row
role % (z) = x,y
labors were assigned by x column, picking top num per role
now...
labors are assigned by
z = x,y position
so now assignments are assigned by z vs x
so all role %'s are sorted, and then the matching x,y is looked up, and assign up to number of dwarfs per x, and number of labors per y.
Update:
I'm kind of stuck right now... Splinterz says I shouldn't bother with pointers... but even the dwarf object is a pointer in most things, and that's an issue as well.
So... have to work through this, but I'm on the labor optimization. Chances are, I'll still have it done this weekend. Going to sleep, I sent him a notice on it, I only had about an hour to work on this today.
Update:
I've finished the coding, now to debugging...having weird problems...
labor 11 maps to carpentry and not farming... I know it does because I hard coded 11 into QT creator and it still enables carpentry, but 12 is stone detailing (i.e. engraving), yet, that one matches the script editor's labor_id map...
and not just that... it's not assigning all my labors right... I think it's a loop issue, but... making progress.
Update: updated code posted...
Here's a link to the updated code (not working correctly!) but you can see where I'm going with this
http://www.mediafire.com/?46zx8x6tt8ennb7AND SUCCESS!
http://tinypic.com/m/fvwz86/4So... the problems were.
I had an rPos not getting updated correctly due to a wrong counter variable.
and my labor_id's were off because I was using skill_id's.
fixed, now all I have to do is implement the Miner, Hunter, Woodcutter check, and it's ready!
Update:
it's not respecting labor per dwarf, will have to get back to that this eve
Update:
IT WORKS NOW!
So far what it does
is clear currently assigned labors
assign labors based on a role that maps to a labor_id (specified by the user).
currently does not support custom professions.
Here it is!
http://www.mediafire.com/?9wwp1xo6ws9ls5hsource
http://www.mediafire.com/?dnnqqv9pmiin1j9 intro
http://www.youtube.com/watch?v=Hm0X6LWsNpg&feature=youtu.be