チーム2058

課題名

BGM付きマインスイーパー

研究者名

Tatsuya Suhara
Genta Takahashi

作品概要

マインスイーパーをキーボードの入力で行えるように実装しました。
キーボードを4×4に見立てました。
1 2 3 4
q w e r
a s d f
z x c v
表示方法
爆弾が"@"
開く前のマスが"-"
開いた後のマス(周囲に爆弾あり)が"数字"
開いた後のマス(周囲に爆弾なし)が"."
TeraTermには最後にCLEARかGAMEOVERが表示されます。
また、BGMとして紅蓮華が流れ、LCDに歌詞をローマ字で表示します。

チーム2032とチーム2033を参考にさせてもらいました。
チーム2032がマインスイーパー、チーム2033が紅蓮華の音階です。

ソースコード

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

/*------- music ---------*/
int PW=125; // Pulse Width
int SILENT=0,D=229,Ds=217,L=204,Ls=193,M=182,F=172,Fs=162,S=153,Ss=145,R=136,Rs=129,C=121;
int DD=115,DDs=108,LL=102,LLs=96,MM=91,FF=86,FFs=81,SS=77,SSs=72,RR=68,RRs=64,CC=61;
int TC=0; //Time Count
int words = 1;
void myISR(void)
{
 TC += 1; //TC = TC +1
  PWM16_1_WritePulseWidth(PW);
  if(TC == 1) {
      PWM16_1_WritePeriod(L);
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("kesanaiyumemo");
   }
  else if(TC == 4)
      PWM16_1_WritePeriod(L);
  else if (TC == 5)
      PWM16_1_WritePeriod(L);
  else if (TC == 9)
      PWM16_1_WritePeriod(C);
  else if (TC == 13)
      PWM16_1_WritePeriod(R);
  else if (TC == 15)
      PWM16_1_WritePeriod(C);
  else if (TC == 17)
      PWM16_1_WritePeriod(LL);
  else if (TC == 19)
      PWM16_1_WritePeriod(C);
  else if (TC == 21)
      PWM16_1_WritePeriod(R);
  else if (TC == 23)
      PWM16_1_WritePeriod(C);
  else if (TC == 24)
      PWM16_1_WritePeriod(C);
  else if (TC == 27){
      PWM16_1_WritePeriod(S);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("tomarenaiimamo");
   }
  else if (TC == 29)
      PWM16_1_WritePeriod(R);
  else if (TC == 31)
      PWM16_1_WritePeriod(C);
  else if (TC == 33)
      PWM16_1_WritePeriod(LL);
  else if (TC == 35)
      PWM16_1_WritePeriod(C);
  else if (TC == 37)
      PWM16_1_WritePeriod(R);
  else if (TC == 39)
      PWM16_1_WritePeriod(C);
  else if (TC == 40)
      PWM16_1_WritePeriod(C);
  else if (TC == 43){
      PWM16_1_WritePeriod(L);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("darekanotameni");
   }
  else if (TC == 45)
      PWM16_1_WritePeriod(L);
  else if (TC == 47)
      PWM16_1_WritePeriod(S);
  else if (TC == 48)
      PWM16_1_WritePeriod(S);
  else if (TC == 51)
      PWM16_1_WritePeriod(L);
  else if (TC == 53)
      PWM16_1_WritePeriod(L);
  else if (TC == 55)
      PWM16_1_WritePeriod(S);
  else if (TC == 57){
      PWM16_1_WritePeriod(R);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("tuyokunarerunara");
   }
  else if (TC == 59)
      PWM16_1_WritePeriod(S);
  else if (TC == 61)
      PWM16_1_WritePeriod(LL);
  else if (TC == 65)
      PWM16_1_WritePeriod(DD);
  else if (TC == 69)
      PWM16_1_WritePeriod(C);
  else if (TC == 72)
      PWM16_1_WritePeriod(R);
  else if (TC == 75)
      PWM16_1_WritePeriod(S);
  else if (TC == 77)
      PWM16_1_WritePeriod(S);
  else if (TC == 83){
      PWM16_1_WritePeriod(S);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("arigatou");
   }
  else if (TC == 85)
      PWM16_1_WritePeriod(S);
  else if (TC == 87)
      PWM16_1_WritePeriod(R);
  else if (TC == 89)
      PWM16_1_WritePeriod(C);
  else if (TC == 91)
      PWM16_1_WritePeriod(R);
  else if (TC == 97){
      PWM16_1_WritePeriod(L);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("kanashimiyo");
   }
  else if (TC == 99)
      PWM16_1_WritePeriod(R);
  else if (TC == 103)
      PWM16_1_WritePeriod(C);
  else if (TC == 105)
      PWM16_1_WritePeriod(LL);
  else if (TC == 107)
      PWM16_1_WritePeriod(R);
  else if (TC == 109)
      PWM16_1_WritePeriod(C);
  else if(TC == 121){
      PWM16_1_WritePeriod(L);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("sekainiutinomesarete");
   }
  else if(TC == 125)
      PWM16_1_WritePeriod(L);
  else if (TC == 129)
      PWM16_1_WritePeriod(C);
  else if(TC == 133)
      PWM16_1_WritePeriod(R);
  else if(TC == 135)
      PWM16_1_WritePeriod(C);
  else if (TC == 137)
      PWM16_1_WritePeriod(LL);
  else if(TC == 139)
      PWM16_1_WritePeriod(C);
  else if(TC == 141)
      PWM16_1_WritePeriod(R);
  else if (TC == 143)
      PWM16_1_WritePeriod(C);
  else if (TC == 144)
      PWM16_1_WritePeriod(C);
  else if(TC == 147){
      PWM16_1_WritePeriod(S);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("makeruimiwoshitta");
   }
  else if (TC == 148)
      PWM16_1_WritePeriod(S);
  else if(TC == 149)
      PWM16_1_WritePeriod(R);
  else if(TC == 151)
      PWM16_1_WritePeriod(C);
  else if (TC == 153)
      PWM16_1_WritePeriod(LL);
  else if(TC == 155)
      PWM16_1_WritePeriod(C);
  else if(TC == 157)
      PWM16_1_WritePeriod(R);
  else if (TC == 159)
      PWM16_1_WritePeriod(C);
  else if(TC == 160)
      PWM16_1_WritePeriod(S);
  else if(TC == 163){
      PWM16_1_WritePeriod(S);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("gurennnohanayo");
   }
  else if (TC == 165)
      PWM16_1_WritePeriod(S);
  else if(TC == 168)
      PWM16_1_WritePeriod(R);
  else if(TC == 171)
      PWM16_1_WritePeriod(C);
  else if(TC == 175)
      PWM16_1_WritePeriod(C);
  else if(TC == 177)
      PWM16_1_WritePeriod(SS);
  else if(TC == 179)
      PWM16_1_WritePeriod(FFs);
  else if(TC == 185){
      PWM16_1_WritePeriod(LL);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("sakihokore");
   }
  else if(TC == 189)
      PWM16_1_WritePeriod(C);
  else if(TC == 192)
      PWM16_1_WritePeriod(R);
  else if(TC == 195)
      PWM16_1_WritePeriod(S);
  else if(TC == 197)
      PWM16_1_WritePeriod(S);
  else if(TC == 203){
      PWM16_1_WritePeriod(S);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("unnmeiwo");
   }
  else if(TC == 205)
      PWM16_1_WritePeriod(S);
  else if(TC == 207)
      PWM16_1_WritePeriod(R);
  else if(TC == 209)
      PWM16_1_WritePeriod(C);
  else if(TC == 211)
      PWM16_1_WritePeriod(R);
  else if(TC == 213){
      PWM16_1_WritePeriod(SILENT);
      if(words)LCD_1_Init();
      LCD_1_Position(0,0);
      if(words)LCD_1_PrCString("terashite");
   }
  else if(TC == 219)
      PWM16_1_WritePeriod(L);
  else if(TC == 225)
      PWM16_1_WritePeriod(M);
  else if (TC == 229){
      if(words)LCD_1_Init();
      PWM16_1_WritePeriod(SILENT);
   }
   else if (TC >= 331) {
       TC = 0;    
   }
}


