views:

77

answers:

1

I'm trying to come up with a way for players to fire their weapons and only hit for a certain percentage. For example, one gun can only hit 70% of the time while another only hits 34% of the time.

So far all I could come up with is weighted arrays.

Attempt 1:

private function weighted_random(&$weight)
    {
        $weights = array(($weight/100), (100-$weight)/100);
        $r = mt_rand(1,1000);
        $offset = 0;
        foreach($weights as $k => $w)
        {
            $offset += $w*1000;
            if($r <= $offset)
                return $k;
        }
    }

Attempt 2:

private function weapon_fired(&$weight)
    {
        $hit = array();
        for($i = 0; $i < $weight; $i++)
            $hit[] = true;
        for($i = $weight; $i < 100; $i++)
            $hit[] = false;
        shuffle($hit);
        return $hit[mt_rand(0,100)];
    }

It doesn't seem that the players are hitting the correct percentages but I'm not really sure why.

Any ideas or suggestions? Is anything glaringly wrong with these?

Thanks

+8  A: 
private function weapon_fired($weight)
    {
        return mt_rand(0, 99) < $weight;
    }
Chris AtLee
This is a much simpler way of doing my second attempt right? Do you happen to know if it's "accurate?"
noko
It should be. You can test accuracy by calling it a few thousand times and seeing how it works out.
Charles
Depends what you mean by "accurate". Randomness is a funny thing. Just because it might returns true 10 times in a row for a weapon with a 1% chance of hitting doesn't mean it's not "accurate".
Chris AtLee
Another important thing to consider. When developing a game you definitely _do not_ want to have your weapon firing function be _any_ form of loop.
hobodave
Wouldn't it be: `mt_rand(0, 99) < $weight` Your answer uses 0, 100 which returns 1 of 101 possibilities.
webbiedave
I don't think so, since if you have a 99% accurate weapon and you roll a 100 then it should miss, right?
noko
@noko: Note the less than sign. Also note that it would allow a weight of 0 to be passed in case you want a weapon to never hit.
webbiedave
@webbiedave, yup, you're right. Edited my answer to match.
Chris AtLee
AH, okay. Thanks guys.
noko