LED Game Candle Panic details here https://kohacraft.com/candlepanic

Dependencies:   mbed

main.cpp

Committer:
kohacraft
Date:
2020-08-30
Revision:
0:ec192cf5acd1

File content as of revision 0:ec192cf5acd1:

/*
    candle panic
    キャンドル パニック
    
    詳しくはこちら
    https://kohacraft.com/candlepanic

    public domain
*/

#include "mbed.h"

//LED&光センサー
#define ArrayNum 8
DigitalOut ledK[ArrayNum] = { dp1, dp2, dp4, dp6, dp9, dp10, dp13, dp14};
DigitalOut ledA(dp11);
DigitalIn ledSensor(dp15);
DigitalOut flash(dp5);
bool sensorArray[ArrayNum] = { 0, 0, 0, 0, 0, 0, 0, 0 };
bool ledArray[ArrayNum] = { 0, 0, 0, 0, 0, 0, 0, 0 };
#define LedA_Led 0       //LEDをLEDモードにする
#define LedA_Sensor 1    //LEDをセンサーモードにする

//サウンド
#define C1 1/261.626
#define D1 1/293.665
#define E1 1/329.628
#define F1 1/349.228
#define G1 1/391.995
#define A1 1/440.000
#define B1 1/493.883
#define C2 C1/2
#define D2 D1/2
#define E2 E1/2
#define F2 F1/2
#define G2 G1/2
#define A2 A1/2
#define B2 B1/2
const float tone[] = { C1, D1, E1, F1, G1, A1, B1, C2, D2, E2, F2, G2, A2, B2 }; 
PwmOut sp(dp18);
bool offBeepOn = 0; //LEDがOFFするときの音を出す
bool onBeepOn = 0; //LEDがONするときの音を出す
int beepDevide = 30;

int loopCount = 0; 
int offCount = 500; //loopCountがこの値になったらLEDを一つ消す
int speedUpCount = 30;  //loopCountがこの値になったらOffCountを減らす   
int goleOffCount = 50; //offCountがこの値になったらゲームクリア

DigitalOut led(dp17);

void lightDetect();
void beep(float);
void showLed();
void offBeep();
void onBeep();

int main() {
            
            
    //初期化
    for( int i=0 ; i< ArrayNum ; i++ )
    {
        ledK[i] = 1;
        ledArray[i] = 0;
    }
    flash = 1;

    //LEDを順番に点灯しながら音を鳴らす
    
    for( int i=0 ; i< ArrayNum ; i++ )
    {
        ledArray[i] = 1;
        showLed();
        beep( tone[i] );
        wait( 0.1 );
    }
    beep( 0 );
    
    int offCounter = 0;
    while(1) {
        
        //ランダムにどれか1つ消灯する
        if( offCounter > offCount )
        {
            while(1)
            {
                float numFloat = (float)rand()/RAND_MAX * ( ArrayNum - 1 );
                int num = int( numFloat + 0.5 );
                if( ledArray[ num ] == 1 )
                {
                    ledArray[ num ] = 0;
                    break;
                }
            }
            
            offBeepOn = 1;
            offCounter = 0;
        }
        offCounter++;

        showLed();
                
        lightDetect();    //センサ状態を取得
        for( int i=0 ; i< ArrayNum ; i++ )
        {
            if( ledArray[i] == 0 && sensorArray[i] == 1 )
            {
                ledArray[i] = 1;
                onBeepOn = 1;
            }
        }
        showLed();
        
        //全部消えたら終わり
        int result = 0;
        for( int i=0 ; i< ArrayNum ; i++ )
        {
            result += ledArray[i];
        }
        if( result == 0 )
        {
            break;
        }

        onBeep();
        offBeep();
        
        wait(0.002);
        loopCount++;
        if( loopCount%speedUpCount == 0 )
        {
            offCount--;
            if( offCount < goleOffCount )
                break;
        }
                
    }
    
    if( offCount >= goleOffCount )
    {
        //失敗
        beep( C1 );
        wait( 0.2 );
        beep( 0 );
        wait( 0.2 );
        beep( C1 );
        wait( 1 );
        beep( 0 );
    
    }
    else
    {
        //成功
        for( int j=0 ; j<3 ; j++ )
        {
            for( int i=7 ; i<15 ; i++ )
            {
                beep(tone[i]);
                wait( 0.05 );
            }
        }
        beep(0);
        
        while(1)
        {
            for( int i=0 ; i< ArrayNum ; i++ )
                ledArray[i] = 1;
            showLed();
            wait(0.2);
            
            for( int i=0 ; i< ArrayNum ; i++ )
                ledArray[i] = 0;
            showLed();
            wait(0.2);
        }        
    }
    while(1)
    {
        ;
    }
}

