我想出一个好头衔有点问题,但我现在要解释一下。
我正在建立一个在线游戏。我试图建立销毁武器的选择。
我有4种武器 - 攻击,防御,巡逻和间谍。 巡逻和间谍武器有3级武器,攻击和防御有15级。我有一个表格,每个类别都有col。命名为w1,w2,w3,w4 ......和用户的ID。
我给出了每个等级点,所以w15例如值15分,w2值2分,我建立了一个函数来计算攻击者摧毁了多少分给防守者。
我被困的地方是如何随机挑选武器?
让我们说攻击者摧毁了100点武器。所以它可以是100种巡逻等级1的武器,或者25种武器,每种类别1种,或10种武器,排名10。 我需要在类别(攻击,防御,巡逻和间谍)之间以及武器(w1,w2,w3 ..)之间随机进行。另外我需要它在防守者拥有的武器数量的极限,他不能失去更多的武器。
非常感谢!!我知道我写了一个很长的问题
答案 0 :(得分:2)
首先UNION这样你的四张桌子
SELECT * FROM (
SELECT * FROM w1
UNION
SELECT * FROM w2
UNION
SELECT * FROM w3
UNION
SELECT * FROM w4
)
然后计算你的体重 - 并随机选择
... ORDER BY RAND() LIMIT 5;
答案 1 :(得分:2)
// randomly picks a number between 1 and 4
$randomWeapon = rand(1,4);
// Creates for ex. SELECT * FROM w1
$selectWeapon = mysqli($con, "SELECT * FROM w$randomWeapon"
答案 2 :(得分:1)
根据我的其他提示,这是一个应该可以解决问题的解决方案。
基本上你首先用他们的用户权重随机化所有的waepons。如果您在此处有NULL
个值,则应取消选择它们。 LIMIT
之后的巨大ORDER BY RAND()
是必要的,因为我发现如果你没有在这里指定LIMIT
,MySQL Optimizer将删除随机化。只要把它变得比整个桌子都要大。
其次,你用一个运行变量连续计算武器重量。
第三,你从整个连续列表中选择造成的伤害量。如果所需的伤害不完全匹配,您应该将其调整到一系列生命值。
-- 3. limit your sum to hitpoints
SELECT * FROM (
-- 2. now sum weaponWeight
SELECT weaponWeight, @prevWeight, @prevWeight:= weaponWeight + @prevWeight as cumulSum
FROM (
-- 1. shuffle all waepons of a user to do the random pick
SELECT weaponWeight FROM
(
-- attack
SELECT w1 as weaponWeight FROM attack WHERE ID = 'myUserID'
UNION
SELECT w2 as weaponWeight FROM attack WHERE ID = 'myUserID'
UNION
...
UNION
SELECT w15 as weaponWeight FROM attack WHERE ID = 'myUserID'
-- defence
UNION
SELECT w1 as weaponWeight FROM defence WHERE ID = 'myUserID'
UNION
...
UNION
SELECT w15 as weaponWeight FROM defence WHERE ID = 'myUserID'
-- patrol
UNION
SELECT w1 as weaponWeight FROM patrol WHERE ID = 'myUserID'
UNION
SELECT w2 as weaponWeight FROM patrol WHERE ID = 'myUserID'
UNION
SELECT w3 as weaponWeight FROM patrol WHERE ID = 'myUserID'
-- spy
UNION
SELECT w1 as weaponWeight FROM spy WHERE ID = 'myUserID'
UNION
SELECT w2 as weaponWeight FROM spy WHERE ID = 'myUserID'
UNION
SELECT w3 as weaponWeight FROM spy WHERE ID = 'myUserID'
)
ORDER BY RAND()
LIMIT 1000000000000 -- huge number here because Optimizer will remove random order otherwise
) as randomizedData,
(SELECT @prevWeight := 0) as a
) as sums
WHERE round(sums.cumulSum) = 100
答案 3 :(得分:1)
我认为这更像是一个逻辑问题而不是处理表格的技术问题。如果您先处理逻辑,那么您可以轻松地在桌面上执行所需的操作。我们只需要知道随机选择将使用(销毁)每个项目的数量。这是一个随机选择方法部分sudo-code / part php:
1. Query database for available items and their relative values.
2. Store information as a multi-dimensional Array
3. Shuffle the Array
//in php
bool shuffle ( array $itemsArray() )
4. Iterate through each item in the array and add 1
to a variable for that item if, we have not reached our
limiting factors (amount available and cost vs remaining points).
Do this until all available points are allotted to a variable.
//in php
$i = 0;
do {
if ($itemsArray[$i][numAvail] > 0 &&
($availiblePoints - $itemsArray[$i][cost] >= $itemsArray[$i][cost]){
$$itemsArray[$i]++
//use of '$$' for variable variable
$availiblePoints-=$itemsArray[$i][cost];
}
else {
countSkips++
//need to keep track of how many items we skip
//if $availiblePoints is not zero yet but skips is size of array then
//we are done and have leftover points that cant be used.
}
$i++;
if ($i > count($itemsArray)) { $i=0; };
//start over if we have gone past the end of our Array
} while ($availiblePoints > 0 && $countSkips < count($itemsArray) );
5. Logic Done. Now use the new variables to perform action on tables
因为数组是随机洗牌的,所以无论我们有多少分数,我们的结果都是随机的。如果我们有100分,我们的随机数组中的第一项花费100分,或前4分需要25分;随机性无论如何都会完成它的工作。
这只是概念。代码可以改进一堆,例如我们保存的变量实际上应该在一个数组中,这样我们就可以在它对表执行操作时循环遍历它们。
答案 4 :(得分:0)
好的......我测试了一个表逻辑表。只需要组合(联合)你想要包含的所有东西。 (问题用php标记,所以这是一个php解决方案....)
<?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;
}
}
?>
样本输出,可以轻松重新排列。索引值是指原始的$weapons
数组索引。
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
)
)
答案 5 :(得分:0)
尝试类似:
$attackWeapon = array( /* weapon info comes here */ );
$defenseWeapon = array( /* weapon info comes here */);
$patrolWeapon = array( /* weapon info comes here */);
$spyWeapon = array( /* weapon info comes here */);
$rdmWeapon = mt_rand(1,4);
$attackLenght = count($attackWeapon);
$rdmAttackWeapon = mt_rand(0, $attackLenght-1);
$defenseLenght = count($defenseWeapon);
$rdmDefenseWeapon = mt_rand(0, $defenseLenght-1);
$patrolLenght = count($patrolWeapon);
$rdmPatrolWeapon = mt_rand(0, $patrolLenght-1);
$spyLenght = count($spyWeapon);
$rdmSpyLenght = mt_rand(0, $spyLenght-1);
If($rdmWeapon=1){
$dropWeapon = "attack";
echo $rdmAttackWeapon;
}
else if($rdmWeapon=2){
$dropWeapon = "defense";
echo $rdmDefenseWeapon;
}
else if($rdmWeapon=3){
$dropWeapon = "patrol";
echo $rdmPatrolWeapon
}
else($rdmWeapon=4){
$dropWeapon = "spy";
echo $rdmSpyWeapon;
}
这很简单,很傻,但适合我。