Components and supplies
Arduino UNO
Resistor 221 ohm
5 mm LED: Green
Jumper wires (generic)
Breadboard (generic)
5 mm LED: Yellow
Tactile Switch, Top Actuated
5 mm LED: Red
LED, Blue
Project description
Code
Buttons & Lights Games
c_cpp
Remember and repeat given light sequences within a fixed time.
1/* 2 Ron D Bentley, Stafford, UK 3 Feb 2021 4 5 Buttons & Lights Game 6 ''''''''''''''''''''' 7 8 This example and code is in the public domain and may be used without restriction and 9 without warranty. 10 11 Basic game of Buttons & Lights 12 Game flow: 13 - game starts by blinking all 4 leds 4 times 14 - a sequence of 4, 5 or 6 leds are then illuminated, in turn, at the end 15 of which a 20 second timer then starts within which the sequence must 16 be entered on the button switches, each button switch one coresponding to an 17 associated led 18 - if correct sequence is entered then the green led will flash 5 times 19 - if the incorrect sequence is entered them the red led will flash 5 times 20 - if the sequence is not fully entered within the given time then the 21 blue led will flash 5 times and the game reset for the next round. 22 23 Configurability: 24 1. sequence size for illuminated leds - the number of guesess is defined by 25 the sequence size definition ('#define max_sequence'). Change this as 26 required, but should be > 4 for a reasonable game. 27 2. game time - the duration for entering the guess sequence is controlled 28 by the variable 'int guess_duration'. This should be set with the time in 29 milliseconds given for the guess period. 30*/ 31 32#define num_switches 4 // number of button switches connected 33struct switch_control {// digital input pin control data structure 34 int switch_pin; // digital button switch input pin, 35 bool switch_pending; // records if switch in transition or not, 36 long unsigned int elapse_timer; // records debounce timer count when associated switch is in transition 37} switches[num_switches] = { 38 8, false, 0, 39 9, false, 0, 40 10, false, 0, 41 11, false, 0 42}; 43 44#define success true // used for verifying guesses sequence 45#define switched true // signifies switch has been pressed 46#define debounce 10 // number of milliseconds to wait for switch to settle once pressed 47 48int leds[num_switches] = {// analogue outputs, one for each digital input/switch 49 A0, 50 A1, 51 A2, 52 A3 53}; 54 55#define red_led A0 // failed guess indicator 56#define green_led A2 // successful guess indicator 57#define blue_led A3 // timed out indicator, before guess fully made 58 59#define max_sequence 6 // must be >= 4 for a reasonable game, change if more wanted 60int sequence[max_sequence + 1]; // records sequence to guess.[0] will hold number of entries in array 61 62#define number_of_guesses max_sequence 63int guesses[number_of_guesses + 1]; // records player's guesses. [0] will hold number of entries in array 64 65long unsigned int start_time = 0; // used to time start of a game 66int guess_duration = 10000; // duration time given to a play game, in millisecs 67 68void setup() { 69 int sw; 70 // initialise digital input switch pins and their associated LEDs 71 for (sw = 0; sw < num_switches; sw++) { 72 pinMode(switches[sw].switch_pin, INPUT_PULLUP); // pin willbe HIGH unless switched 73 pinMode(leds[sw], OUTPUT); 74 } 75 randomSeed(analogRead(A4)); // A4 not used in this sketch as a connected output 76 reset_game(); // set up first game 77} 78 79void loop() { 80 if (millis() - start_time > guess_duration) { 81 // play time out 82 flash_led(blue_led, 5); // flash failure 83 delay(2000); 84 reset_game(); 85 } else { 86 if (guesses[0] < sequence[0]) { 87 // poll switches again for a selection 88 for (int sw = 0; sw < num_switches; sw++) { 89 if (read_switch(sw) == switched) { 90 // this button is pressed so record it - add to guess list 91 guesses[0]++; 92 guesses[guesses[0]] = sw; // record this switch's position in control struct(ure) 93 } 94 } 95 } else { 96 // all guesses made within the play time - check if correct 97 if (check_sequence() == success) { 98 // guessed correct 99 flash_led(green_led, 5); // flash success 100 } else { 101 // guess incorrect 102 flash_led(red_led, 5); // flash failure 103 } 104 delay(2000); 105 reset_game(); 106 } 107 } 108} 109 110// 111// game reset, clear down and generate a new sequence 112// 113void reset_game() { 114 int i, num_in_sequence; 115 guesses[0] = 0; // clear down previous guesses 116 // set up a new sequence for next game 117 num_in_sequence = random(4, max_sequence + 1); // pick new sequence length, at least 4 in sequence 118 for (i = 1; i <= num_in_sequence; i++) { 119 sequence[i] = random(0, num_switches); // index to switch pin/led array 120 } 121 sequence[0] = num_in_sequence; 122 flash_all_leds(4); 123 delay(2000); 124 play_sequence(); 125 start_time = millis(); // set guess timer start time 126} 127 128// 129// flash leds in the order defined by the sequence list 130// 131void play_sequence() { 132 int i; 133 for (i = 1; i <= sequence[0]; i++) { 134 analogWrite(leds[sequence[i]], 255); 135 delay(1000); 136 analogWrite(leds[sequence[i]], 0); 137 delay(1000); 138 } 139} 140 141// 142// check off guessed button presses against the sequence 143// 144bool check_sequence() { 145 int i; 146 for (i = 1; i <= guesses[0]; i++) { 147 if (guesses[i] != sequence[i]) { 148 return !success; 149 } 150 } 151 return success; 152} 153 154// 155// flash given led the given number of times 156// 157void flash_led(int led, int num) { 158 for (int i = 1; i <= num; i++) { 159 analogWrite(led, 255); 160 delay(250); 161 analogWrite(led, 0); 162 delay(250); 163 } 164} 165 166// 167// flash all leds the given number of times to signify game starting 168// 169void flash_all_leds(int n) { 170 int cycle, led, level; 171 n = 2 * n; // because 1 cycle is on then off, hence a x2 factor 172 level = 0; 173 for (cycle = 1; cycle <= n; cycle++) { 174 level = 255 - level; 175 for (led = 0; led < num_switches; led++) { 176 analogWrite(leds[led], level); 177 } 178 delay(250); 179 } 180} 181 182// 183// read the switch connected to the given pin 184// note that this function works in a nonexclusive way 185// and incorporates debounce code 186// 187bool read_switch(int sw) { 188 int switch_pin_reading; 189 switch_pin_reading = digitalRead(switches[sw].switch_pin); 190 if (switch_pin_reading == LOW) { 191 // switch is pressed, so start/restart debounce process 192 switches[sw].switch_pending = true; 193 switches[sw].elapse_timer = millis(); // start elapse timing 194 return !switched; // now waiting for debounce to conclude 195 } 196 if (switches[sw].switch_pending && switch_pin_reading == HIGH) { 197 // switch was pressed, now released, so check if debounce time elapsed 198 if (millis() - switches[sw].elapse_timer > debounce) { 199 // dounce time elapsed, so switch press cycle complete 200 switches[sw].switch_pending = false; 201 return switched; 202 } 203 } 204 return !switched; 205} 206
Downloadable files
Buttons & Lights Game Schematic
Buttons & Lights Game Schematic
Buttons & Lights Circuit Diagram
Buttons & Lights Circuit Diagram
Buttons & Lights Game Schematic
Buttons & Lights Game Schematic
Buttons & Lights Circuit Diagram
Buttons & Lights Circuit Diagram
Comments
Only logged in users can leave comments