2014-10-05 119 views
6

我有一个问题想出一个好的标题,但我现在解释。从4个表中随机挑选

我正在构建一个在线游戏。我试图建立摧毁武器的选项。

我有4种武器 - 攻击,防御,巡逻和间谍。巡逻和间谍武器有3个等级的武器,攻击和防御有15个等级。

我有一个表的每个类与col。命名为w1,w2,w3,w4 ...和课程用户的ID。

我给出了每个等级分数,所以w15例如值15分,w2值2分,我建立了一个函数来计算攻击者将多少点摧毁到防御者。

我卡在哪里是如何随机挑选武器?

假设攻击者摧毁了100点武器。所以它可以是100级的巡逻兵1级,或25级武器,每级1级,或10级武器,排名第10。 我需要在类别(攻击,防御,巡逻和间谍)和武器之间随机(w1 ,W2,W3 ..)。另外我需要的是在防守者拥有的武器数量的限制下,他不能再输多少。

非常感谢!我知道我写了一个很长的问题

+3

我会考虑架构更改。为什么不用一个武器表,武器类型列与涉及不同武器类型细节的表格有关? – 2014-10-14 13:39:48

+3

你可以请一个模式和样本数据,与所需的输出? – 2014-10-14 13:59:14

+0

你有多少列w1..w15?请在sql小提琴中提供架构。 – 2014-10-14 14:19:08

回答

1

我认为这是一个逻辑问题,而不是处理表格的技术问题。如果您先处理逻辑,那么您可以轻松地在桌上执行所需的操作。我们只需要知道每个项目有多少将随机选择使用(销毁)。以下是在部分须藤码/部分的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分;随机性将以任何方式完成其工作。

这只是概念。代码可以进行一些改进,例如我们保存的变量实际上应该放在一个数组中,这样当我们在表上执行操作时,我们就可以遍历它们。

+0

谢谢!完美的作品! – OfirH 2014-10-17 08:44:56

+0

太棒了。很高兴我能够帮助你通过它来思考:) 这是一个很好的问题。 – 2014-10-24 00:06:13

2

第一联合的四个表这样

SELECT * FROM (
    SELECT * FROM w1 
    UNION 
    SELECT * FROM w2 
    UNION 
    SELECT * FROM w3 
    UNION 
    SELECT * FROM w4 
) 

然后计算出你的体重,功能,做一个随机挑选

... ORDER BY RAND() LIMIT 5; 
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" 
1

基于我的其他提示这里是一个解决方案,应该做的伎俩。

基本上,你首先随机化所有waepons与他们的权重的用户。如果你在这里有NULL值,你应该取消选择它们。 ORDER BY RAND()之后的巨大LIMIT是必要的,因为我发现如果您不指定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 
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 
     ) 

) 
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; 
    } 

It's简单和愚蠢的,但对我的作品。