マカロニペンギンの健忘録

特にテーマを決めているわけじゃないが、私が気になったことを書いていく予定です。

電子工作でSIMONゲームを作ってみた。プログラム編

2012年12月23日 | 電子工作
このSIMONというゲームをArduinoを使って電子工作してみました。
同じように作りたいという人のために説明編回路図編とプログラム編に分けて、今回の電子工作を公開しています。
このブログはプログラム編です。


#define LED_RED 0
#define LED_GREEN 1
#define LED_BLUE 2
#define LED_YELLOW 3
#define FAILURE 9
#define LED_RED_PIN 10
#define LED_GREEN_PIN 11
#define LED_BLUE_PIN 12
#define LED_YELLOW_PIN 13
#define RELAY 4
#define BUTTON_RED_PIN 6
#define BUTTON_GREEN_PIN 7
#define BUTTON_BLUE_PIN 8
#define BUTTON_YELLOW_PIN 9
#define TIME_LIMIT 300
#define MOVE_TO_WIN 8
#define MARK_OF_LOST false
#define MARK_OF_WIN true

int moves[32];
int nmoves = 0;
int leave_counter;

void setup() {
pinMode(LED_RED_PIN, OUTPUT);
pinMode(LED_GREEN_PIN, OUTPUT);
pinMode(LED_BLUE_PIN, OUTPUT);
pinMode(LED_YELLOW_PIN, OUTPUT);
pinMode(BUTTON_RED_PIN, INPUT);
pinMode(BUTTON_GREEN_PIN, INPUT);
pinMode(BUTTON_BLUE_PIN, INPUT);
pinMode(BUTTON_YELLOW_PIN, INPUT);
pinMode(RELAY,OUTPUT);
digitalWrite(RELAY,HIGH);
play_winner(3);
randomSeed(analogRead(0));
}

void loop() {
delay(1000);
if (game_mode() == MARK_OF_WIN){
play_winner(10);
}else{
play_loser();
}
}

void led_all_switch_on(){
for ( int i = 0 ; i <= 25 ; ++i){
for ( int j = 0 ; j<= 3 ; ++j){
set_leds(j);
delay(1);
}
}
}

void play_loser(){
for (int i = 0; i <=5 ;++ i){
led_all_switch_on();
set_leds(4);
delay(100);
}
}

void play_winner(int count){
for ( int i = 0 ; i <= count ; ++i){
set_leds(0);
delay(80);
set_leds(1);
delay(80);
set_leds(3);
delay(80);
set_leds(2);
delay(80);
set_leds(4);
}
}

//問題を表示する
void play_moves(){
for (int c_move = 0 ; c_move < nmoves ; ++c_move){
set_leds(moves[c_move]);
delay(200);
set_leds(4);
delay(200);
}
}

//新しい色を加える
void add_to_moves(){
int new_button;
moves[nmoves] = random(4);
++nmoves;
}

// ボタンが押されるか、タイムアウトまで待つ。返り値は0から3までの色かFAILURE=9のどれか。
int wait_for_button(){
int old_button = FAILURE;
int time_limit = TIME_LIMIT;
while( time_limit > 0){
int button;
button = check_button();
if (((old_button == 0)||(old_button == 1)||(old_button == 2)||(old_button == 3))&&(button == FAILURE)){
return old_button;
}
old_button = button;
delay(10);
--time_limit;
}
return FAILURE;
}

//ゲームのメインサブルーチン
boolean game_mode(){
nmoves= 0;
while ( nmoves < MOVE_TO_WIN){
add_to_moves();
play_moves();
for ( int c_move = 0 ; c_move < nmoves ; ++c_move){
int choice = wait_for_button();
if (choice == FAILURE) {
//リレーを操作 auto power off
if (nmoves == 1) {
++leave_counter ;
if (leave_counter >= 5) digitalWrite(RELAY,LOW);
}else leave_counter =0;
//
return MARK_OF_LOST;
}

set_leds(choice);
delay(200);
if (choice != moves[c_move]) return MARK_OF_LOST;
set_leds(4);
}
delay(1000);
}
return MARK_OF_WIN;
}

//ボタンをチェック。0~3の色かFAILURE=9の返り値
int check_button(){
int i = FAILURE;
if (digitalRead(BUTTON_RED_PIN) == HIGH){
delay(10);
i = LED_RED;
}
if (digitalRead(BUTTON_GREEN_PIN) == HIGH){
delay(10);
i = LED_GREEN;
}
if (digitalRead(BUTTON_BLUE_PIN) == HIGH){
delay(10);
i = LED_BLUE;
}
if (digitalRead(BUTTON_YELLOW_PIN) == HIGH){
delay(10);
i = LED_YELLOW;
}
return i;
}

//LEDの表示。返り値なし
void set_leds(int leds){
digitalWrite(LED_RED_PIN,LOW);
digitalWrite(LED_GREEN_PIN,LOW);
digitalWrite(LED_BLUE_PIN,LOW);
digitalWrite(LED_YELLOW_PIN,LOW);
switch (leds){
case 0:
digitalWrite(LED_RED_PIN,HIGH);
break;
case 1:
digitalWrite(LED_GREEN_PIN,HIGH);
break;
case 2:
digitalWrite(LED_BLUE_PIN,HIGH);
break;
case 3:
digitalWrite(LED_YELLOW_PIN,HIGH);
break;
}
}


最新の画像もっと見る

コメントを投稿