forked from NattyBumppo/Simon-Clone-for-Arduino
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GameMode.cpp
191 lines (160 loc) · 3.83 KB
/
GameMode.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include "Modes.h"
#include "Output.h"
#include "Input.h"
// Gameplay elements
const int easyModeTurns = 7;
const int hardModeTurns = 11;
const int superHardModeTurns = 15;
// easy hard secret
const int turnsToWin[] = { 7, 11, 15 };
const int ledDisplayTime[] = { 200, 200, 75 };
const int lightDelay[] = { 200, 200, 75 };
const int fireworksCount[] = { 0, 3, 6 };
class State :
public Mode
{
public:
State(GameMode& game);
virtual Mode* Update(int dT);
protected:
GameMode& mGame;
};
class ShowSeqState :
public State
{
public:
ShowSeqState(GameMode& game);
virtual Mode* Update(int dT);
private:
int seqShow;
int time;
};
class ReadSeqState :
public State
{
public:
ReadSeqState(GameMode& game);
virtual Mode* Update(int dT);
private:
int correct;
};
State::State(GameMode& game)
:
mGame(game)
{
}
/////////////////////////////////////////////////
// Showing the Sequence
ShowSeqState::ShowSeqState(GameMode& game)
:
State(game),
seqShow(0),
time(0)
{
mGame.colorChain[mGame.turnNo] = (Color)random(0,4);
++mGame.turnNo;
}
Mode* ShowSeqState::Update(int dT)
{
time += dT;
if((mGame.LEDDisplayTime + mGame.delayBetweenLights) * seqShow < time)
{
// enough time has passed, we should start the next light/sound in the sequence:
Output::Get().LightOn(mGame.colorChain[seqShow], mGame.LEDDisplayTime);
Output::Get().SetTone(mGame.colorChain[seqShow], mGame.LEDDisplayTime);
}
seqShow++;
if(seqShow == mGame.turnNo)
{
// hit the end of the sequence, transition to reading input state:
return new ReadSeqState(mGame);
}
return this;
}
/////////////////////////////////////////////////
// Reading the Sequence
ReadSeqState::ReadSeqState(GameMode& game)
:
State(game),
correct(0)
{
}
Mode* ReadSeqState::Update(int dT)
{
// turn off lights/sounds as they're released.
int released = Input::Get().Released();
if(released)
{
if(released & Input::Get().SNESCode(RED))
Output::Get().LightOff(RED);
if(released & Input::Get().SNESCode(GREEN))
Output::Get().LightOff(GREEN);
if(released & Input::Get().SNESCode(BLUE))
Output::Get().LightOff(BLUE);
if(released & Input::Get().SNESCode(YELLOW))
Output::Get().LightOff(YELLOW);
}
// handle new input
int pressed = Input::Get().Pressed();
if(pressed)
{
Color expectedColor = mGame.colorChain[correct];
if(pressed == Input::Get().SNESCode(expectedColor))
{
Output::Get().LightOn(expectedColor);
++correct;
}
else
{
mGame.condition = GameMode::Defeat;
}
}
if(correct == mGame.turnNo)
{
if(correct == mGame.turnsUntilWin)
mGame.condition = GameMode::Victory;
return new ShowSeqState(mGame);
}
return this;
}
// when input is received:
// play the light/color that they're pressing
// if it's right:
// if the sequence is not yet complete:
// keep going
// else, sequence is done:
// transition to playing back sequence / win
// if it's wrong:
// transition to losing melody
/////////////////////////////////////////////////
// Game
GameMode::GameMode(Difficulty difficulty)
:
condition(StillPlaying),
turnNo(0)
{
turnsUntilWin = turnsToWin[difficulty];
LEDDisplayTime = ledDisplayTime[difficulty];
delayBetweenLights = lightDelay[difficulty];
fireworks = fireworksCount[difficulty];
}
Mode* GameMode::Update(int dT)
{
// Manage our own state -- waiting for input, or playing back a sequence.
State* newState = (State*)curState->Update(dT);
if(newState != curState)
{
delete curState;
curState = newState;
}
switch(condition)
{
case Victory:
return new MelodyMode((Melody)(WIN + fireworks), new AttractMode());
break;
case Defeat:
return new MelodyMode(LOSE, new AttractMode());
break;
}
return this;
}