チーム1737

課題名

パネルゲーム

研究者名

小澤 詩織 shiori ozawa
川島 宙 sora kawashima

使用した機材

PSoC評価基盤 ×1
16個ボタン基盤(KEYPAD-16X16) ×1
PSOC ×1
MiniProg ×1
UARTケーブル ×1
ジャンパー線 ×2

仕様

チーム1634を参考。
16つのボタンを使用。
押したボタンに対応するパネルとそのパネルに隣接しているパネルの色を反転させる。
全て白色になるとゲームクリア

対応しているパネル

159D
26AE
37BF
48C0

ソースコード

[main.c]

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


/*****************Variables***************************/
/* LUT for storing keys. The size of the LUT should be equal to 2 ^ (NUMBER OF ROWS + COLUMNS).
Row and column information from Scanning function is used as index to this LUT for finding the key.
Value 0x20 indicates invalid key. */

static const keypad_LUT[256] =
{/* 0 1 2 3 4 5 6 7
                                                    8     9     A     B     C     D     E     F  */
/*0*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*1*/0x20, '1', '5', 0x20, '9', 0x20, 0x20, 0x20,
   'D', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/*2*/0x20, '2', '6', 0x20, 'A', 0x20, 0x20, 0x20,
   'E', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*3*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*4*/0x20, '3', '7', 0x20, 'B', 0x20, 0x20, 0x20,
   'F', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*5*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*6*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*7*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*8*/0x20, '4', '8', 0x20, 'C', 0x20, 0x20, 0x20,
   '0', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*9*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*A*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*B*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*C*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*D*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*E*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
/*F*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
    0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
};

/* These two variables are used to store the row number and the column number */
BYTE rows,cols;

BYTE InterruptCounter=0;

/* These two variables store the key number */
unsigned char key[2] = {0x20,0};
/*****************************************************/


/****************Functions****************************/

/* Handles keypad function- Checks the key pressed and debounces key */
void KeyPadHandler(void);

/* Keypad scanning routine */
unsigned char keypad_scan(void);

/* Initializes user modules used in the design */
void InitModules(void);

/* Interrupt handler for GPIO interrupt */
void GPIOInterrupt(void);
/****************************************************/


void main(void)
{
  char *strPtr;
  UART_CmdReset();
  UART_IntCntl(UART_ENABLE_RX_INT);
  Counter8_WritePeriod(155);
  Counter8_WriteCompareValue(77);
  Counter8_Start();
  UART_Start(UART_PARITY_NONE);
     InitModules();  /* Initialize variables and user modules */
   M8C_EnableGInt;     /* Enable Global Interrupt */
   // UART_CPutString("\r\nWelcome to PSoC UART test program. V1.1 \r\n");
  
   
   while(1)
   {    
       /* Check the Keypad status and update on LCD if any key is pressed */
                   
       if(key[0] != 0x20)
       {
           /* Valid key */
           if (key[0] == '1') {
           UART_CPutString("1");    // Send for processing key number
           key[0] = 0x20;        // Invalidate key
       } else if (key[0] == '2') {
           UART_CPutString("2");
           key[0] = 0x20;
       } else if (key[0] == '3') {
           UART_CPutString("3");
           key[0] = 0x20;
       } else if (key[0] == '4') {
           UART_CPutString("4");
           key[0] = 0x20;
       } else if (key[0] == '5') {
           UART_CPutString("5");
           key[0] = 0x20;
       } else if (key[0] == '6') {
           UART_CPutString("6");
           key[0] = 0x20;
       } else if (key[0] == '7') {
           UART_CPutString("7");
           key[0] = 0x20;
       } else if (key[0] == '8') {
           UART_CPutString("8");
           key[0] = 0x20;
       } else if (key[0] == '9') {
           UART_CPutString("9");
           key[0] = 0x20;
       } else if (key[0] == 'A') {
           UART_CPutString("A");
           key[0] = 0x20;
       } else if (key[0] == 'B') {
           UART_CPutString("B");
           key[0] = 0x20;
       } else if (key[0] == 'C') {
           UART_CPutString("C");
           key[0] = 0x20;
       } else if (key[0] == 'D') {
           UART_CPutString("D");
           key[0] = 0x20;
       } else if (key[0] == 'E') {
           UART_CPutString("E");
           key[0] = 0x20;
       } else if (key[0] == 'F') {
           UART_CPutString("F");
           key[0] = 0x20;
       } else if (key[0] == '0') {
           UART_CPutString("0");
           key[0] = 0x20;
       }
           /* Set LCD cursor position */
           LCD_1_Position(0, 7);
           
           /* Display pressed keypad button */
           LCD_1_PrString((char *)key);
                   
           /* Set LCD cursor position */
           LCD_1_Position(1, 12);
       
           /* Display nuymber of times key is pressed so far */
           LCD_1_PrHexByte(InterruptCounter);
       
           /* Invalidate key */    
           key[0]=0x20;
       }
           
       /* Do other tasks */
   }
}



/* This function initializes all the user modules used in the design */
void InitModules(void)
{
  /* Initialize LCD */
   LCD_1_Start();
   LCD_1_Position(0,0);
   LCD_1_PrCString("Switch:");
   LCD_1_Position(1,0);
   LCD_1_PrCString("Interrupts:");
       
   /* Initilize timer- 10ms delay */
   Timer16_1_WritePeriod(320);
   Timer16_1_EnableInt();
       
   /* Enable GPIO interrupt */
   INT_MSK0|=0x20;
       
   /* Write 1's at column lines */
   PRT0DR|=0xF0;
}



/* This function scan the keypad and identifies the key pressed */
unsigned char keypad_scan(void)
{
  BYTE key_result;
       
   /* Drive rows */
   PRT0DR = 0x0F;
   
   /* Read columns */
   rows = PRT0DR;
   
   /* Drive columns */
   PRT0DR = 0xF0;
   
   /* Read rows */
   cols = PRT0DR;
   
   /* Combine results */
   key_result = rows & cols;
       
   /* Get the key number from LUT */
   return(keypad_LUT[key_result]);
}


/* This is the interrupt handler for the GPIO interrupt. Debounce timer is started on GPIO interrupt */
#pragma interrupt_handler GPIOInterrupt
void GPIOInterrupt(void)
{
  /* Disable GPIO interrupt */
   INT_MSK0&=~0x20;    
       
   /* Start Timer */
   Timer16_1_Start();
}


/* This is the interrupt handler for the timer. Scanning routine is called for key identification */
void TimerInterrupt(void)
{
  /* Stop the timer and update the flag */
   Timer16_1_Stop();
       
   /* Get the key */
   key[0] = keypad_scan();
       
       
   /* Check if no key or multiple keys are pressed */
   if(key[0] != 0x20)
   {
   /* Valid key. Take action if required */
           
       /* Increment interrupt counter */
       InterruptCounter++;        
   }
   
   /* Clear GPIO posted interrupt */
   INT_CLR0&=~0x20;
       
   /* Enable GPIO interrupt */
   INT_MSK0|=0x20; 
}

[proccesing]


import processing.serial.*;

Serial port = new Serial(this, "COM3", 38400);

Board board;
public final int LEVEL = 4;
public final int RINSETSU = 4;
public final int PANELCOUNT = 16;
PImage imgclear;
PImage imgsample;
PImage [] image = new PImage [PANELCOUNT];

char before, after;
boolean end = false;

void setup() { //Set up
size(800, 600);
background(120, 0, 120);

board = new Board();
imgclear = loadImage("clear.png");
///imgsample = loadImage ("s3.jpg");

///for(int i=0;i<16;i++){
///  image[i] = imgsample.get (100*(i%4),100*i ,100, 100 );
}



void draw() {
after = port.readChar();
//print(after);
  if (after != '?') {
    MykeyPressed(after);
  }
for (int i = 0; i < PANELCOUNT; i++) {
  if (board.getCell(i)) {  // After
    rectMode(CORNER);
    fill(255);
    rect(200+100*(i/4), 100+100*(i%4),100, 100);
///    image(image[i],200+100*(i/4), 100+100*(i%4),100,100);
    
    if(end) image(imgclear, 315, 260);
  } else { 
    rectMode(CORNER);
    fill(23);
    rect(200+100*(i/4), 100+100*(i%4),100, 100);
    if(end)image(imgclear, 300, 250);
  }
}
}

void MykeyPressed(char indata) {
if (!end){
if (indata == 'q' | | indata == 'Q' /*| | sw[0] == 0*/){
 exit();
} else if (indata == '1') {
 board.touch(0);
 
} else if (indata == '2') {
 board.touch(1);
} else if (indata == '3') {
 board.touch(2);
} else if (indata == '4') {
 board.touch(3);
} else if (indata == '5') {
 board.touch(4);
} else if (indata == '6') {
 board.touch(5);
} else if (indata == '7') {
 board.touch(6);
} else if (indata == '8') {
 board.touch(7);
} else if (indata == '9') {
 board.touch(8);
} else if (indata == 'A') {
 board.touch(9);
} else if (indata == 'B') {
 board.touch(10);
} else if (indata == 'C') {
 board.touch(11);
} else if (indata == 'D') {
 board.touch(12);
} else if (indata == 'E') {
 board.touch(13);
} else if (indata == 'F') {
 board.touch(14);
} else if (indata == '0') {
 board.touch(15);
}
if (board.gameset()) {
  image(imgclear, 300, 250);
  tint (255, 50);
  end = true;
  //image(imgclear, 300, 250);
  //indata = end;
}
}
}

class Board {

private Panel[] cell;  //panels
 private int[] start;   //first false points

  public Board() {
    cell = new Panel[PANELCOUNT];  // cells
    start = new int[LEVEL];        // 16 cells start
    for (int i = 0; i < PANELCOUNT; i++) {
      cell[i] = new Panel(i);  // New 16 cells
    }
    for (int i = 0; i < LEVEL; i++) {
      start[i] = (int)random(15)+1; // Start state is random 
    }
    firstPanel();
  }

  public void firstPanel() {
    for (int i = 0; i < PANELCOUNT; i++) {
      cell[i].reset();  // return status = true
    }
    for (int i = 0; i < LEVEL; i++) {
      touch(start[i]);
    }
  }

  public boolean getCell(int pos) {
    return cell[pos].getStatus();  // Before or after
  }

  public boolean gameset() {
    for (int i = 0; i < PANELCOUNT; i++) {
      if (!cell[i].getStatus()) {
        return false;
      }
    }
    return true;
  }

  public void touch(int pos) {
    cell[pos].change();
    for (int i = 0; i < RINSETSU; i++) {
      if (cell[pos].next[i] != -1) {
        cell[cell[pos].next[i]].change();
      }
    }
  }
}

class Panel {

private boolean status;
 private int pos;  // Cell position
  public int[] next;  // Side don't react

  public Panel(int pos) {
    status = true;  // Cell status
    this.pos = pos;  // Cell position
    next = new int[RINSETSU];  // Surrounding cell
    if (0 <= pos - 4 ) {  // Not react on the left side 
      next[0] = pos - 4;
    } else {
      next[0] = -1;   
    }
    if (pos + 4 < PANELCOUNT) { // Not react on the right side
      next[1] = pos + 4;
    } else {
      next[1] = -1;
    }
    if (pos % 4 != 0) {  // Not react on the top side
      next[2] = pos - 1;
    } else {
      next[2] = -1;
    }
    if (pos % 4 != 3 ) {  // Not react on the bottom side
      next[3] = pos + 1;
    } else {
      next[3] = -1;
    }
  }

  public void reset() {  // Cell reset
    status = true;
  }

  public boolean getStatus() {  // Current status
    return status;
  }

  public void change() {  // change
    status = !status;
  }
}

考察

パネルが全て画像になると「clear」の文字を表示させること
LCDにスイッチ入力回数を出力されるようにしたこと
上記2点を工夫した。

○○ボタンを押すとPC側に○○という情報を送信する、といった制御に苦労した。

PSoCにプログラムを書き込むときにジャンパー線を外さないとエラーが発生してしまうことに対して
分流してしまうのが原因だと気づくのが遅れてしまったため作業が進まないことがあった。

完成図を画像にする、制限時間を設けて時間経過でゲームオーバーにする、という案もあったが
時間的に断念した。

  • 最終更新:2017-07-11 17:47:51

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

認証パスワード