You scratch my ticket, I'll scratch yours...
April 22, 2009 11:55 AM   Subscribe

How should I approach programming a prize draw?

I've been given the job of putting together an online prize draw scratchcard for a promotion on a website. The draw will run between two fixed dates. There is one grand prize and there are fifty runner-up prizes. The front-end is Flash; the back-end is PHP/MySQL.

I'm aware that I should do pretty much everything on the server; the Flash movie will be fed a particular scratchcard, collect the details of each player, reveal whether they have won, then send their details back to the server. The allocation of the cards will be done entirely on the server-side.

But how do I allocate the tickets? Is there a 'best practice' way of doing this sort of thing, given that I have no idea how many people will play (I'm guessing tens of thousands)?

And what simple precautions should I take to ensure that prizes are won fairly?
posted by le morte de bea arthur to Computers & Internet (17 answers total) 1 user marked this as a favorite
 
Wait, how exactly does getting a scratch ticket work? Can any random person go to the website and get one? Normally online contests are either in the form of buying a physical item with a code on it that can be entered via the website to possibly win a prize, or filling out some sort of online form and waiting for a drawing at the end of the contest. Actual scratch-off lottery tickets work by charging more per ticket than the average payout, but running a contest like that would be considered gambling in most places.
posted by burnmp3s at 12:07 PM on April 22, 2009


Depending on what state you're in and the size of the contest, you need to post odds of winning any given prize. For a scratch card, this means you have to have a limited number of cards available (for example, 1 grand prize winning card and 500 total cards means 1:500 odds and therefore you can't change the number cards).

You have to estimate the number of people who will play and then add a margin of error (about 10%). Don't know the details of your contest, but there must be a No Purchase way of entry, so also account for those (also around 10% for online).

If you advertise the contest and have good prizes, people will try and hack it to win.
posted by dripdripdrop at 12:24 PM on April 22, 2009


Best answer: If anyone can take part (without paying or entering a code gathered offline, etc.) and the prizes are decent then brace yourself for creating multiple layers of defence.

The kinds of things to consider are:
- Robust server-side validation/filtering to avoid basic things like SQL injection
- Monitoring tools that can apply some simple fuzzy logic to highlight suspicious activity (similar activity from different IPs, different activity from similar IPs, similar contact details, etc.) and let you block it
- Scrupulous server security; lock everything down mercilessly and monitor carefully
- Try to ensure the server will cope with spikes in traffic (hard to diagnose and solve issues if someone's tying it up with too many requests)
- Talk to your hosting firm about the possibility of being able to block certain types/origins of traffic before it hits the server (just in case someone proves to be a really persistent pest)
- Sensible rate limiting, e.g. X scratchcards per IP per day (although this can seem unfair if X is so low that some legitimate users get excluded, and may need addressing in terms and conditions)
- Make sure the terms and conditions allow you to freely exclude anyone
- Sanity-check your plans with other developers

As for allocating prizes, well ideally you don't want them all to go in the first day, but also need to be fair and transparent. One solution is to offer daily prizes and then allocate the grand prize at the end to a random winner (or entrant if losers also enter their details), which helps retain interest throughout the promotion.
How you structure the prizes and pick the winners very much depends upon how the draw is described/presented and the laws that apply. If it's clearly analogous to physical scratchcards then a fixed number of prizes for a variable number of entries may be problematic (as dripdripdrop has explained), whereas in other cases you might be able to get away with picking a winning time each day in advance and serving a winning ticket when it's reached (carefully allowing for someone not claiming or it rolling over to the next day if the winning time is close to midnight).

I've worked on online competitions where the client made it clear they didn't care about cheating as long as the site got traffic, and many developers have a similarly lax/resigned attitude, but the battle of wits can be an interesting learning experience. And clients tend to quickly change their minds about the cheating thing when they have a prize-giving PR event and a bunch of unphotogenic hacker types turn up looking smug...
posted by malevolent at 12:57 PM on April 22, 2009 [1 favorite]


Response by poster: Some clarification:

1. Yes, a random person can go to the site, enter their email address and other contact info, then scratch a ticket. There's no payment involved; it's just a promotional gimmick. The fact that the thing is presented as a scratch-off ticket is largely irrelevant. At the root of it is the fact that a random visitor will either win one of the prizes or they won't.

2. I'm in the UK, so different rules will apply. Since no payment is made, the prize draw is (I'm told) not considered a 'lottery' and is therefore not subject to the kinds of rules mentioned. And in any case, I'm the freelance developer; I'm not here asking legal questions.

