Skip to content

Instantly share code, notes, and snippets.

@pinglunliao
Created October 2, 2016 07:48
Show Gist options
  • Save pinglunliao/cf957c88691e90835a91adfa148dbf9c to your computer and use it in GitHub Desktop.
Save pinglunliao/cf957c88691e90835a91adfa148dbf9c to your computer and use it in GitHub Desktop.
/*
* 程式碼參考來源 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