/*---- minesweeper -----*/
#define ROW 4
#define COL 4

enum kind { B, N };

char map[ROW][COL] = {
  B, N, N, N,
   N, N, N, N, 
   N, N, B, N, 
   N, N, N, N, 
};

char openedmap[ROW][COL];
int visitedmap[ROW][COL];
int gameend = 0;
void key_open(char* key);

void ini_openedmap(void);
char open(int r, int c);
int index(int r, int c);
void print_openedmap(void);
int gameClear(void);
int searchable(int dx, int dy);

void ini_openedmap(void)
{
  int i, j;
   for (i = 0; i < ROW; ++i)
       for (j = 0; j < COL; ++j)
           openedmap[i][j] = '-';
}

char open(int r, int c)
{
  int dx, dy;
   int bomb = 0;

  if (visitedmap[r][c] != 0) return openedmap[r][c];
   else visitedmap[r][c] = 1;

  if (map[r][c] == B) {
       gameend = 1; return '@';
   }

  for(dx = -1; dx <= 1; ++dx)
       for (dy = -1; dy <= 1; ++dy)
       {
           if (index(r + dx, c + dy))
               if (map[r + dx][c + dy] == B) ++bomb;
       }
   if (bomb != 0) return '0' + bomb;

  for(dx = -1; dx <= 1; ++dx)
       for (dy = -1; dy <= 1; ++dy)
       {
           if (!searchable(dx, dy)) continue;
           if (index(r+dx, c+dy))
           {
               if (map[r + dx][c + dy] == N) {
                   openedmap[r + dx][c + dy] = open(r + dx, c + dy);
               }
           }
       }
   return '.';
}

