简体   繁体   中英

Select random array generated from while loop

im learning PHP because i made only designs and templates, and i came to an big problem, at least for me. I am making simple "army battle script" where each player has some troops with attack, defense, hp stats, and they battle against each other. Ive made attack player vs player but i am struggling about many entity fight and how to code it. First im calling all my units sended to attack, run it trought the loop and get in array every row/unit Then i made that with enemy units, and in the end, i have a simple simulation script that makes the fight. But the fight isnt working. It doesnt select random unit from the array, it doesnt switch between attacker x defender turns and whats the worse, it only runs with one unit, when that units dies, the script ends and thats it... Can you guys please give me some answer, or way to handle this? I will be so thankfull because i am solving this for few days and i have no clue. Thanks. (i know that the code is ugly, but its just concept...)

//EDIT Ok, i turned on the error reports and change a bit the simulation code, but the results are bad. I get error Fatal error: Maximum execution time of 30 seconds exceeded in or Warning: Division by zero in php in line

  $hit = ($attacker['attack']/$defender['defense']) + rand(1, 2);

Heres the full code, ive tried rand(0,count($unit_attacker_def)-1); but i think its without changes. Also i added selecting new random array with unit, if there is 0 health and unset. And its still running trought one unit, not all in attacker array, and all, or left units in defender array. I somehow came to phase where the script calls the next unit, but it havent any variables in it loaded.

    case 'battle_wizard_execute';
                    ?>
                    <table> 
                    <tr><td><h3>Utok</h3></td></tr>
                    <?

                   $query_street = mysql_query("SELECT * FROM game_army_attacks WHERE attack_id = '".$_GET['id']."' ");
                   $row_street = mysql_fetch_assoc($query_street);

                   $query_loc_info = mysql_query("SELECT * FROM game_location_street WHERE street_id = '".$row_street['attack_attacker']."' ");
                   $row_loc_info = mysql_fetch_assoc($query_loc_info);

                   $tilee_info = mysql_num_rows($query_street);
                   if ($tilee_info > 0){ 

   $query_units_info = mysql_query("SELECT * FROM game_army_units_attacking WHERE army_attack = '".$_GET['id']."' ");
   while (($unitsinfo = mysql_fetch_assoc($query_units_info)) != NULL) {
   $query_unit_info = mysql_query("SELECT * FROM game_army_class WHERE army_class_id = '".$unitsinfo['army_class_id']."' ");
   $unit = mysql_fetch_assoc($query_unit_info);
   $unit_attacker = array();

   $unit_attacker[] = array(
        'name' => $unit['army_class_name'],
        'power' => $unitsinfo['army_power'],
        'attack' => $unitsinfo['army_att'],
        'defense' => $unitsinfo['army_def']
    );

   ///// Kolko jednotiek máš tolko krat sa vypise 
   $x = 1;    
   while($x <= $unitsinfo['army_population']) {

   foreach($unit_attacker as $index => $record){    

   ///// Tato cast pusti kod pre kazdu jednu jednotku ktora je v poli
   echo "<tr><td>Jednotka: {$record['name']} ID: {$record['power']} ParentID: {$record['attack']} Title: {$record['defense']}</td></tr>";
   $x++;
} 
}
}   
}  
                 ?>
                    </table>
                    <table> 
                    <tr><td><h3>Utok protivnik</h3></td></tr>
                    <?
   $query_street_def = mysql_query("SELECT * FROM game_army_units WHERE army_street = '".$row_street['attack_defender']."' ");
   $tilee_info_def = mysql_num_rows($query_street_def);
   if ($tilee_info_def > 0){ 

   $query_units_info_def = mysql_query("SELECT * FROM game_army_units WHERE army_street = '".$row_street['attack_defender']."' ");
   while (($unitsinfo_def = mysql_fetch_assoc($query_units_info_def)) != NULL) {
   $query_unit_info_def = mysql_query("SELECT * FROM game_army_class WHERE army_class_id = '".$unitsinfo_def['army_class_id']."' ");
   $unit_def = mysql_fetch_assoc($query_unit_info_def);
   $unit_attacker_def = array();

   $unit_attacker_def[] = array(
        'name' => $unit_def['army_class_name'],
        'power' => $unitsinfo_def['army_power'],
        'attack' => $unitsinfo_def['army_att'],
        'defense' => $unitsinfo_def['army_def']
    );

   ///// Kolko jednotiek máš tolko krat sa vypise 
   $y = 1;    
   while($y <= $unitsinfo_def['army_population']) {

   foreach($unit_attacker_def as $index => $record_def){    

   ///// Tato cast pusti kod pre kazdu jednu jednotku ktora je v poli
   echo "<tr><td>Jednotka: {$record_def['name']} ID: {$record_def['power']} ParentID: {$record_def['attack']} Title: {$record_def['defense']}</td></tr>";
   $y++;
} 
}
}    
} 

