2014-10-05 88 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簡單和愚蠢的,但對我的作品。