チーム1568
課題名
絶対音感ゲーム!!
研究者名
Eito Mitomi
Yuichi Watanabe
使用器具
・PSoC基盤 1個
・MiniProg 1本
・EIA-574(DSUB9)ストレート通信ケーブル 1本
・スピーカー 1個
・ジャンパー線 4本
ゲーム内容
①出題者がキーボードで音を鳴らします
(a:ド s:レ d:ミ f:ファ g:ソ h:ラ j:シ k:ド l:無音 )
②回答者はその音をよく聴き、答えだと思うキーを押します
③正解、不正解、スコア、残りライフをLCD画面に表示します。そして不正解ならばヒントも表示します
(ヒント:正解の音と回答者が答えた音を比較して、低いのか(lower)、高いのか(higher)を画面に表示する)
④5回正解したらゲームクリアですが、3回間違えるとゲームオーバーです
※以下のような仕様になっています
LCD画面…回答者用
PC画面 …出題者用
正解の場合
不正解の場合
ゲームクリア!
ゲームオーバー…
PC画面(Tera Term)
ソースコード
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include <stdlib.h>
#include <stdio.h>
int PW=125;
int SILENT=0,D=229,L=204,M=182,F=172,S=153,R=136,C=121,DD=115;
int SCORE=0,LIFE=3,CLEAR=5;
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!"); 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 { 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); // 初期化してゲーム再開 score = SCORE; life = LIFE; UART_CPutString("\r\n\r\nSet the Answer Tone.\r\n"); break; } } // 不正解の場合 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); // 正解の音程は回答したものよりも高い if(choice > answer){ UART_CPutString("\r\nhigher"); LCD_PrCString("higher"); } // 正解の音程は回答したものよりも低い else if(choice < answer){ UART_CPutString("\r\nlower"); LCD_PrCString("lower"); } } // ゲームオーバーの場合(ライフが0になった場合) else { csprintf(score_char, "%d", score); // UART UART_CPutString("\r\n\r\nGAME OVER.\r\nscore : "); UART_PutString(score_char); // LCD LCD_Position(0,0); LCD_PrCString("GAME OVER."); LCD_Position(1,0); LCD_PrCString("Score : "); LCD_PrString(score_char); // 初期化してゲーム再開 score = SCORE; life = LIFE; UART_CPutString("\r\n\r\nSet the Answer Tone.\r\n"); break; } } // スコアの表示 // 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; } } }
}
ブロック図
考察
作成した後に気づいたことだが、もしも回答者が間違った場合、
ヒントを表示したにも関わらず、出題者が次の問題(音)を自由に変えることができてしまう。
これだとヒントの価値がなくなってしまう。
せっかくヒントを表示したのだから、回答者が正解するまでずっと同じ音を鳴らすべきである。
つまり、出題者に「回答者が正解するまでは同じ音しか鳴らせない」
というような制限がついてあれば、より良いゲームが作れたであろう。
無音(SILENT)を選択した場合、ゲーム終了としたいので
breakしてwhile文からループを抜けているが、
そのwhile文の上に更に大きなwhile文があるため
実は、完全にゲームを終了できていないことになっている。
この大きなwhile文からループを抜けることができれば
完全にゲームを終了することができるだろう。
- 最終更新:2015-12-22 16:42:29