//光センサとして光を検知する
void lightDetect()
{
    ledA = LedA_Sensor;   //光センサのモードにする
    for( int i=0 ; i < ArrayNum ; i++ )  //全てのセンサをOFFにする
    {
        ledK[i] = 0;
        sensorArray[i] = 0;
    }
    
    for( int i=0 ; i < ArrayNum ; i++ )
    {        
        flash = 0;
        wait(0.0001);
        flash = 1;
        
        ledK[i] = 1;    //特定のセンサのみONにする
        wait(0.0001);
        bool res = ledSensor; //センサの状態を読み込む
        if( res == 0 )
            sensorArray[i] = 1;
        else
            sensorArray[i] = 0;
        ledK[i] = 0;    //特定のセンサをOFFにする
    }
    return;
}

//指定した周期でピープを鳴らす 0ならOFF
void beep( float scale )
{
        if( scale != 0 )
        {
            sp.period(scale);
            sp.write(0.5f);
        }
        else
        {
            sp.write(0.0f);
        }
}

//ledArrayにしたがってLEDを点灯する
void showLed()
{
    for( int i=0 ; i<ArrayNum ; i++ )
    {
        if( ledArray[i] == 1)
        {
            ledK[i] = 0;
        }
        else
        {
            ledK[i] = 1;
        }
    }
    ledA = LedA_Led;   //LEDのモードにする
}

//LEDがOFFするときのサウンド
bool offBeepRun = 0;
int offBeepCount = 0;
int offMelodyCounter = 0;
void offBeep()
{
    int melodyLength = 2;
    float melody[2] = { D1, C1 };
    
    if( offBeepOn == 1 )
    {
        offBeepOn = 0;
        offBeepRun = 1;
        offBeepCount = 0;
        offMelodyCounter = 0;
    }
        
    if( offBeepRun == 1 )
    {
        if( offBeepCount%beepDevide == 0 )
        {
            if( offMelodyCounter < melodyLength )
            {
                //メロディの長さ以下だったら音を鳴らす
                beep( melody[ offMelodyCounter++ ] );
            }
            else
            {   
                //音を止める
                beep(0);
                offBeepRun = 0;
            }
        }
        
        offBeepCount++;
        return;
    }
    
    return;
}

//LEDがONするときのサウンド
bool onBeepRun = 0;
int onBeepCount = 0;
int onMelodyCounter = 0;
void onBeep()
{
    int melodyLength = 2;
    float melody[2] = { C2, D2 };
    
    if( onBeepOn == 1 )
    {
        onBeepOn = 0;
        onBeepRun = 1;
        onBeepCount = 0;
        onMelodyCounter = 0;
    }
        
    if( onBeepRun == 1 )
    {
        if( onBeepCount%beepDevide == 0 )
        {
            if( onMelodyCounter < melodyLength )
            {
                //メロディの長さ以下だったら音を鳴らす
                beep( melody[ onMelodyCounter++ ] );
            }
            else
            {   
                //音を止める
                beep(0);
                onBeepRun = 0;
            }
        }
        
        onBeepCount++;
        return;
    }
    
    return;
}