Created
October 2, 2016 07:48
-
-
Save pinglunliao/cf957c88691e90835a91adfa148dbf9c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 程式碼參考來源 https://github.com/SJHOne/MintDuino-Repeat-After-Me-Game | |
*/ | |
#define BUTTON_BASE 2 // 按鈕腳位 2 ~ 4 | |
#define BUZZER_PIN 6 // 蜂鳴器腳位 6 | |
#define LED_BASE 7 // LED 腳位 7 ~ 9 | |
#define WINSTATE 12 // 在一回合中,最多需要回答 12 次的聲音頻率,須為 4 的倍數 | |
#define RESPONSETIME 3000 // 每回合中,回答每個聲音頻率之間的等待時間 | |
int band = WINSTATE / 4; // 遊戲結束後,判斷等級用 | |
int turn = 0; // 每回合需要回的聲音頻率次數 | |
int input1 = LOW; // 按鈕一按下的狀態 | |
int input2 = LOW; // 按鈕一按下的狀態 | |
int input3 = LOW; // 按鈕一按下的狀態 | |
int counter = 0; // 目前等了多久時間 | |
int beepdelay = 200; | |
int pausedelay = 100; | |
int randomArray[100]; //Intentionally long to store up to 100 inputs (doubtful anyone will get this far) | |
int tonearray[3]; | |
void ProcessSingleOutput(int value); | |
void playTone(int tone, int duration); | |
void fail(int correct); | |
void FlashAll(); | |
/////////////////////////////////////////////////////////////////////////// | |
void setup() { | |
Serial.begin(9600); | |
pinMode(BUZZER_PIN, OUTPUT); | |
tonearray[0] = 1915; | |
tonearray[1] = 1519; | |
tonearray[2] = 1275; | |
for (int f = 0; f < 3; f++) | |
{ | |
pinMode(LED_BASE + f, OUTPUT); | |
pinMode(BUTTON_BASE+ f, INPUT); | |
digitalWrite(BUTTON_BASE+ f, HIGH); // turn on pullup resistors | |
ProcessSingleOutput(f+1); | |
} | |
randomSeed(analogRead(0)); // Added to generate "more randomness" with the randomArray for the output function | |
delay(1000); | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
void ProcessSingleOutput(int value) | |
{ | |
value--; | |
digitalWrite(LED_BASE + value, HIGH); | |
playTone(tonearray[value], beepdelay); // Passes tone value and duration of the tone to the playTone function | |
delay(beepdelay); | |
digitalWrite(LED_BASE + value, LOW); | |
delay(pausedelay); | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// function for generating the array to be matched by the player | |
void output() | |
{ | |
Serial.println(""); | |
Serial.print("Turn: "); | |
Serial.println(turn); | |
randomArray[turn] = random(1, 4); // Assigning a random number (1-3) to the randomArray[y], y being the turn count | |
for (int x = 0; x <= turn; x++) | |
{ | |
Serial.print(randomArray[x]); | |
Serial.print(" "); | |
ProcessSingleOutput(randomArray[x]); | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
void ProcessSingleInput(int value, int x) | |
{ | |
digitalWrite(LED_BASE + value, HIGH); | |
playTone(tonearray[value], 200); // Passes tone value and duration of the tone to the playTone function | |
delay(200); | |
digitalWrite(LED_BASE + value, LOW); | |
delay(50); | |
Serial.print(" "); | |
Serial.print(value+1); | |
if ((value+1) != randomArray[x]) | |
{ | |
fail(randomArray[x]); | |
} else { | |
counter = 0; | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// Function for allowing user input and checking input against the generated array | |
void input() | |
{ | |
for (int x = 0; x <= turn;) | |
{ | |
input1 = digitalRead(BUTTON_BASE); | |
input2 = digitalRead(BUTTON_BASE+1); | |
input3 = digitalRead(BUTTON_BASE+2); | |
counter++; | |
if (counter > RESPONSETIME) | |
{ | |
Serial.println("TIMEOUT!"); | |
fail(randomArray[x]); | |
x++; | |
} | |
delay(1); | |
if (input1 == HIGH) | |
{ | |
ProcessSingleInput(0, x); | |
x++; | |
} | |
if (input2 == HIGH) | |
{ | |
ProcessSingleInput(1, x); | |
x++; | |
} | |
if (input3 == HIGH) | |
{ | |
ProcessSingleInput(2, x); | |
x++; | |
} | |
} | |
delay(500); | |
turn++; // Increments the turn count, also the last action before starting the output function over again | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// Function used if the player fails to match the sequence | |
void fail(int correct) | |
{ | |
digitalWrite(LED_BASE, HIGH); | |
digitalWrite(LED_BASE+1, HIGH); | |
digitalWrite(LED_BASE+2, HIGH); | |
playTone(6000,1000); // Rather Rude Rasp | |
digitalWrite(LED_BASE, LOW); | |
digitalWrite(LED_BASE+1, LOW); | |
digitalWrite(LED_BASE+2, LOW); | |
correct--; | |
for (int y = 0; y <= 2; y++) | |
{ | |
// Flashes light that should have been pressed | |
digitalWrite(LED_BASE + correct, HIGH); | |
//playTone(tonearray[correct], 200); | |
delay(200); | |
digitalWrite(LED_BASE + correct, LOW); | |
delay(50); | |
} | |
Serial.println(""); | |
Serial.print("OOPS! Should have pressed "); | |
Serial.println(correct+1); | |
delay(500); | |
// Now Score | |
// 1 - Beginner | |
// 2 - Amateur | |
// 3 - Expert | |
// 4 - Champ | |
int scoreband = turn / band; | |
for (int y=0; y<=5; y++) | |
{ | |
// Flashes score light | |
digitalWrite(LED_BASE + scoreband, HIGH); | |
playTone(tonearray[scoreband], 200); | |
digitalWrite(LED_BASE + scoreband, LOW); | |
delay(50); | |
} | |
Serial.print("You Score "); | |
Serial.println(scoreband+1); | |
delay(500); | |
FlashAll(); | |
delay(500); | |
turn = -1; // Resets turn value so the game starts over without need for a reset button | |
counter = 0; | |
beepdelay = 200; | |
pausedelay = 100; | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
void win() | |
{ | |
Serial.println("WIN!"); | |
for (int y=0; y < 4; y++) | |
{ | |
for (int f = 0; f < 3; f++) | |
{ | |
digitalWrite(LED_BASE + f, HIGH); | |
playTone(tonearray[f], 100); | |
digitalWrite(LED_BASE + f, LOW); | |
delay(25); | |
} | |
} | |
FlashAll(); | |
turn = -1; // Resets turn value so the game starts over without need for a reset button | |
beepdelay = 200; | |
pausedelay = 100; | |
delay(1000); | |
} | |
void FlashAll() | |
{ | |
/////////////////////////////////////////////////////////////////////////// | |
// Flashes all lights | |
for (int y=0; y<=5; y++) | |
{ | |
digitalWrite(LED_BASE, HIGH); | |
digitalWrite(LED_BASE+1, HIGH); | |
digitalWrite(LED_BASE+2, HIGH); | |
delay(200); | |
digitalWrite(LED_BASE, LOW); | |
digitalWrite(LED_BASE+1, LOW); | |
digitalWrite(LED_BASE+2, LOW); | |
delay(200); | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// Low C = 1915 | |
// D = 1700 | |
// E = 1519 | |
// F = 1432 | |
// G = 1275 | |
// A = 1136 | |
// B = 1014 | |
// High C = 956 | |
void playTone(int tone, int duration) | |
{ | |
for (long i = 0; i < duration * 1000L; i += tone * 2) | |
{ | |
digitalWrite(BUZZER_PIN, HIGH); | |
delayMicroseconds(tone); | |
digitalWrite(BUZZER_PIN, LOW); | |
delayMicroseconds(tone); | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
// Slowly cranks up the pressure | |
void increaseSpeed() | |
{ | |
if (turn == band) | |
{ | |
beepdelay = 170; | |
pausedelay = 80; | |
return; | |
} | |
if (turn == band * 2) | |
{ | |
beepdelay = 150; | |
pausedelay = 60; | |
return; | |
} | |
if (turn == band*3) | |
{ | |
beepdelay = 120; | |
pausedelay = 40; | |
} | |
} | |
/////////////////////////////////////////////////////////////////////////// | |
void loop() | |
{ | |
output(); | |
input(); | |
increaseSpeed(); | |
if( turn >= WINSTATE ) { | |
win(); | |
turn = -1; | |
counter = 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment