チーム1748

課題名

音階当てゲーム

研究者名

森屋吏記 根本真也

使用器具

PSoc基盤
Miniprog 
シリアル通信用ケーブル
ジャンパー線 2本
スピーカー

内容

このゲームは出題者と回答者の二人で対戦する。

<操作方法>

1.出題者がキーボードで音を鳴らす。

  PC,LCD上にスタートメッセージが表示され、起動音がでたらゲーム開始
  出題者が下記キーから一つキーを押し、エンターキーで出題する音を登録し
  スピーカーよりその音階の音が発生する。
 (a:ド s:レ d:ミ f:ファ g:ソ h:ラ j:シ k:ド に対応する)
※小文字のLを入力するとゲームが終了する
※何文字か押した後エンターを押すと、はじめに押したキーに
対応した音階のみが発生する


2.回答者はその音をよく聴き、答えだと思う音階に対応したキーを押す。

  起動音でドレミの音階が発生するのでよく聞き
 音を頭に入れておくとよい。

3.正解か不正解か、その時点での正解数(スコア)をLCD画面に表示する。

4.3回正解したらゲームクリア、1回間違えるとゲームオーバー

 クリアするとクリア音が流れ、LCD上に「GAME CLEAR」と表示される
 不正解するとゲームオーバー音が流れ、LCD上にメッセージと正解数が表示される

5.ゲームを再開するときはリセットボタンを押す

※以下のような仕様になっています
 LCD画面…回答者用
 PC画面 …出題者用
(入力はどちらもキーボードである)

ソースコード


#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
#include <stdio.h>
#pragma interrupt_handler myISR

int PW=125;
int SILENT=0,D=229,L=204,M=182,F=172,S=153,R=136,C=121,DD=115,LL=102;
int SCORE=0,LIFE=1,CLEAR=3;
int TC = 15,n=2;

void myISR(void)
{
TC += 1;
if(n == 2){ //起動音
PWM16_1_WritePulseWidth(PW);
/******ドレミ******/
if(TC == 1)
PWM16_1_WritePeriod(D);
else if(TC == 2)
PWM16_1_WritePeriod(L);
else if(TC == 3)
PWM16_1_WritePeriod(M);
else if(TC == 4)
PWM16_1_WritePeriod(F);
else if(TC == 5)
PWM16_1_WritePeriod(S);
else if(TC == 6)
PWM16_1_WritePeriod(R);

else if(TC == 7)
PWM16_1_WritePeriod(C);
else if(TC == 8)
PWM16_1_WritePeriod(DD);
else if(TC == 10)
PWM16_1_WritePeriod(SILENT);
 }
else if(n == 1){ //GAME OVER音
PWM16_1_WritePulseWidth(PW);
/******マリオ******/
if(TC == 1)
PWM16_1_WritePeriod(L);
else if(TC == 2)
PWM16_1_WritePeriod(DD);
else if(TC == 3)
PWM16_1_WritePeriod(SILENT);
else if(TC == 4)
PWM16_1_WritePeriod(DD);
else if(TC == 5)
PWM16_1_WritePeriod(DD);
else if(TC == 6)
PWM16_1_WritePeriod(C);

else if(TC == 7)
PWM16_1_WritePeriod(SILENT);
else if(TC == 8)
PWM16_1_WritePeriod(R);
else if(TC == 9)
PWM16_1_WritePeriod(S);
else if(TC == 10)
PWM16_1_WritePeriod(SILENT);
 }
 
else if(n == 0){  //CLEAR音
PWM16_1_WritePulseWidth(M);
/******マリオ******/
if(TC == 1)
PWM16_1_WritePeriod(M);
else if(TC == 2)
PWM16_1_WritePeriod(SILENT);
else if(TC == 3)
PWM16_1_WritePeriod(M);
else if(TC == 4)
PWM16_1_WritePeriod(SILENT);
else if(TC == 5)
PWM16_1_WritePeriod(D);
else if(TC == 6)
PWM16_1_WritePeriod(M);

else if(TC == 7)
PWM16_1_WritePeriod(SILENT);
else if(TC == 8)
PWM16_1_WritePeriod(S);
else if(TC == 9)
PWM16_1_WritePeriod(SILENT);
}
}