int index(int r, int c)
{
  return 0 <= r && r < ROW && 0 <= c && c < COL;
}

int searchable(int dx, int dy)
{
  return dx == 0 && dy == 1 | | dx == -1 && dy == 0 
           | | dx == 1 && dy == 0 | | dx == 0 && dy == -1;
}

void print_openedmap(void)
{
  int i, j;
   for (i = 0; i < ROW; ++i) {
       for (j = 0; j < COL; ++j) {
           UART_PutChar(openedmap[i][j]);
       }
       UART_CPutString("\r\n");
   }
}

void key_open(char* key)
{
  switch (*key)
   {
       case '1': openedmap[0][0] = open(0,0); break;
       case '2': openedmap[0][1] = open(0,1); break;
       case '3': openedmap[0][2] = open(0,2); break;
       case '4': openedmap[0][3] = open(0,3); break;
           
       case 'q': openedmap[1][0] = open(1,0); break;
       case 'w': openedmap[1][1] = open(1,1); break;
       case 'e': openedmap[1][2] = open(1,2); break;
       case 'r': openedmap[1][3] = open(1,3); break;
           
       case 'a': openedmap[2][0] = open(2,0); break;
       case 's': openedmap[2][1] = open(2,1); break;
       case 'd': openedmap[2][2] = open(2,2); break;
       case 'f': openedmap[2][3] = open(2,3); break;
       
       case 'z': openedmap[3][0] = open(3,0); break;
       case 'x': openedmap[3][1] = open(3,1); break;
       case 'c': openedmap[3][2] = open(3,2); break;
       case 'v': openedmap[3][3] = open(3,3); break;
           
       default: break;
   }
}

int gameClear(void)
{
  int i, j;
   for(i = 0; i < ROW; ++i)
       for (j = 0; j < COL; ++j) {
           if (visitedmap[i][j] == 0 && map[i][j] == N)
               return 0;
       }
   return 1;
}

int main(void)
{
  char *strPtr;
   int clear = 0;
   int first = 1;
   
   /*---- music initialize -----*/
   M8C_EnableGInt;
   PWM16_1_Start();
   LCD_1_Start();
   Timer16_1_EnableInt();
   Timer16_1_Start();
   
   /*---- minesweeper initialize ----*/
     UART_CmdReset();
     UART_IntCntl(UART_ENABLE_RX_INT);
     Counter8_WritePeriod(155);
     Counter8_WriteCompareValue(77);
     Counter8_Start();
   //LCD_1_Start();
     UART_Start(UART_PARITY_NONE);
     //M8C_EnableGInt;
     UART_CPutString("Minesweeper\r\n");
   ini_openedmap();
   print_openedmap();
          while (!gameend){
         if (first) {
            UART_CPutString("\r\nopen position => ");
            first = 0;
         }
              if (UART_bCmdCheck()){
                  while(strPtr = UART_szGetParam()){
                      UART_PutString(strPtr);
                      UART_CPutString("\r\n");
                      key_open(strPtr);
                      print_openedmap();
                      if(gameClear())
                      {
                          gameend = 1;
                          clear = 1;
                      }
                      first = 1;
                  }
              UART_CmdReset();
           }
          }
       if(clear)
       {
           LCD_1_Init();
           UART_CPutString("CLEAR\r\n");
           LCD_1_PrCString("CLEAR");
           words = 0;
       }
       else {
           LCD_1_Init();
           UART_CPutString("GAMEOVER\r\n");
           LCD_1_PrCString("GAMEOVER");
           words = 0;
       }
    return 0;
}

使用器具

PSoCミニプラグ
基盤
シリアルケーブル
スピーカー

考察

チーム2032とチーム2033を参考にさせてもらい、マインスイーパーの方はうまく出力ができていなかったのでそれをできるように修正をし、音楽に関してはLCDに歌詞を表示することでアレンジを加えました。
この自由課題を通して、PSoCの利用方法やプログラムの作成をある程度は理解することができたと思います。ただ、マインスイーパーが1プレイしか行えないので何度もプレイができるようにしたかったです。

  • 最終更新:2020-11-24 16:50:12

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

認証パスワード