   Conceptual Random Problem : Theoretically Infinite
  Hey all,I've got this section of code for my PHP game, Feudal Conquest (minor pimpage: www.feudalconquest.com)The fact that its PHP is pretty much irrelevant, its prevelant in any language.ANYWAYS:In the battle engine I'm working on, I've code this section of code.while($iCombatRolls > 0 && $iAbortMission == 0)  {  // Get Valid Target  $iValidTarget = 0;  while($iValidTarget == 0)  {    $iTarget = rand(0, 2);    switch($iTarget)    {    // Infantry    case 0: if($AttackingForce->GetMilitaryInfantryCount() > 0) { if($this->GetDiceRoll($iModifierAttacker) < $this->GetDiceRoll($iModifierDefender))   $AttackingForce->AlterMilitaryInfantryCount(-1); $iValidTarget = 1; } break;    // Ranged    case 1: if($AttackingForce->GetMilitaryRangedCount() > 0) { if($this->GetDiceRoll($iModifierAttacker) < $this->GetDiceRoll($iModifierDefender))   $AttackingForce->AlterMilitaryRangedCount(-1); $iValidTarget = 1; } break;    // Mounted    case 2: if($AttackingForce->GetMilitaryMountedCount() > 0) { if($this->GetDiceRoll($iModifierAttacker) < $this->GetDiceRoll($iModifierDefender))   $AttackingForce->AlterMilitaryMountedCount(-1); $iValidTarget = 1; } break;    }  }  // If theres no invading troops left, abort.  if(($AttackingForce->GetMilitaryInfantryCount() + $AttackingForce->GetMilitaryRangedCount() + $AttackingForce->GetMilitaryMountedCount()) <= 0)    $iAbortMission = 1;  $iCombatRolls -= 1;  }The main issue I'm having is here:  $iTarget = rand(0, 2);    switch($iTarget)    {    // Infantry    case 0: if($AttackingForce->GetMilitaryInfantryCount() > 0) { if($this->GetDiceRoll($iModifierAttacker) < $this->GetDiceRoll($iModifierDefender))   $AttackingForce->AlterMilitaryInfantryCount(-1); $iValidTarget = 1; } break;    // Ranged    case 1: if($AttackingForce->GetMilitaryRangedCount() > 0) { if($this->GetDiceRoll($iModifierAttacker) < $this->GetDiceRoll($iModifierDefender))   $AttackingForce->AlterMilitaryRangedCount(-1); $iValidTarget = 1; } break;    // Mounted    case 2: if($AttackingForce->GetMilitaryMountedCount() > 0) { if($this->GetDiceRoll($iModifierAttacker) < $this->GetDiceRoll($iModifierDefender))   $AttackingForce->AlterMilitaryMountedCount(-1); $iValidTarget = 1; } break;    }  }I need to think of a solution thats just as "random" in its initial selection, but then picks a valid target within the same pass if the first one isn't valid...Basically this is what I mean:A random roll for a valid target is found:$iTarget = rand(0, 2);Assuming $iTarget is 1, the switch case statement goes here:if($AttackingForce->GetMilitaryRangedCount() > 0)That checks to see if the Attacking Player has more than 0 attacking Ranged soldiers.  If they do not, then a new random roll is made.The PROBLEM is when a player ONLY sends Infantry ($iTarget would be 0), the $iTarget = rand(0, 2); could in THEORY go on forever always picking 1 and 2 over and over.This problem isn't as noticable when small armies are engaging in combat (ie, 2000 soldiers versus 2000 soldiers) but when scaled up to say 250,000 versus 250,000 and a player sending NOTHING but Infantry the $iTarget random roll really starts to become 5+ seconds and its horribly lagged in the output (its quite noticable as well).I can't seem to come up with a solution... where a random roll is made, and then if that FAILS a perfect section is picked.Any ideas?(God I hope that made sense)    [edited by - GroZZleR on August 1, 2003 9:25:42 PM]
  If i understand correctly, your problem is that your checking whether the unit count > 0 AFTER you make the role.Why not just check before the role, and then only make the role for the units that have a count of > 0? ;  Not a bad idea, but I''m not quite sure how to tackle that problem.Say $iTarget = 1 is no longer valid, how do you randomize 0-2 and ignore 1, without randomizing over and over again?I thought maybe just randomize 0 - 1 instead, and if its 1 then add 2.  But in the case of expansion to more unit types (which will happen), you''re going to get bigger and uglier if statements scattered all through out it. ;  Rather than always creating a random number from 0 - 2, create a random number from 0 - n where n is the number of units with a unit count > 0. Then simply map each unit to a number in the range. These mappings will be dynamic, so you won''t just be able to harcode 0 -> Infantry, 1-> Ranged and 2 -> Mounted. 