チーム1839

課題名

じゃんけん(時間制限あり)

研究者名

Yusuke Ueda
Ka Kei
Kotaro Kanasugi

概要

Psocで三人と同時にじゃんけんをする。

リセットボタンを押してスタートする。

グー:g
チョキ:c
パー:p

として、キーボードから自分の出す手を入力する。それ以外が入力された場合はエラー(終了)とする。
リセットボタンを押す、またはゲームが終わると再スタートできる。
三回勝つか三回負けると音楽が流れゲームが終わる。
時間制限があり、LCDに大まかな残り時間が表示される。
LCDにtimeoverと表示された状態で手を入力するとタイムオーバー(負け)になる。

使用した機材

PSoC基盤 1個
PSoC MiniProg 1個
ジャンパ線 2本
スピーカー 1個
シリアル通信ケーブル 1本

配線

1839配線.PNG

ソース

#include <m8c.h>
#include "PSoCAPI.h"
#include <stdio.h>
#include <stdlib.h>
#pragma interrupt_handler myISR

int PW=125;
int SILENT=0, D=229, L=204, Mf = 193, M=182, F=172, S=153, R=136, C=121, DD=115, MM=91, LL=102, Fs=162;
int TC=0;
int i = 0;
int settime =150;
int over = 0;

void myISR(void){

if(i == 0){
   LCD_1_Start();
    
   Timer16_1_WritePeriod(9999);
   TC+= 1;
    PWM16_1_WritePulseWidth(PW);
    //残り時間
   if(TC <= 50 && TC >= 0)
       LCD_1_PrCString("150/150");
   else if(TC <= 100 && TC >= 51)
       LCD_1_PrCString("100/150");
   else if(TC <= 149 && TC >= 101)
       LCD_1_PrCString("50/150");
   if(TC >= settime){
   //タイムオーバー表示
   LCD_1_PrCString("timeover");
   over = 1;
       }
       }

else if(i == 1){ 
  LCD_1_Start();
  
  LCD_1_PrCString("Congratulations!");
  
  Timer16_1_WritePeriod(9999);
  TC += 1;
  PWM16_1_WritePulseWidth(PW);

 if(TC==1) PWM16_1_WritePeriod(M);
  else if(TC==3) PWM16_1_WritePeriod(M);
  else if(TC==5) PWM16_1_WritePeriod(F);
  else if(TC==7) PWM16_1_WritePeriod(S);
  else if(TC==9)PWM16_1_WritePeriod(S);
  else if(TC==11)PWM16_1_WritePeriod(F);
  else if(TC==13)PWM16_1_WritePeriod(M);
  else if(TC==15)PWM16_1_WritePeriod(L);
  else if(TC==17)PWM16_1_WritePeriod(D);
  else if(TC==19)PWM16_1_WritePeriod(D);
  else if(TC==21)PWM16_1_WritePeriod(L);
  else if(TC==23)PWM16_1_WritePeriod(M);
  else if(TC==25)PWM16_1_WritePeriod(M);
  else if(TC==28)PWM16_1_WritePeriod(L);
  else if(TC==29) PWM16_1_WritePeriod(L);
  else if(TC==33) PWM16_1_WritePeriod(M);
  else if(TC==35) PWM16_1_WritePeriod(M);
  else if(TC==37) PWM16_1_WritePeriod(F);
  else if(TC==39) PWM16_1_WritePeriod(S);
  else if(TC==41) PWM16_1_WritePeriod(S);
  else if(TC==43) PWM16_1_WritePeriod(F);
  else if(TC==45) PWM16_1_WritePeriod(M);
  else if(TC==47) PWM16_1_WritePeriod(L);
  else if(TC==49) PWM16_1_WritePeriod(D);
  else if(TC==51) PWM16_1_WritePeriod(D);
  else if(TC==53) PWM16_1_WritePeriod(L);
  else if(TC==55) PWM16_1_WritePeriod(M);
  else if(TC==57) PWM16_1_WritePeriod(L);
  else if(TC==60) PWM16_1_WritePeriod(D);
  else if(TC==61) PWM16_1_WritePeriod(D);
  else if(TC==64) PWM16_1_WritePeriod(SILENT);
  else if(TC == 65){
  i = 0;
  TC = 0;
  }
}
else if(i == 2){
LCD_1_Start();
 if(over == 1)
         LCD_1_PrCString("timeover");
   else
          LCD_1_PrCString("Don't mind!");

Timer16_1_WritePeriod(3000);
  TC += 1;
  PWM16_1_WritePulseWidth(PW);
  
if(TC==1) PWM16_1_WritePeriod(S);
 else if(TC==3) PWM16_1_WritePeriod(L);
  else if(TC==5) PWM16_1_WritePeriod(S);
  else if(TC==7) PWM16_1_WritePeriod(C);
  else if(TC==9) PWM16_1_WritePeriod(R);
  else if(TC==11) PWM16_1_WritePeriod(SILENT);
  else if(TC==13) PWM16_1_WritePeriod(Fs);    
  else if(TC==17) PWM16_1_WritePeriod(S);
  else if(TC==21) PWM16_1_WritePeriod(Fs);
  else if(TC==23) PWM16_1_WritePeriod(M);
  else if(TC==25) PWM16_1_WritePeriod(L);
  else if(TC==29) PWM16_1_WritePeriod(L); 
  else if(TC==33) PWM16_1_WritePeriod(M);
  else if(TC==37) PWM16_1_WritePeriod(L);
  else if(TC==39) PWM16_1_WritePeriod(D);
  else if(TC==41) PWM16_1_WritePeriod(L);
  else if(TC==45) PWM16_1_WritePeriod(S);
  else if(TC==47) PWM16_1_WritePeriod(S);
  else if(TC==49) PWM16_1_WritePeriod(M);
  else if(TC==51) PWM16_1_WritePeriod(S);
  else if(TC==55) PWM16_1_WritePeriod(C);
  else if(TC==57) PWM16_1_WritePeriod(R);
  else if(TC == 61) PWM16_1_WritePeriod(SILENT);
  else if(TC == 62){
  i = 0;
  TC = 0;
  over = 0;
  }
 Timer16_1_WritePeriod(9999);
}
}
void main(void)
{
// Insert your main routine code here.

 int yubi = 0; //ユーザーの出す手
 int enemy1 = 0; //相手の出す手
 int enemy2 = 0;
 int enemy3 = 0;
 int win = 0, lose = 0, draw = 0; //勝ち、負け、引き分けの判定フラグ
 int count = 0; //勝った回数
 int countl = 0; //負けた回数    
 int a=0;
char *strPtr;
 UART_CmdReset();
 UART_IntCntl(UART_ENABLE_RX_INT);
 Counter8_WritePeriod(155);
 Counter8_WriteCompareValue(77);
 Counter8_Start();
 UART_Start(UART_PARITY_NONE);
 M8C_EnableGInt;
 PWM16_1_Start();
Timer16_1_EnableInt();
Timer16_1_Start();
UART_CPutString("\r\nWelcome to PSoC JYANNKENN. START! \r\n"); //スタート
  UART_CPutString("グー: g   チョキ: c   パー: p \r\n");
 

while(1){
 a++;
     if(UART_bCmdCheck()){
         if(strPtr = UART_szGetParam()){
              //ユーザーの出す手を選択
              UART_CPutString("\r\n");
              UART_CPutString("Your choice => ");
              UART_PutString(strPtr);
              UART_CPutString("\n");
             
              if (*strPtr=='g'){ //グー
                   yubi = 0;    
                   UART_CPutString("\r\n You   : グー\r\n");
              }     
              else if (*strPtr=='c'){ //チョキ
                  yubi = 1;
                  UART_CPutString("\r\n You   : チョキ\r\n");
              }
              else if (*strPtr=='p'){ //パー
                  yubi = 2;
                   UART_CPutString("\r\n You   : パー\r\n");
              }
                else{ //エラー
                   yubi = 8;
                  UART_CPutString("\r\n error \r\n"); 
                     break;
              }
              
              srand(a);
              //相手の手(乱数)
              enemy1 = rand() % 3;
              if(yubi == 0 | | yubi == 1 | | yubi == 2){
                    if(enemy1 == 0)
                         UART_CPutString(" Enemy1 : グー\r\n");
                   else if(enemy1 == 1)
                       UART_CPutString(" Enemy1 : チョキ\r\n");
                     else if(enemy1 == 2)
                           UART_CPutString(" Enemy1 : パー\r\n");
              }
              

              enemy2 = rand() % 3;
              if(yubi == 0 | | yubi == 1 | | yubi == 2){
                    if(enemy2 == 0)
                         UART_CPutString(" Enemy2 : グー\r\n");
                   else if(enemy2 == 1)
                       UART_CPutString(" Enemy2 : チョキ\r\n");
                     else if(enemy2 == 2)
                           UART_CPutString(" Enemy2 : パー\r\n");
              }
            
              enemy3 = rand() % 3;
              if(yubi == 0 | | yubi == 1 | | yubi == 2){
                    if(enemy3 == 0)
                         UART_CPutString(" Enemy3 : グー\r\n");
                   else if(enemy3 == 1)
                       UART_CPutString(" Enemy3 : チョキ\r\n");
                     else if(enemy3 == 2)
                           UART_CPutString(" Enemy3 : パー\r\n");
              }
            
              //4ninn
              if((enemy1 + enemy2 + yubi) % 3 == 0){
                  if(enemy1 != enemy2)
                      draw = 1;
                  else{
                      if(yubi == 0 && enemy3 == 1)
                      win = 1;
                  else if(yubi == 1 && enemy3 == 2)
                      win = 1;
                  else if(yubi == 2 && enemy3 == 0)
                      win = 1;
                  else if(yubi == enemy3)
                      draw = 1;
                  else
                      lose = 1;
                  }
              }
              else{ // 一人だけ負けるとき
                  if(enemy1 == enemy2){
                      if((enemy1 + enemy3 + yubi) % 3 == 0)
                          draw = 1;
                      else if((enemy1 + enemy3 + yubi) % 3 == 1){ // 一人だけ負けるとき
                            if(yubi == 0 && enemy1 == 1)
                                 win = 1;
                          else if(yubi == 1 && enemy1 == 2)
                                  win = 1;
                            else if(yubi == 2 && enemy1 == 0)
                              win = 1;
                          else if(yubi == 0 && enemy3 == 1)
                                 win = 1;
                             else if(yubi == 1 && enemy3 == 2)
                                 win = 1;
                          else if(yubi == 2 && enemy3 == 0)
                                 win = 1;
                          else 
                              lose = 1;
                         }

                    else if((enemy1 + enemy3 + yubi) % 3 == 2){ // 二人が負けるとき
                          if(yubi == 0 && enemy1 == 1)
                              win = 1;
                          else if(yubi == 1 && enemy1 == 2)
                              win = 1;
                          else if(yubi == 2 && enemy1 == 0)
                              win = 1;
                          else 
                              lose = 1;
                      }
                  }
                  else if(enemy1 == yubi){
                      if((yubi + enemy2 + enemy3) % 3 == 0)
                          draw = 1;
                      else if((yubi + enemy2 + enemy3) % 3 == 1){ // 一人だけ負けるとき
                          if(yubi == 0 && enemy3 == 1)
                              win = 1;
                          else if(yubi == 1 && enemy3 == 2)
                              win = 1;
                          else if(yubi == 2 && enemy3 == 0)
                                 win = 1;
                          else if(yubi == 0 && enemy2 == 1)
                                 win = 1;
                          else if(yubi == 1 && enemy2 == 2)
                                 win = 1;
                          else if(yubi == 2 && enemy2 == 0)
                                 win = 1;
                          else 
                              lose = 1;
                      }

                    else if((yubi + enemy2 + enemy3) % 3 == 2){ // 二人が負けるとき
                          if(yubi == 0 && enemy3 == 1)
                              win = 1;
                          else if(yubi == 1 && enemy3 == 2)
                              win = 1;
                          else if(yubi == 2 && enemy3 == 0)
                              win = 1;
                          else 
                              lose = 1;
                      }
                  }
                  else if(enemy2 == yubi){
                      if((yubi + enemy1 + enemy3) % 3 == 0)
                          draw = 1;
                      else if((yubi + enemy1 + enemy3) % 3 == 1){ // 一人だけ負けるとき
                          if(yubi == 0 && enemy3 == 1)
                              win = 1;
                          else if(yubi == 1 && enemy3 == 2)
                              win = 1;
                          else if(yubi == 2 && enemy3 == 0)
                                 win = 1;
                          else if(yubi == 0 && enemy1 == 1)
                                 win = 1;
                          else if(yubi == 1 && enemy1 == 2)
                                 win = 1;
                          else if(yubi == 2 && enemy1 == 0)
                                 win = 1;
                          else 
                              lose = 1;
                      }

                    else if((yubi + enemy1 + enemy3) % 3 == 2){ // 二人が負けるとき
                          if(yubi == 0 && enemy3 == 1)
                              win = 1;
                          else if(yubi == 1 && enemy3 == 2)
                              win = 1;
                          else if(yubi == 2 && enemy3 == 0)
                              win = 1;
                          else 
                              lose = 1;
                      }
                  }
                  
              }

                if(win == 1){ //勝った場合
                         UART_CPutString("\r\n You win! \r\n");
                        count++;
                  }
                     
                  else if(lose == 1){ //負けた場合
                      UART_CPutString("\r\n You lose! \r\n");
                      countl++;
                  }
                 if(over == 1){
                            UART_CPutString("\r\n time over \r\n");
                           TC = 0;
                              i = 2;
                              countl = 0;
                           
                           main();
                        }
                  if(count == 0) {
                      UART_CPutString(" Win count: 0\r\n");  
                  }
                 
                  if(count == 1) {
                      UART_CPutString(" Win count: 1\r\n");
                     
                  }
                  if(count == 2) {
                      UART_CPutString(" Win count: 2\r\n");
                  }
                  if(count == 3){
                      UART_CPutString("\r\n Congratulations!! \r\n");
                      UART_CPutString("\r\n  \r\n");
                      TC = 0;
                      i = 1;
                       main();
                     count = 0;
                     countl = 0;
                  }
                  win = 0;
              
              
                  if(countl == 0){
                      UART_CPutString(" Lose count: 0\r\n");
                  }
                  if(countl == 1) {
                         UART_CPutString(" Lose count: 1\r\n");
                  }
                  if(countl == 2) {
                      UART_CPutString(" Lose count: 2\r\n");
                  }
                  
                  if(countl == 3 ){
                          if(over == 0){
                              UART_CPutString("\r\n Don't mind! \r\n");
                           TC = 0;
                             i = 2;
                           count = 0;
                              countl = 0;
                           main();
                          }
                   }
                  
                  lose = 0;
              
             
                  if(draw == 1){ //引き分けの場合
                         UART_CPutString("\r\n draw \r\n");
                      draw = 0;
                  }
          
                  UART_CmdReset();
          }
      }
  }
}

考察

じゃんけんの判定はチーム1756を参考にした。PCとのシリアル通信はuart_1、音楽の演奏はtimer_pwm2を参考にした。

4人でじゃんけんをする際の勝敗の判定には、グーを0、チョキを1、パーを2とし、まずユーザーを含めた3人の出し手の和で場合分けをした。3人の出し手がすべて異なる場合は、そこで判定を終了し、あいことした。それ以外の場合は、3人のうち出し手の同じ2人をまとめて1人とし、4人を3人として、勝敗を決定するようにした。

じゃんけんで勝ったり負けたりすると、割り込み処理が実行され、曲が流れる。勝った時にはOde to Joyが流れ、負けた時、時間切れの時に負けないでが流れる。割り込み処理中にLCDをスタートさせ、勝った時、負けた時、時間切れの時のメッセージ、残り時間をそれぞれ表示できるようにした。
勝敗を決めて割り込みをさせる前にTCを0にすることで、時間を測るために使っていたTCを0にし、曲が初めから流れるようにした。ゲームが終わった後再び時間制限ができるようにした。

  • 最終更新:2018-07-10 17:31:18

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

認証パスワード