void main(void)
{
// M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
  // Insert your main routine code here.
  
  char *strPtr_1;
  char *strPtr_2;
  int answer;          // 正解の音
  int choice;          // 回答した音
  int score = SCORE;   // スコア
  char score_char[20]; // スコアの文字列化
  int life = LIFE;     // ライフ
  char life_char[20];  // ライフの文字列化
  
  UART_CmdReset();
  UART_IntCntl(UART_ENABLE_RX_INT);
  Counter8_WritePeriod(155);
  Counter8_WriteCompareValue(77);
  Counter8_Start();
  UART_Start(UART_PARITY_NONE);
  M8C_EnableGInt;
  LCD_Start();
  PWM16_1_Start();
  
  // ゲームスタートの初期画面
  // UART側に出題を要求する
  UART_CPutString("\r\nPSoC Synthesizer V1.1 \r\n");
  UART_CPutString("\r\nSet the Answer Tone.\r\n");
  // LCD
  LCD_PrCString("GAME START!");
  //ゲーム開始とともに起動音を発生
  TC=0;n=2;
  M8C_EnableGInt;
            PWM16_1_Start();
             Timer16_1_EnableInt();
             Timer16_1_Start();
  
  while(1){
    // 1つ目のループ 出題(鳴らす音を選ぶ)
    while(1){
      if(UART_bCmdCheck()){
        if(strPtr_1 = UART_szGetParam()){
        
          // コマンド入力と音の発生、正解をanswerに記憶
          if(*strPtr_1 == 'a'){
            PWM16_1_WritePeriod(D);
            answer = 1;
          }
          else if(*strPtr_1 == 's'){
            PWM16_1_WritePeriod(L);
            answer = 2;
          }
          else if(*strPtr_1 == 'd'){
            PWM16_1_WritePeriod(M);
            answer = 3;
          }
          else if(*strPtr_1 == 'f'){
            PWM16_1_WritePeriod(F);
            answer = 4;
          }
          else if(*strPtr_1 == 'g'){
            PWM16_1_WritePeriod(S);
            answer = 5;
          }
          else if(*strPtr_1 == 'h'){
            PWM16_1_WritePeriod(R);
            answer = 6;
          }
          else if(*strPtr_1 == 'j'){
            PWM16_1_WritePeriod(C);
            answer = 7;
          }
          else if(*strPtr_1 == 'k'){
            PWM16_1_WritePeriod(DD);
            answer = 8;
          }
          // 無音(SILENT)を選択した場合、ゲーム終了
          else if(*strPtr_1 == 'l'){
               PWM16_1_WritePeriod(SILENT);
            UART_CPutString("Bye!\r\n");
            break;
          }
          UART_CmdReset();
        
          // 回答を要求する表示
          // UART
          UART_CPutString("Inputed your Answer from [a, s, d, f, g, h, j, k] => ");
          // LCD
          LCD_Control(0x01);
          LCD_Position(0,0);
          LCD_PrCString("Input Answer");
          
          // 出題し、回答を要求したところで、1つ目のループを抜ける
          break;
        }
      }
    }
    
    // 2つ目のループ 回答(鳴っている音を選ぶ)
    while(1){
      if(strPtr_2 = UART_szGetParam()){
        UART_PutString(strPtr_2);
        PWM16_1_WritePeriod(SILENT);
        
        // コマンド入力、回答をchoiceに記憶
        if(*strPtr_2 == 'a'){
          choice = 1;
        }
        else if(*strPtr_2 == 's'){
          choice = 2;
        }
        else if(*strPtr_2 == 'd'){
          choice = 3;
        }
        else if(*strPtr_2 == 'f'){
          choice = 4;
        }
        else if(*strPtr_2 == 'g'){
          choice = 5;
        }
        else if(*strPtr_2 == 'h'){
          choice = 6;
        }
        else if(*strPtr_2 == 'j'){
          choice = 7;
        }
        else if(*strPtr_2 == 'k'){
          choice = 8;
        }
        
        //LCDの初期化
        LCD_Control(0x01);
        LCD_Position(0,0);
        
        // 正解の場合
        if(choice == answer){
          score++;
          
          // 正解の表示
          if(score != CLEAR) {
            // UART
            UART_CPutString("\r\nTrue!");
            // LCD
            LCD_PrCString("True!");
            // 出力のために、int型変数をchar型配列にコピー
            csprintf(score_char, "%d", score);
            csprintf(life_char, "%d", life);
          }
          
          // クリアした場合(スコアがCLEARに達した場合)
          // クリア音を発生させる
          // もういちど遊ぶにはリセットを押す
          else {
          TC = 0;
          n = 0;
            csprintf(score_char, "%d", score);
            // UART
            UART_CPutString("\r\n\r\nGAME CLEAR!\r\nscore : ");
            UART_PutString(score_char);
            // LCD
            LCD_PrCString("GAME CLEAR!");
            LCD_Position(1,0);
            LCD_PrCString("Score : ");
            LCD_PrString(score_char);
            //クリア音の発生
                M8C_EnableGInt;
            PWM16_1_Start();
             Timer16_1_EnableInt();
             Timer16_1_Start();
             while(1)
             {};
          }
        }
        
        // 不正解の場合
        else {
          life--;
          
          // 不正解の表示
          if(life != 0) {
            // UART
            UART_CPutString("\r\nFalse");
            // LCD
            LCD_PrCString("False");
            // 出力のために、int型変数をchar型配列にコピー
            csprintf(score_char, "%d", score);
            csprintf(life_char, "%d", life);
            
            LCD_Position(1,0);
          }
          
          // ゲームオーバーの場合(ライフが0になった場合)
          else {
          n = 1; //GAME OVER音の設定
               TC = 0;
            csprintf(score_char, "%d", score);
            // UART
            UART_CPutString("\r\n\r\nGAME OVER.\r\nscore : ");
            UART_PutString(score_char);
            // LCD の表示
            // LCDへの表示とゲームオーバー音を発生させる
            LCD_Position(0,0);
            LCD_PrCString("GAME OVER.");
            LCD_Position(1,0);
            LCD_PrCString("Score : ");
            LCD_PrString(score_char);
            
           M8C_EnableGInt;
            PWM16_1_Start();
             Timer16_1_EnableInt();
             Timer16_1_Start();
             while(1)
             {};
          }
        }
        
        // スコアの表示
        // UART
        UART_CmdReset();
        UART_CPutString("\r\nscore : ");
        UART_PutString(score_char);
        // LCD
        LCD_Position(0,7);
        LCD_PrCString("Score: ");
        LCD_PrString(score_char);
        
        // ライフの表示
        // UART
        UART_CPutString("\r\nlife : ");
        UART_PutString(life_char);
        // LCD
        LCD_Position(1,7);
        LCD_PrCString("Life : ");
        LCD_PrString(life_char);
        
        // 次の出題をUART側に要求して、2つ目のループを抜ける
        UART_CPutString("\r\n\r\nSet the Answer Tone.\r\n");
        break;
      }
    }
  }    
}

考察

ラボ timer_pwm2 pwm_uart2を基に音階を作成し、ゲーム内容に関しては、チーム1568の内容を参考にさせていただいた。
ゲームに挑戦し、成功した場合と失敗した場合とで、多くの人が聞いたことあるであろう音楽をそれぞれ作ったのだが、質のいい音楽が作成できたかと言われたらそうとは言い難い。また、一回でも間違うとゲームオーバーという仕様にしたので、面白みやユニークさに欠けてしまう部分があった。
実行中における改善点として、コマンドを打ち間違えると(Enterキーを2回押してしまった場合等)、そのあとのコマンドを押しても何も反応しなくなってしまった。打ち間違えた場合の対処は何も考えていなかったので、より良いゲームを作るためには、あらゆる場合にも実行が続くソースコードを記述しなければならない。

  • 最終更新:2017-10-24 16:13:26

このWIKIを編集するにはパスワード入力が必要です

認証パスワード