I'm pretty sure this will do it, not having any test data or a compiler to hand makes me not 100% confident:
private void BestItems()
{
_bestHead = GetBestItem(_heads);
_bestChest = GetBestItem(_chests);
_bestLeg = GetBestItem(_legs);
_bestFeet = GetBestItem(_feets);
}
private Stats GetBestItem(List<Stats> items)
{
double best = 0.0;
Stats result = null;
foreach stats item in items
{
double total = item.stamina * _scaleSta + item.power * _scalePower + item.armor * _scaleArmor;
if (total > best)
{
result = item;
}
}
return result;
}
Edit:
Steps:
- Create a list for each slot in order of most important stat (smallest first)
- Loop through using some kind of weighting to find the smallest values of hit that satisfy your hit rating. (yuo will need this per slot for my next step)
- For each slot pick item with best stats that meets that slots min-hit rating.
you will need a lot of loops one after the other, but its better than 2^28 i think :p
Edit2: Again, still no compiler here... but this might work. You will end up with a bucket load of threads though...
For thread joining and waiting see here (msdn) (look at mutex, monitor, ManualResetEvent, AutoResetEvent)
private void BruteForce()
{
var threads = new List<Thread>;
foreach (Stats head in _heads)
foreach (Stats chest in _chests)
foreach (Stats leg in _legs)
foreach (Stats feet in _feets)
{
if (threads.Count <= 2)
thread worker = new thread(addressof Process, new object() {head, chest, leg, feet, ...});
worker.start();
threads.add(worker);
}
foreach (Thread t in threads)
t.join(); //this might not be the best as it might make the main thread wait for each thread one after the other, not when all finished. A manual/auto reset is probably better here.
}
private void Process(params...)
{
int stamina = head.sta + chest.sta + leg.sta + feet.sta;
int power = head.power + chest.power + leg.power + feet.power;
int armor = head.armor + chest.armor + leg.armor + feet.armor;
int hit = head.hit + chest.hit + leg.hit + feet.hit;
double total = stamina * _scaleSta + power * _scalePower + armor * _scaleArmor;
lock _bestscore
{
if (total > _bestScore && hit >= 100)
{
_bestScore = total;
// Store best setup for output when done with bruteforce
_bestHead = head;
_bestChest = chest;
_bestLeg = leg;
_bestFeet = feet;
}
}
}
EDIT 4: Guess who still doesnt have a compiler near him?
Something along the lines of this should make sure you only have 2 threads alive at any point.
var threads = new Dictionary<Guid, Thread>;
private void BruteForce()
{
foreach (Stats head in _heads)
foreach (Stats chest in _chests)
foreach (Stats leg in _legs)
foreach (Stats feet in _feets)
{
while (threads.Count >= 2) {} //im sure thread.join or equivelent can do this instead of a nasty loop :p
var guid = Guid.NewGuid();
thread worker = new thread(addressof Process, new object() {guid, head, chest, leg, feet, ...});
worker.start();
threads.add(guid, worker);
}
foreach (Thread t in threads)
t.join(); //this might not be the best as it might make the main thread wait for each thread one after the other, not when all finished. A manual/auto reset is probably better here.
}
private void Process(params...)
{
int stamina = head.sta + chest.sta + leg.sta + feet.sta;
int power = head.power + chest.power + leg.power + feet.power;
int armor = head.armor + chest.armor + leg.armor + feet.armor;
int hit = head.hit + chest.hit + leg.hit + feet.hit;
double total = stamina * _scaleSta + power * _scalePower + armor * _scaleArmor;
lock _bestscore
{
if (total > _bestScore && hit >= 100)
{
_bestScore = total;
// Store best setup for output when done with bruteforce
_bestHead = head;
_bestChest = chest;
_bestLeg = leg;
_bestFeet = feet;
}
}
_threads.remove(guid)
}