-
Notifications
You must be signed in to change notification settings - Fork 0
/
SimonGame_v2.0.py
182 lines (157 loc) · 5.26 KB
/
SimonGame_v2.0.py
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
# Circuit Playground Express Simon Game
#
# Author: David Mendez
# MIT License (https://opensource.org/licenses/MIT)
import time
import random
import math
import board
from analogio import AnalogIn
from adafruit_circuitplayground.express import cpx
cpx.pixels.brightness = 0.1 # adjust NeoPixel brightness to your liking
FAILURE_TONE = 100
SEQUENCE_DELAY = 0.8
GUESS_TIMEOUT = 3.0
DEBOUNCE = 0.250
SEQUENCE_LENGTH = {
1 : 8,
2 : 14,
3 : 20,
4 : 31
}
SIMON_BUTTONS = {
1 : { 'pads':(4,5), 'pixels':(0,1,2), 'color':0x00FF00, 'freq':415 },
2 : { 'pads':(6,7), 'pixels':(2,3,4), 'color':0xFFFF00, 'freq':252 },
3 : { 'pads':(1, ), 'pixels':(5,6,7), 'color':0x0000FF, 'freq':209 },
4 : { 'pads':(2,3), 'pixels':(7,8,9), 'color':0xFF0000, 'freq':310 },
}
def choose_skill_level():
# Default
skill_level = 1
# Loop until button B is pressed
while not cpx.button_b:
# Button A increases skill level setting
if cpx.button_a:
skill_level += 1
skill_level = skill_level if skill_level < 5 else 1
# Indicate current skill level
cpx.pixels.fill(0)
for p in range(skill_level):
cpx.pixels[p] = 0xFFFFFF
time.sleep(DEBOUNCE)
return skill_level
def new_game(skill_level):
# Seed the random function with noise
a4 = AnalogIn(board.A4)
a5 = AnalogIn(board.A5)
a6 = AnalogIn(board.A6)
a7 = AnalogIn(board.A7)
seed = a4.value
seed += a5.value
seed += a6.value
seed += a7.value
random.seed(seed)
# Populate the game sequence
return [random.randint(1,4) for i in range(SEQUENCE_LENGTH[skill_level])]
def indicate_button(button, duration):
# Turn them all off
cpx.pixels.fill(0)
# Turn on the ones for the given button
for p in button['pixels']:
cpx.pixels[p] = button['color']
# Play button tone
if button['freq'] == None:
time.sleep(duration)
else:
cpx.play_tone(button['freq'], duration)
# Turn them all off again
cpx.pixels.fill(0)
def show_sequence(sequence, step):
# Set tone playback duration based on current location
if step <= 5:
duration = 0.420
elif step <= 13:
duration = 0.320
else:
duration = 0.220
# Play back sequence up to current step
for b in range(step):
time.sleep(0.05)
indicate_button(SIMON_BUTTONS[sequence[b]], duration)
def cap_map(b):
if b == 1: return cpx.touch_A1
if b == 2: return cpx.touch_A2
if b == 3: return cpx.touch_A3
if b == 4: return cpx.touch_A4
if b == 5: return cpx.touch_A5
if b == 6: return cpx.touch_A6
if b == 7: return cpx.touch_A7
def get_button_press():
# Loop over all the buttons
for button in SIMON_BUTTONS.values():
# Loop over each pad
for pad in button['pads']:
if cap_map(pad):
indicate_button(button, DEBOUNCE)
return button
return None
def game_lost(step):
# Show button that should have been pressed
cpx.pixels.fill(0)
for p in SIMON_BUTTONS[sequence[step]]['pixels']:
cpx.pixels[p] = SIMON_BUTTONS[sequence[step]]['color']
# Play sad sound :(
cpx.play_tone(FAILURE_TONE, 1.5)
# And just sit here until reset
while True:
pass
def game_won():
# Play 'razz' special victory signal
for i in range(3):
indicate_button(SIMON_BUTTONS[4], 0.1)
indicate_button(SIMON_BUTTONS[2], 0.1)
indicate_button(SIMON_BUTTONS[3], 0.1)
indicate_button(SIMON_BUTTONS[1], 0.1)
indicate_button(SIMON_BUTTONS[4], 0.1)
indicate_button(SIMON_BUTTONS[2], 0.1)
# Change tones to failure tone
for button in SIMON_BUTTONS.values():
button['freq'] = FAILURE_TONE
# Continue for another 0.8 seconds
for i in range(2):
indicate_button(SIMON_BUTTONS[3], 0.1)
indicate_button(SIMON_BUTTONS[1], 0.1)
indicate_button(SIMON_BUTTONS[4], 0.1)
indicate_button(SIMON_BUTTONS[2], 0.1)
# Change tones to silence
for button in SIMON_BUTTONS.values():
button['freq'] = None
# Loop lights forever
while True:
indicate_button(SIMON_BUTTONS[3], 0.1)
indicate_button(SIMON_BUTTONS[1], 0.1)
indicate_button(SIMON_BUTTONS[4], 0.1)
indicate_button(SIMON_BUTTONS[2], 0.1)
# Initialize setup
cpx.pixels.fill(0)
cpx.pixels[0] = 0xFFFFFF
skill_level = choose_skill_level()
sequence = new_game(skill_level)
current_step = 1
while True:
# Show sequence up to current step
show_sequence(sequence, current_step)
# Read player button presses
for step in range(current_step):
start_guess_time = time.monotonic()
guess = None
while (time.monotonic() - start_guess_time < GUESS_TIMEOUT) and (guess == None):
guess = get_button_press()
if not guess == SIMON_BUTTONS[sequence[step]]:
game_lost(sequence[step])
# Advance the game forward
current_step += 1
if current_step > len(sequence):
game_won()
# Small delay before continuing
time.sleep(SEQUENCE_DELAY)