Okay... I tested with one table logical table. Just combine (union) all the things you want to include. (question is tagged with php, so this is a php solution....)
<?php
$weapons = array(
array('name'=>'knife', 'type'=>'A', 'weight'=>5),
array('name'=>'sword', 'type'=>'A', 'weight'=>6),
array('name'=>'axe', 'type'=>'A', 'weight'=>3),
array('name'=>'handgun', 'type'=>'B', 'weight'=>7),
array('name'=>'rifle', 'type'=>'B', 'weight'=>5),
array('name'=>'cannon', 'type'=>'B', 'weight'=>2),
array('name'=>'mustard gas', 'type'=>'C', 'weight'=>7),
array('name'=>'agent orange', 'type'=>'C', 'weight'=>10),
array('name'=>'lewisite', 'type'=>'C', 'weight'=>5),
array('name'=>'mind', 'type'=>'D', 'weight'=>8),
// must have at least one thing with one... for this to work.
// i can definitely work on a solution that doesn't require this
// but it would take me a minute to think about it...
array('name'=>'words', 'type'=>'D', 'weight'=>1),
array('name'=>'hands', 'type'=>'D', 'weight'=>2),
array('name'=>'silent treatment','type'=>'D', 'weight'=>5),
);
$total_destroyed = 100;
$return = get_weapons($weapons, $weapons, $total_destroyed);
print_r($return);
function get_weapons($orig_weapons, $in_weapons, $n) {
// filter for only weapons w/ weight less than $n
$in_weapons = array_filter($in_weapons,
array(new LowerThanFilter($n),
'isLowerOrEq'));
$return = array();
if ($n > 0) {
if (empty($in_weapons)) {
$return = get_weapons($orig_weapons, $orig_weapons, $n);
}
else {
$found_it = array();
for ($i = 0; $i < count($in_weapons); $i++) {
$rand_index = array_rand($in_weapons);
$rand_weapon = $in_weapons[$rand_index];
if ($rand_weapon['weight'] <= $n) {
break;
}
}
$max_ct = floor($n/$rand_weapon['weight']);
$weapon_ct = rand(1,$max_ct);
$amount = $weapon_ct * $rand_weapon['weight'];
unset($in_weapons[$rand_index]);
$get_more = get_weapons($orig_weapons, $in_weapons, $n-$amount);
$return = $get_more;
$return[] = array_merge($rand_weapon, array(
'count' =>$count,
'amount'=>$amount));
}
}
return $return;
}
class LowerThanFilter {
// http://stackoverflow.com/a/5483168/623952
private $num;
function __construct($num) {
$this->num = $num;
}
function isLowerOrEq($i) {
return $i['weight'] <= $this->num;
}
}
?>
sample output, which can easily be re-arranged. the index value refers to the original $weapons
array index.
Array
(
[0] => Array
(
[name] => words
[type] => D
[weight] => 1
[count] => 1
[amount] => 1
)
[1] => Array
(
[name] => knife
[type] => A
[weight] => 5
[count] => 2
[amount] => 10
)
[2] => Array
(
[name] => sword
[type] => A
[weight] => 6
[count] => 1
[amount] => 6
)
[3] => Array
(
[name] => agent orange
[type] => C
[weight] => 10
[count] => 2
[amount] => 20
)
[4] => Array
(
[name] => mustard gas
[type] => C
[weight] => 7
[count] => 9
[amount] => 63
)
)