Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********************************************************************
- * |RRR /OOO |U U |L |EEEEE |TTTTT |TTTTT |EEEEE *
- * |R R |O O |U U |L |E |T |T |E *
- * |RRR |O O |U U |L |EE |T |T |EE *
- * |R R |O O |U U |L |E |T |T |E *
- * |R R \OOO \UUU |LLLLL |EEEEE |T |T |EEEEE *
- * *
- * ARDUINO BASED ALCOHOLIC ROULETTE GAME *
- * *
- * ~ b y F r a s h P i k a s s , 2 0 1 3 ~ *
- ********************************************************************/
- /******************************
- * PLAYING THE *
- * GAME *
- *******************************
- Have a special tray in which each led is under a shotglass.
- Fill each shotglass with a different drink.
- Place the tray at the center of the table and sit around it
- with your friends.
- Decide an order for drinking; each drinker has to click
- the REROLL pushbutton once to get a randomly picked drink!
- When a game is finished, have another round!
- /******************************
- * SCHEMATICS *
- *******************************
- ARDUINO
- PINS REROLL
- PUSHBUTTON
- D2 ─────────────/ ──────┐
- │
- LEDS │
- D3 ──►|──┐ │
- │ │
- D4 ──►|──┤ Resistor │
- ├─────\/\/\────┤
- D5 ──►|──┤ │
- │ │
- D6 ──►|──┘ │
- ┴
- A0 ── GND
- Leave A0 unplugged.
- You can put as many leds as you want on pins from D3 to D13
- and from A1 (which can be used as digital pin D15 in the code)
- to A5 (which can be used as digital pin D19 in the code), for
- a maximum total of 16 leds.
- Remember to change the code accordingly, by placing the led pins
- you've chosen for your project in the constant array "pins" with
- their correct order and the number of LEDs plugged in the constant
- "NUMBER_OF_PINS".
- Choose the resistor according to how much current you need to
- power up all your leds together at the same time.
- I suggest you to try different values with a potentiometer while
- prototyping.
- */
- /******************************
- * CONSTANTS *
- ******************************/
- //The number of pins installed
- #define NUMBER_OF_PINS 4
- //The minimum number of cycles Arduino must do when rolling
- #define MIN_NUMBER_OF_ROLLING_CYCLES 5
- //The minimum time between blinks in a roll
- #define MIN_ROLLING_TIME_STEP 10
- //The maximum time between blinks in a roll
- #define MAX_ROLLING_TIME_STEP 550
- //The default delay time for blinks
- #define DEFAULT_DELAY 200
- /*
- The pins array contains all the pins with leds attached
- in the order you want them to turn on while cycling.
- */
- const int pins[NUMBER_OF_PINS] = {3, 4, 5, 6};
- /*
- This is an input pin connected to the reroll pushbutton.
- The reroll pushbutton short circuits the input on pin 2
- to GND, and the reroll pin is read with the internal pullup
- resistors of the arduino.
- */
- const int rerollPin = 2;
- /*
- This constant holds the pin number of the analog pin with
- NOTHING ATTACHED the value of which is used as a seed to
- generate random numbers throughout the code.
- */
- const int analogSeedPin = 0;
- /******************************
- * GLOBAL *
- * VARIABLES *
- ******************************/
- /*
- This is a parallel array to the constant array pins.
- The availablePins array contains for each led its status of
- availability. If a pin is available its status is 1, if it's
- unavailable its status is 0.
- It's initialized to ones at the beginning of each loop.
- The status is updated to 0 every time the roulette stops.
- */
- int availablePins[NUMBER_OF_PINS];
- /*
- The numberOfAvailablePins variable keeps track of how many pins are
- still available. It's inizialized in the initAvailablePins() function
- to NUMBER_OF_PINS and it's decreased by 1 every time the roulette
- stops.
- */
- int numberOfAvailablePins=NUMBER_OF_PINS;
- /*
- The currentPin variable contains the index of the current pin in the
- cycle.
- */
- int currentPin;
- /******************************
- * UTILITY *
- * FUNCTIONS *
- ******************************/
- /*
- Blinks once on the specific pin for a given time
- */
- void blink(int pin, int time)
- {
- digitalWrite(pin, HIGH);
- delay(time);
- digitalWrite(pin, LOW);
- delay(time);
- return;
- }
- /*
- Turns on the specific pin.
- */
- void turnOn(int pin)
- {
- digitalWrite(pin, HIGH);
- return;
- }
- /*
- Turns off the specific pin.
- */
- void turnOff(int pin)
- {
- digitalWrite(pin, LOW);
- return;
- }
- /*
- Turns on all the pins for a given time (in millis)
- */
- void allOn(long millisOn)
- {
- int i;
- long prevTime=millis();
- while((millis()-prevTime)<millisOn)
- {
- for(i=0; i<NUMBER_OF_PINS; i++)
- {
- digitalWrite(pins[i], HIGH);
- digitalWrite(pins[i], LOW);
- }
- }
- return;
- }
- /*
- Turns all the led pins on.
- Overloads the previous function but uses no arguments
- */
- void allOn()
- {
- for(int i=0; i<NUMBER_OF_PINS; i++)
- {
- digitalWrite(pins[i], HIGH);
- }
- return;
- }
- /*
- Turns off all the pins.
- */
- void allOff()
- {
- int i;
- for(i=0; i<NUMBER_OF_PINS; i++)
- digitalWrite(pins[i], LOW);
- return;
- }
- /*
- Blinks all lights a number of times with a default delay.
- */
- /*
- *I'm not too happy with this variant, but it should work
- *more efficiently when done properly.
- void blinkAll(int times, long delay_)
- {
- for(int i=0; i<times; i++)
- {
- allOn(delay_);
- allOff();
- delay(delay_);
- }
- return;
- }
- */
- void blinkAll(int times, long delay_)
- {
- for(int i=0; i<times; i++)
- {
- allOn();
- delay(delay_);
- allOff();
- delay(delay_);
- }
- return;
- }
- /*
- Initializes to 1 the array of pin availability status and resets
- the variable numberOfAvailablePins.
- */
- void initAvailablePins()
- {
- numberOfAvailablePins = NUMBER_OF_PINS;
- int i;
- for(i=0; i<NUMBER_OF_PINS; i++)
- availablePins[i] = 1;
- return;
- }
- /*
- Returns the index of an available pin after pinIndex
- */
- int getNextAvailablePin(int pinIndex)
- {
- int p = (pinIndex+1)%NUMBER_OF_PINS;
- if(numberOfAvailablePins==0) //If there are no pins available
- return -1; //return -1
- else if(availablePins[p]==1) //Else, if the pin p is available
- return p; //return p
- else //Otherwise, run recursively until
- return getNextAvailablePin(p);//you find an available pin
- }
- /*
- Returns the index of a random available pin
- */
- int getRandomAvailablePin()
- {
- int randomPin;
- if(numberOfAvailablePins==0) //If there are no pins available
- return -1; //return -1
- else
- {
- //Seeds the random number generator
- randomSeed(analogRead(analogSeedPin));
- //Gets a random pin index number
- randomPin = random(0, NUMBER_OF_PINS);
- return getNextAvailablePin(randomPin);
- }
- }
- /*
- Rolls the roulette in a fancy way!
- Returns the random available pin extracted.
- */
- int roll(int firstPinId)
- {
- allOff();
- //Seeds the random number generator
- randomSeed(analogRead(analogSeedPin));
- //Setup a random unbalancer
- int unbalancer=random(0, numberOfAvailablePins);
- //Setup an index for the cycle and one for the pins
- int i, p=firstPinId;
- //Setup how many rolling steps we must cycle through
- int rollingSteps = MIN_NUMBER_OF_ROLLING_CYCLES*numberOfAvailablePins+unbalancer;
- for(i=0; i<rollingSteps; i++)
- {
- //Blink for a time directly proportional to the position of i in the range
- //[0,rollingSteps]
- blink(pins[p], map(i, 0, rollingSteps, MIN_ROLLING_TIME_STEP, MAX_ROLLING_TIME_STEP));
- p=getNextAvailablePin(p);
- }
- return p;
- }
- /*
- Wait until reroll pushbutton is pushed and released.
- The function is written considering the rerollPin is
- configured as INPUT_PULLUP, meaning that LOW means
- "button pushed" and HIGH means "button released".
- */
- void waitForReroll()
- {
- while(true)
- {
- if(digitalRead(rerollPin)==LOW){
- while(true){
- if(digitalRead(rerollPin)==HIGH);
- break;
- }
- break;
- }
- }
- return;
- }
- /*
- Sets the selected pin as unavailable for future rolls.
- */
- void setUnavailable(int pinIndex)
- {
- if(pinIndex>=0 && pinIndex<NUMBER_OF_PINS)
- {
- availablePins[pinIndex] = 0;
- numberOfAvailablePins--;
- }
- return;
- }
- /*
- Test leds for malfunctions
- */
- void testLeds()
- {
- allOff();
- for(int i = 0; i < NUMBER_OF_PINS; i++)
- {
- turnOn(pins[i]);
- delay(500);
- }
- for(int i = 0; i < NUMBER_OF_PINS; i++)
- {
- turnOff(pins[i]);
- delay(500);
- }
- }
- /******************************
- * MAIN PROGRAM *
- ******************************/
- /*
- RUNS ONCE AT THE BEGINNING
- */
- void setup()
- {
- int i; //Cycle index
- //Initializes the led pins in the pins array as output
- for(i=0; i<NUMBER_OF_PINS; i++)
- pinMode(pins[i], OUTPUT);
- //Initializes the reroll pin as input pullup
- //meaning that the open button will read as HIGH
- //while the closed button will read as LOW.
- //To close the button on rerollPin, you need to short it
- //to GND!!!
- pinMode(rerollPin, INPUT_PULLUP);
- }
- /*
- LOOPS INDEFINITELY
- */
- void loop()
- {
- //Initialize all
- initAvailablePins();
- currentPin = getRandomAvailablePin();
- testLeds();
- allOn();
- //Wait for reroll input...
- waitForReroll();
- for(int i = numberOfAvailablePins;i>0;i--)
- {
- //Let's roll!
- if(i>1)
- currentPin = roll(currentPin);
- else
- {
- allOff();
- currentPin = getNextAvailablePin(currentPin);
- }
- //If a valid pin was extracted
- if(currentPin != -1)
- {
- turnOn(pins[currentPin]);
- delay(DEFAULT_DELAY); //Wait for reroll input...
- waitForReroll();
- //Set the current pin as unavailable for future rolls
- setUnavailable(currentPin);
- }
- else //If no valid pin was extracted (e.g. in case of a severe hardware error)
- {
- testLeds();
- testLeds();
- allOn();
- waitForReroll();
- break;
- }
- }
- //If one game has finished,
- //Blink all lights three times
- blinkAll(3, DEFAULT_DELAY);
- //Loop from the start!
- }
- /******************************
- * CONTACTS & *
- * COPYRIGHT NOTICE *
- ******************************/
- /*
- * Code written by Frash Pikass (spamfrash@gmail.com)
- * in November 2013.
- *
- * This piece of software is released under a Creative Commons
- * Licence.
- * You can:
- * - Share and enjoy it with friends freely
- * - Make derivative works out of it (but giving some credits to
- * the author)
- * You can not:
- * - Sell derivative works (at least without the author's consent)
- * - Sell this code.
- *
- * Drink responsibly and don't break the law in your country
- * (UNLESS THE LAW IS UNJUST)
- *
- * "One has not only a legal but a moral responsibility to obey
- * just laws. Conversely, one has a moral responsibility to
- * disobey unjust laws."
- * ~Martin Luther King Jr.
- * (from "Letter from a Birmingham Jail")
- *
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement