Wireless game show style buzzer system

I have a little experience using Arduino, but I have 0 experience with anything wireless.

I would like to build a system with 16 wireless transmitters that act as a game show style buzzer. The biggest problem I'm having so far is trying to figure out what kind of transmitter and receiver I can use that can work with 16 different frequencies.

I've also heard mention of using IR transmitters with PWM, but I know that IR has a higher chance of not being picked up as distance and things increase.

Like I said, I know almost nothing about wireless and the research I've done up to this point hasn't been very helpful. Cost isn't much of an issue, so any guidance would be great. Thanks.

and the research I've done up to this point hasn't been very helpful.

That's hard to believe. The usual questions, that you failed to provide answers to, are:

What range?
How much data?
How reliable?
What price range?

XBees would fill the bill, but break the bank. 16 of them, with shipping, would run you in the neighborhood of $500. Very reliable.

Using wireless would be difficult if contestants ring in at the same time.

This was discussed awhile back using a wired network:

/*jeopardy style game-- master button (masClick) will enable 20+ other buttons (chiClick) to "buzz" in.
Once a player button is pressed, the others are locked out and the player's corresponding LED is lit indicating 
which player buzzed in first. The loop resets after 5 seconds and waits for the master to be pressed again.
*/
 
//LarryD
#define pushed LOW   //pushing gives a LOW
//#define pushed HIGH  //pushing gives a HIGH
 
#define LEDon   HIGH
#define LEDoff  LOW
 
const byte masClick    = 53; // iteration should commence once masClick pin 53 goes HIGH
const byte masClickLED = 52; // will illuminate when master button is pressed
 
const byte chiClick[]    = { 2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
//                           0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21
const byte chiClickLED[] = {24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45};

const byte pinCount      = 22;
 
const unsigned int onTime         = 5000; //after you have a winner leave LED on for this time
const unsigned int debounceDelay  = 25;   //scans switches every 25 milliseconds
 
unsigned long debounceMillis; //used in timing switch checking
unsigned long FiveSecMillis;  //used in timing after first person has been detected
unsigned long masterMillis;   //used for flashing master LED after cheating is detected
unsigned long delayMillis;    //used after cheating has been acknowledgment by master push
unsigned long winnerMillis;   //used in timing to flash the winners LED
 
byte winnerIndex;          //the array index number of the winner
 
bool FiveSecFlag = false;  //false = not in 5 second timing mode
bool polingFlag  = false;  //flase = not scanning the contestant switches
bool cheatFlag   = true;   //true  = check to see if contestant button is pressed before it should be
bool flashFlag   = false;  //false = flash the master LED
 
//*********************************************************
 
void setup()
{
  pinMode(masClick, INPUT_PULLUP);
  pinMode(masClickLED, OUTPUT);
  digitalWrite(masClickLED, LEDoff);
 
  for (int i = 0; i < pinCount; i++)
  {
    pinMode(chiClick[i], INPUT_PULLUP);
    pinMode(chiClickLED[i], OUTPUT);
    digitalWrite(chiClickLED[i], LEDoff);
  }
 
  //Lamp test, flash LEDs 10 times at reset, an even number here leaves the LEDs off
  for (int x = 0; x < 20; x++)
  {
    for (int i = 0; i < pinCount; i++)
    {
      digitalWrite(chiClickLED[i], !digitalRead(chiClickLED[i]));
    }
    digitalWrite(masClickLED, !digitalRead(masClickLED));
    delay(500);
  }
 
} //END of             s e t u p ( )
 
//*********************************************************
 
void loop()
{
 
  //NON-blocking code goes here
 
  //**************************
  //if there is any cheating flash master LED
  if (flashFlag == true)
  {
    if (millis() - masterMillis >= 250)
    {
      masterMillis = millis();
      //toggle master LED
      digitalWrite(masClickLED, !digitalRead(masClickLED));
    }
  }
 
  //**************************
  //are we in the 5 second timeout period?
  if (FiveSecFlag == true && millis() - winnerMillis > 100ul)
  {
     //flash winners LED
     winnerMillis = millis();
     //toggle LED
     digitalWrite(chiClickLED[winnerIndex], !digitalRead(chiClickLED[winnerIndex]));
  }
 
  else if (FiveSecFlag == true && millis() - FiveSecMillis >= onTime)
  { 
    //five seconds has gone by, disable timeout
    FiveSecFlag = false;
 
    //turn off contestant LEDs
    for (int i = 0; i < pinCount; i++)
    {
      digitalWrite (chiClickLED[i], LEDoff) ;
    }
 
    //turn off master LED
    digitalWrite (masClickLED, LEDoff);
 
    //allow cheat checking
    cheatFlag = true;
  }
 
  //**************************
  //time to scan the switches?
  if (millis() - debounceMillis >= debounceDelay)
  {
    debounceMillis = millis();
    readSwitches();
  }
 
} // END of             l o o p ( )
 
 
//*********************************************************
 
void readSwitches()
{
  //**************************
  //should we check for cheating?
  if (cheatFlag == true)
  {
    //check to see if any number of contestants are holding their switch down
    for (int i = 0; i < pinCount; i++)
    {
      if (digitalRead(chiClick[i]) == pushed)
      {
        //turn on the cheaters LED
        digitalWrite (chiClickLED[i], LEDon);
 
        //notify master that a switch is being pressed too early
        flashFlag = true;
      }
    }
  }
 
  //**************************
  //if there is cheating, has the master acknowledged it
  if (flashFlag == true && digitalRead(masClick) == pushed)
  {
    //Stop master LED flashing
    flashFlag = false;
    //turn off Master LED
    digitalWrite (masClickLED, LEDoff);
    //turn off all contestant LEDs
    for (int i = 0; i < pinCount; i++)
    {
      digitalWrite (chiClickLED[i], LEDoff) ;
    }
 
    //must give some time after cheat acknowledgment
    delayMillis = millis();
  }
 
  //**************************
  //Start the game?
  //not in 5 second mode, no cheating, we are not currently poling, 2 seconds has gone by since
  //the last cheat acknowledgment and the master switch is now pressed
  if (FiveSecFlag == false && flashFlag == false && polingFlag == false  && millis() - delayMillis > 2000
      && digitalRead(masClick) == pushed)
  {
    //turn on master LED
    digitalWrite (masClickLED, LEDon);
 
    //allow scanning
    polingFlag = true;
    //disable check checking
    cheatFlag = false;
  }
 
  //**************************
  //should we scan for a winner?
  if (polingFlag == true)
  {
    //scan for the first LOW switch
    for (int i = 0; i < pinCount; i++)
    {
      if (digitalRead(chiClick[i]) == pushed)
      {
        //save the winners array index
        winnerIndex = i;
        winnerMillis = millis();
       
        //turn on the winner LED
        digitalWrite (chiClickLED[i], LEDon);
 
        //disable further scanning
        polingFlag = false;
       
        //Enable the 5 second countdown timer
        FiveSecFlag = true;
        FiveSecMillis = millis();
       
        //we found the winner, stop looking any further
        break;
      }
    }
  }
 
} // END of         r e a d S w i t c h e s ( )
 
//*********************************************************

You can unlock and timestamp all receivers with the same broadcast,
let they do their timings on the button, and send back the measurement until handshaked.

You could also poll all node for the measurement after unlocking, eliminating any chance of collision.
Because the measurement will be based on a common timestamp, the polling introduces no unfairness.
A second command loop after the first positive query could signal the you win/loose state.

NRF24L01+ should work quite well in an auditorium type environment and they are cheap.