Malevolent, thanks for all that; you've raised a few points I hadn't considered. One thing that's already set in stone however is that there will be immediate feedback when a prize is won, so we can't simply allocate the big prize at the end. Somehow I need to think of a way to ensure that the prize is given at some random time not too close to the start of the competition.
posted by le morte de bea arthur at 1:06 PM on April 22, 2009


Somehow I need to think of a way to ensure that the prize is given at some random time not too close to the start of the competition.

You can't, really, at least without cheating. Think about it, if you were the first person entering the contest, and you learned that they had purposely designed it to not pay out until later, wouldn't you feel ripped off? malevolent's suggestion of picking a random winning time and not telling anyone about it is the closest thing to fair that qualifies, but in my opinion that's still deceptive.

If you don't have a fixed number of tickets and each ticket has a random chance of winning, there's no way to give immediate feedback and still make sure that all of the prizes are given away by the deadline, or that all of them aren't given away very early in the contest.
posted by burnmp3s at 1:23 PM on April 22, 2009 [1 favorite]


Best answer: Phew. If you have to hand out a prize immediately you're in for a world of pain.

This is why prize giveaways collect the data first and select a winner later. This lets you audit the data and throw out the obvious fraud. If you're doing it live you have to try on automated systems to catch the fraud, and they're a huge bitch to program well. (And even then.... It's much better to have a person looking over it.)

But hey, it's not your contest, just your job.

You're on the right track with picking specific (random) times of day to hand out prizes since that's the hardest to game. Another option would be for a human at the company doing the contest to in the blind push a button that tells the server to choose one of the next hundred (or thousand) entries as a winner. It's still pretty rigged but as long as it's blind and somewhat random it's not so bad. It's more akin to drawing a name out of a hat that way. (Though you're still throwing out a great many of the entries without a chance at all.)

If people can only enter once I'd set a Flash cookie (SharedObject) that will record if a person/computer has entered the contest and will only let them do it once (or once a day, whatever.) It's pretty easy to circumvent, but it should stop most casual ballot stuffers since very few people know that Flash cookies exist, much less how to delete them.

Timestamp every entry and record IP addresses. Throw out entries that happen too quickly from the same IP address. Filter email addresses against the "+" trick. (ie: bob@gmail.com and "bob+contest@gmail.com are the same email address. Slice out everything between the + and the @ before writing to the DB.)

If you want to get really complex and prevent someone from making an automated script you can set up a coded handshake between the server and the SWF that verifies that it's talking to the right client. (Server sends a code to the client (say an MD5'd time stamp) that it saves on the database wit ha session ID. The client runs a secret convolution on it and sends it back to the server with the submission (and session ID). The server compares the result with what's on file and if it matches, we presume it came from the client, not an automaton and we see if we have a winner.) Or encrypt all the communication, but it can bog down your sever and (to my knowledge) Flash doesn't have a good encryption library.
posted by Ookseer at 1:40 PM on April 22, 2009 [1 favorite]


Response by poster: You can't, really, at least without cheating

On reflection I'm thinking that, for the first day, I could hold back on the big prize. Then I could use the entry count for the first day to determine a probability for paying out the prize on the second day. As time progresses the odds of winning increase in inverse proportion to the number of days remaining.

It does seem a little bit wrong to make it impossible to win on the first day, but on the other hand there are fifty smaller prizes (all very good) which could simply be spread over the duration of the draw (including the first day) in the way malevolent suggested.
posted by le morte de bea arthur at 1:43 PM on April 22, 2009


Your job as a consultant is tricky. You can deliver what they ask for, or you can deliver what they need. In this case, they probably need daily prizes rather than instant win. The reason is simple if you think about normal scratch promos. You make a bunch of winner tickets and a bunch of losers; then you hand out that fixed number. Page hits are not a fixed quantity, so establishing any valid odds at all is impossible.

Moreover, this gimmick may fail to gather what you want. What stops an entrant from completely making up the entry and claiming a prize? Send an email at the end of the day announcing the winner. It does a number of neat things:

1. Its fair.
2. All entrants now have incentive to offer credible information
3. You can't make up a billion entries with different mailinator addresses without having to check a billion inboxes at some point in the future. They'll have to record each inbox name.

As for the grand prize allocation, here is how you do it fairly: runners up receive a prize, and a entry for the grand prize. At the end of the contest, the grand prize winner is selected from the runners up.
posted by pwnguin at 1:49 PM on April 22, 2009


Slightly not answering the question here, but couldn't you hand out the small prizes randomly instantly (adjusting the odds as you collect data regarding entries/day) and hand out the big prize at the end?
posted by christonabike at 1:57 PM on April 22, 2009


Response by poster: You can deliver what they ask for, or you can deliver what they need.

If I build something other than what has already been planned, designed, signed off and then passed on to me with a deadline attached, I won't get paid and I won't get any further work.

What stops an entrant from completely making up the entry and claiming a prize?

Every entry (email address + name + phone number + IP address + whatever else) is stored in a database. Duplicates are not accepted. I'll be implementing various checks as Ookseer and others have suggested to prevent suspicious multiple entries. Whether an entry is a win or not is determined by the server before the user sees anything. The user can mess however they want with the front-end - it will make no difference, because their win/lose status is part of their session.
posted by le morte de bea arthur at 2:06 PM on April 22, 2009


Response by poster: And no, I can't change the way prizes are given out. The main prize must be given out to one randomly selected entrant, and they must be notified straight away.

So at this stage I'm really just looking for any insight as to how to allocate that prize fairly, and also how to minimise hackability.
posted by le morte de bea arthur at 2:09 PM on April 22, 2009


Best answer: "If I build something other than what has already been planned, designed, signed off and then passed on to me with a deadline attached, I won't get paid and I won't get any further work. "

Yeah, it's difficult when projects are signed off before anyone knowledgeable has a chance to pick them apart, the planning should've included everything being discussed here (and probably would've led to a different mechanism being selected).

Just make sure you list all the potential issues, get full sign-off on things like the picking mechanisms and terms, and charge extra for any fire-fighting measures needed while it's running. Cover your arse very carefully.

Thinking about it, the simplest option is probably to just set fixed odds for limited prizes and unlimited tickets, don't publicise how many prizes have been won, and specify that any remaining prizes will be awarded at random to losing entrants at the end. That's probably as good/fair as you can get.

If you determine whether they've won in the same request that saves their details and return the status in the response (rather than feeding it to the Flash separately) then you don't have the problem of allowing for unclaimed winning tickets and managing sessions. Someone submits their details, they get validated/filtered/blacklist-checked, then you roll the dice, store the details/prize in the db and return the data describing what they've won.

And if you collect postal address and are only allowing UK entrants then you can restrict to one entry per postcode and clearly state in the form that prizes will only be sent to the address entered. In theory this should drastically reduce the multiple-entry problem and is probably your best weapon against spamming.
posted by malevolent at 2:41 PM on April 22, 2009


(OK, one per postcode would probably lead to complaints, maybe allow half a dozen to avoid grumbles while still limiting spamming, or mention that a valid phone number is needed to contact winners and disallow the same phone/postcode pair being used more than once)
posted by malevolent at 2:47 PM on April 22, 2009


Best answer: If I build something other than what has already been planned, designed, signed off and then passed on to me with a deadline attached, I won't get paid and I won't get any further work.

Yeah, it's tough sometimes because sometimes the things that are impossible, impracticable, or in the worst interests of the client can still slip through that sieve. But sometimes the client really does want you to shoot them in the foot and know exactly what that means.

Anyway...

I've been thinking about this since my last post and I may have an idea:

You don't know how many contestants there will be, but you do know how long the contest will run. So don't make it a "1 in unknown number of contestants" probability. Make it "1 in known number of minutes". Run a timed script that runs every minute (or 10 seconds or whatever). Weight the random number by the number of times the script will run throughout the contest and the number of prizes left. If it comes back with "winner" the next valid entry submitted will be the winner.

If you run it sufficiently often (Say thousands of times over the course of the contest) it will hand out the prizes randomly but spread out evenly (more or less) over the run of the contest.

I'd simulate this many many times before deploying it just to be sure. And make sure you have a good random number generator and that an alarm will go off if the script stops running for any reason. Possibly ramp up the probability as time runs out and there are still prizes left.
posted by Ookseer at 4:59 PM on April 22, 2009


Response by poster: For anyone looking at this thread later:

Thanks to everyone, malevolent and Ookseer in particular.

After my own bit of thinking, I think the way I'm going to approach it is this:

1. During an initial setup phase the system randomly assigns a time to each prize (including the big prize). Each 'prize time' is some point between the start and end times of the draw, and is in the the 7am - midnight range, because the draw is UK-specific and we don't want a build-up of unclaimed prizes at night. Ideally these times should be spready 'evenly-but-randomly', so I may start off with an even distribution, then apply a random 'jiggle' to make the times unpredictable.

2. When a prize becomes due (when its trigger time has passed) it becomes 'available'.

3. When an draw entry is made, the system checks to see if any prizes are currently available (see (2)), then assigns a random probability of winning the prize (say 1 in 10, or perhaps the system could be slightly clever and base the probability on the typical number of entries in a given time period). This provides an additional layer of short-term randomness that isn't strictly necessary, but will help to defeat anyone who happens to know a 'prize time' for whatever reason. Since this probability is relatively high, we can be sure that the prize will be won within a reasonably short time.

4. If the entrant wins a prize in (3), the prize is marked as claimed and is no longer available to anyone else.
posted by le morte de bea arthur at 2:35 AM on April 23, 2009


Sounds OK, although make sure you run it past the client and whoever is writing the terms, checking legality, etc. While picking a time is a sensible option, it's not how scratchcards work and how far the analogy can be stretched isn't your responsibility/decision.

I think the time picked should be purely random; if you make it even then 'jiggle' it then it's more complicated to explain/justify. Make sure the server clock is set correctly and your code is working in the right timezone (if the code uses UTC but the terms mention BST times then you'll be off by an hour).

Also, I'd perhaps drop (3), as it compicates the explanation if you want to be 100% transparent. If you're worried about someone getting the times from the database you could apply offsets that are stored in PHP, and later manually check the submission times of winning entries (so if anyone, e.g. at the hosting firm, tampers with the db to give themselves a prize but doesn't realise there's an offset then it'll show up).
posted by malevolent at 3:11 AM on April 23, 2009


I think it sounds good enough for a pretty difficult assignment. I like step 3 since it adds another layer of randomness to the equation. Malevolent is right, it technically doesn't need it, but since the times could be known by someone, it ads a layer of protection if anyone should complain about the contest being rigged and the thing gets pulled in for an audit. As another layer of protection you could encode or hash the time so it wouldn't be stored as a human readable number anywhere.

However it also ads another layer of complexity, so run as many simulations as you can and check your fringe cases.
posted by Ookseer at 12:12 PM on April 23, 2009


« Older Jackson Browne's autograph at concert--how?   |   Where can a person find a tiny handy netbook... Newer »
This thread is closed to new comments.