View difference between Paste ID: guFvKLxU and 3UTSRM1j
SHOW: | | - or go back to the newest paste.
1
const unsigned char BUTTON_PIN = 0;
2
const unsigned char LED_PIN_1 =  11;
3
const unsigned char LED_PIN_2 =  10;
4
const unsigned char LED_PIN_3 =  9;
5
const int BUTTON_VALUE_1 = 1015;
6
const int BUTTON_VALUE_2 = 925;
7
const int BUTTON_VALUE_3 = 845;
8
9
// GLOBAL
10
int currentReading;
11
unsigned long currentTimer;
12
13
// GAME VARS
14
unsigned char gameCombination[100];
15
unsigned long gameTimer = 0;
16
unsigned char gameState = 0;
17
unsigned char gameLevel = 0;
18
unsigned char gameAccel = 25;
19
unsigned char gameStep = 0;
20
unsigned char gameInputDelay = 150;
21
int gameStateDelay = 1000;
22
int gameMinDelay = 500;
23
24
// LED Light
25
class Light {
26
    unsigned char pin;
27
    unsigned long timerCheck; // checks led timing
28
29
    unsigned char ledState; // led current state
30
31
    public:
32
        Light() = default;
33
        Light(unsigned char p) { // pin number
34
            pin = p;
35
            ledState = 0; // off by default
36
37
            timerCheck = 0;
38
39
            pinMode(pin, OUTPUT);
40
        }
41
42
        unsigned char getPin() {
43
            return pin;
44
        }
45
46
        void blink(unsigned long onTime) {
47
            timerCheck = currentTimer + onTime;
48
            ledState = 1;
49
            digitalWrite(pin, HIGH);
50
        }
51
52
        void update() {
53
            // Check if led is on and if its time to switch it off yet
54
            if (ledState == 1) {
55
                if (timerCheck < currentTimer) {
56
                    digitalWrite(pin, LOW);
57
                    ledState = 0;
58
                }
59
            }
60
61
        }
62
};
63
64
// BUTTON
65
class Button {
66
    int triggerValue; // trigger value
67
    unsigned char triggerFlac; // trigger flactuation
68
    unsigned char inputDelay; // debounce delay
69
70
    unsigned char buttonPressed; // button state
71
    unsigned char debounce;
72
73
    public:
74
        
75
        Button() = default;
76
        Button(int tV) : triggerValue{tV} {
77
            debounce = 0;
78
            buttonPressed = 0; 
79
80
            triggerFlac = 40;
81
            inputDelay = 150;
82
        }
83
84
        unsigned char isPressed() {
85
            return buttonPressed;
86
        }
87
88
        void update() {
89
90
            // Check current reading
91
            if (currentReading > triggerValue - triggerFlac && currentReading < triggerValue + triggerFlac) {
92
                debounce++;
93
            } else {
94
                debounce = 0;
95
                buttonPressed = 0;
96
            }
97
98
            // The button state is changed if the reading is within
99
            // the trigger value boundaries for a certain amount of time
100
            if (debounce > inputDelay) {
101
                buttonPressed = 1;
102
            }
103
104
        }
105
};
106
107
// UTILS
108
void _delay(int dl) {
109
    gameTimer = currentTimer + dl;
110
}
111
112
113
114
// GAME LIGHTS
115
Light gameLights[] = {
116
    Light(LED_PIN_1),
117
    Light(LED_PIN_2),
118
    Light(LED_PIN_3)
119
};
120
121
// GAME BUTTONS
122
Button gameButtons[] = {
123
    Button(BUTTON_VALUE_1),
124
    Button(BUTTON_VALUE_2),
125
    Button(BUTTON_VALUE_3)
126
};
127
128
129
// SETUP
130
void setup() {
131
132
    pinMode(BUTTON_PIN, INPUT);
133
134
    // RANDOMIZER
135
    randomSeed(analogRead(5));
136
137
}
138
139
// TODO: Refactor
140
// this is currently wathing the last user input
141
unsigned char lastUserInput;
142
143
144
// LOOP
145
void loop() {
146
147
    currentReading = analogRead(BUTTON_PIN);
148
    currentTimer = millis();
149
150
    if (gameTimer < currentTimer) {
151
152
        // STATE :: Start game
153
        if (gameState == 0) {
154-
            // play intro
154+
155-
            if (gameStep < 3) {
155+
156
            gameState = 1;
157
            gameStep = 0;
158
            _delay(gameStateDelay);
159
        }
160
161
        // STATE :: Set combination
162
        if (gameState == 1) {
163
            // add new random number to current combination
164
            gameCombination[gameLevel] = random(3);
165
            gameLevel = gameLevel + 1;
166
            gameStep = 0; // reset step
167
            if (gameStateDelay > gameMinDelay) {
168
                gameStateDelay -= gameAccel; // decrease game intervals
169
            }
170
            _delay(gameStateDelay);
171
            gameState = 2; // ->> go to STATE 2
172
        }
173
    
174
        // STATE :: Play current combination
175
        else if (gameState == 2) {
176
            if (gameStep < gameLevel) {
177
                gameLights[gameCombination[gameStep]].blink(150);
178
                gameStep = gameStep + 1;
179
                _delay(gameStateDelay);
180
            }
181
            else {
182
                gameStep = 0;
183
                gameState = 3; // ->> go to STATE 3
184
                _delay(gameInputDelay);
185
            }
186
        }
187
    
188
        // STATE :: User input
189
        else if (gameState == 3) {
190
            if (gameStep < gameLevel) {
191
                
192
                // cycle through all buttons
193
                for (unsigned char i = 0; i < 3; i++) {
194
                    gameButtons[i].update(); // update each button
195
196
                    // BUTTON PRESSED
197
                    if (gameButtons[i].isPressed() == 1) {
198
                        if (lastUserInput != i) {
199
                            lastUserInput = i;
200
201
                            gameLights[i].blink(150);
202
203
                            if (gameCombination[gameStep] == i) {
204
                                // correct press
205
                                gameStep++;
206
                                _delay(gameInputDelay);
207
                            }
208
                            else {
209
                                // wrong press
210
                                gameLevel = gameStep; // used for blinking this led on game over
211
                                gameStep = 0;
212
                                gameState = 4; // ->> got to STATE 4
213
                            }
214
                        }
215
    
216
                        break;
217
                    }
218
                    else if (i == 2) { // Reached last button
219
                        // reset user input because none of the buttons are pressed
220
                        lastUserInput = 255; 
221
                    }
222
                }
223
            }
224
            else { // reached last button - reset user input
225
                gameState = 1; // ->> go to STATE 1
226
            }
227
        }
228
229
        // STATE :: Game over
230
        else if (gameState == 4) {
231
            // blink the correct light 10 times
232
            if (gameStep < 10) {
233
                gameStep++;
234
                gameLights[gameCombination[gameLevel]].blink(100);
235
                _delay(gameStateDelay/5);
236
            }
237
            else {
238
                gameState = 0;  // ->> got to STATE 0
239
                _delay(gameStateDelay);
240
            }
241
        }
242
    }
243
244
245
    for (unsigned char i = 0; i < 3; i++) {
246
        gameLights[i].update();
247
    }
248
249
}