Reputation: 145
I am about to create a script that choose a winner for my lottery. The amount of tickets is chosen by following: amount of money * 100
So $1.26 = 126 tickets.
I made this, which give me the winning ticket number, but then I cannot get the winning user:
$totaltickets = 0;
foreach($players as $player){
$totaltickets += $player->depositedValue*100;
}
$winningTicket = rand(1,$totaltickets);
I have rows like this:
Player1 - 1.25$
Player2 - 5.99$
etc..
If it is possible then I would like to keep it like this, and not have 1000s of rows in the database with each ticket.
Upvotes: 7
Views: 4871
Reputation: 10975
I'm thinking of keeping your idea of numbers instead of bring in an array.
I'm going to have the players hold their ticket positions (start/end). When I pick a random ticket, I'm going to see if my number is within their bounds, and if it is, then I have found the winner.
<?php
class TicketMaster {
private $players = array();
public $total = 0;
public function addPlayer($player) {
$player->tickets[0] = $this->total;
$this->total += $player->value;
$player->tickets[1] = $this->total;
$this->players[] = $player;
}
public function selectWinner() {
$ticket = rand(0, $this->total);
foreach ($this->players as $player)
if ($ticket >= $player->tickets[0] && $ticket <= $player->tickets[1])
return $player;
return false;
}
}
class Player {
public $name = '';
public $value = 0;
public $tickets = array(0, 0);
function __construct($name, $value) {
$this->name = $name;
$this->value = $value;
}
}
$ticketMaster = new TicketMaster();
$ticketMaster->addPlayer(new Player("John", 200));
$ticketMaster->addPlayer(new Player("Mike", 200));
$ticketMaster->addPlayer(new Player("Dave", 1000));
echo $ticketMaster->selectWinner()->name;
Also
$ticket = rand(0, $this->total); //change to random_int, but I kept it at rand because eval.in only works with this one
Output: Dave
Dave wins most of the time because he has like 1000 tickets, over the other two players who only have 400 combined.
Upvotes: 2
Reputation: 24960
-- No php required, just mysql. No crazy rowcounts just 12 in this example.
create table rg
( -- RaffleGuy
guyId int auto_increment primary key,
fullName varchar(100) not null,
cellPhone varchar(20) not null,
ticketCount int not null,
winLow int null,
winHigh int null
);
-- trucate table rg; -- for testing next time
insert rg (fullName,cellPhone,ticketCount) values ('johnny two thumbs','11111',126);
insert rg (fullName,cellPhone,ticketCount) values ('kim','153111',500);
insert rg (fullName,cellPhone,ticketCount) values ('Lady with Hat','113211',1);
insert rg (fullName,cellPhone,ticketCount) values ('Guy with Nose','14454111',900);
insert rg (fullName,cellPhone,ticketCount) values ('Kipper','2211111',100);
insert rg (fullName,cellPhone,ticketCount) values ('Jipper','222888',400);
insert rg (fullName,cellPhone,ticketCount) values ('smith family','534511111',500);
insert rg (fullName,cellPhone,ticketCount) values ('First Pentacostal Church','3153111',200);
insert rg (fullName,cellPhone,ticketCount) values ('Lady with Hat','1132141',123);
insert rg (fullName,cellPhone,ticketCount) values ('Guy with Nose','14441311',500);
insert rg (fullName,cellPhone,ticketCount) values ('Kipper','2211711',300);
insert rg (fullName,cellPhone,ticketCount) values ('Jipper','2272',200);
update rg
join
(select rg.guyId,(select ifnull(sum(ticketCount)+1,1) from rg r2 where r2.guyId<rg.guyId) below
from rg) nnn
on nnn.guyId=rg.guyId
set winLow=nnn.below,winHigh=nnn.below+ticketCount-1
select * from rg;
# fullName cell# tix wLow wHigh
1 johnny two thumbs 11111 126 1 126
2 kim 153111 500 127 626
3 Lady with Hat 113211 1 627 627
4 Guy with Nose 14454111 900 628 1527
5 Kipper 2211111 100 1528 1627
6 Jipper 222888 400 1628 2027
7 smith family 534511111 500 2028 2527
8 First Pentacostal Church 3153111 200 2528 2727
9 Lady with Hat 1132141 123 2728 2850
10 Guy with Nose 14441311 500 2851 3350
11 Kipper 2211711 300 3351 3650
12 Jipper 2272 200 3651 3850
select sum(ticketCount) into @tottix from rg; -- 3850
-- seed your random number, I leave that to you
select rand(unix_timestamp()); -- example
select floor(rand()*@tottix)+1 into @thernd; -- 531
select * from rg where winLow<=@thernd and winHigh>=@thernd;
2 kim 153111 500 127 626
Kim wins, call her
Upvotes: 1
Reputation: 816
You can use this code:
<?php
function getWinnerPlayer($players) {
/* get total amount of tickets */
$total_tickets = 0;
foreach ($players as $player) {
/* var_dump($player->depositedValue); */
$total_tickets += $player->depositedValue * 100;
}
/* get winner ticket */
$winner = rand(1, $total_tickets);
/* return winner player */
$count = 0;
foreach ($players as $player) {
// $total_tickets is not the correct variable, sorry
// $count += $total_tickets->depositedValue * 100;
$count += $player->depositedValue * 100;
if ($count >= $winner) return $player;
}
}
?>
Upvotes: 3
Reputation: 3378
Here is pseudo code that can help draw the lottery randomly and identify the winner. The best approach in this case of multiple numbers since you are using foreach is to use arrays. So in the code below
<?php
//Array that holds the players
$players[] =0;
//Run this loop from 0 until how many tickets were issued
for($i=0; $i<100; $i++){
$players[$i] = $i * 100;
}
//Choosing the randomly winning ticket
$winningTicket = array_rand($players, 1);
//what ticket number won the lottery, (var_dump to be able to see the output)
echo "Winning Number = ".$players[$winningTicket]."<br/>";;
//Who won the lottery, (var_dump to be able to see the output)
echo "Winning Person = Person No.".$winningTicket;
?>
Upvotes: 0