Simulation:

 $count = 0;    
      while ((count($unit_attacker_def) > 0) && (count($unit_attacker) > 0)){
      $count++;
      $attacker_key = rand(0,count($unit_attacker_def)-1);
      $attacker     =& $unit_attacker[$attacker_key];
      $defender_key = rand(0,count($unit_defender)-1);
      $defender     =& $unit_attacker_def[$defender_key];
           while (($defender['power'] >= 0) && ($defender['power'] >= 0)){
      $hit = ($attacker['attack']/$defender['defense']) + rand(1, 2);
      echo "<tr><td>{$count}.xx {$attacker_key} xJednotka {$defender['name']} ({$defender['power']} hp) bola zranená a dostala {$hit} zranenia jednotkou {$attacker['name']} ({$attacker['power']} hp)</td></tr>";
      $defender['power'] = $defender['power'] - $hit;
      $attacker['power'] = $attacker['power'] - $hit;

      if ($defender['power'] <= 0) {
        echo "<tr>Jednotka {$defender['name']} umrela, jednotka {$attacker['name']} vyhrala!</tr>";
        unset($defender[$defender_key]);
        $defender_key = rand(0,count($unit_defender)-1);
        $defender =& $unit_attacker_def[$defender_key];

      }
        if ($attacker['power'] <= 0) {
        echo "<tr>Jednotka {$attacker['name']} umrela, jednotka {$defender['name']} vyhrala!</tr>";
        unset($attacker[$attacker_key]);
        $attacker_key = rand(0,count($unit_attacker_def)-1);
        $attacker =& $unit_attacker[$attacker_key];
      }
      }
    }
     ?>
     </table>
     <? 
             break;

First of all, make sure you have turned on error reporting:

<?php
// Turn off error reporting
error_reporting(0);

// Report runtime errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Report all errors
error_reporting(E_ALL);

// Same as error_reporting(E_ALL);
ini_set("error_reporting", E_ALL);

// Report all errors except E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);
?>

With simple debugging you will find out where is an error. Just var_dump() every important variable and check its state. Nobody can debug for you because we don't know what is the data in your mysql table.

Try to use mysqli_* functions, because mysql are deprecated.

Try to use classes to describe everything in your game and make it more readable and maintainable. For example:

    <?php

    abstract class Unit{


        protected $hp;
        protected $damage;
        protected $defense;

        // Force Extending class to define this method
        abstract protected function applyDamage($damage);

    }

    class GroundUnit extends Unit{

        //GroundUnit inherits everything from Unit

        //define methods specific for GroundUnits


    }

    class FlyingUnit extends Unit{
        //FlyingUnit inherits everything from Unit

         //define methods specific for GroundUnits

}

When you find where is an error, and if you are still stuck, update your question with relevant data.

Note that your code is vulnerable to SQL injection

$query_street = mysql_query("SELECT * FROM game_army_attacks WHERE attack_id = '".$_GET['id']."' ");//don't put $_GET['id'] directly into query because that is security hole

Simple steps(related to your example) to improve your protection from sql injection would be :

//assume that $_GET['id'] should hold an integer value

$id = isset($_GET['id']? trim($_GET['id']) ? 0);
$id = (int)$id;

Now let's pretend that there is a $_GET['some_key'] also and it should hold string value. Now checks would be little different:

$some_string_value =  isset($_GET['some_key']? trim($_GET['some_key']) ? '');
$some_string_value = trim($some_string_value);//triming whitespace
$some_string_value = mysql_real_escape_string($some_string_value);//escaping troublesome quotes(')

Also you can use prepared statements which is in my opinion a preferred way.

Well you use array_rand() it selects one element from the array and when u use $array[$key] where $key = 1 because of array to var conversion it returns second element of your array atackers and second element of defenders. Use rand(0,count($unit_attacker)-1) to generate random key. But it still will be bugy because you can generate the same key )).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM