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