マイコンArduinoを使って電光掲示板を作る。
続き
テトリスに挑戦の8回目はブロックの回転の制限を作って行きます。
壁、ブロックの側面に当たると回転出来ないプログラム
int x_pos = 6;
int y_pos = 0;
int select = 6;
int muki = 0;
int fall_speed_count = 0;
boolean rotate_flag = false;
boolean fixed_flag = false;
int move_count_l = 0;
int move_count_r = 0;
int fixed_count = 0;
int fall_count = 0;
int left_count = 0;
int right_count = 0;
int rotate_count = 0;
short data_hex[] = {0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004,
0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x2004, 0x3ffc};
short block[7][4] = {{0x0660, 0x0660, 0x0660, 0x0660},
{0x4444, 0x00f0, 0x2222, 0x0f00},
{0x2640, 0x0c60, 0x0264, 0x0630},
{0x4620, 0x0630, 0x0462, 0x0360},
{0x0644, 0x0470, 0x2260, 0x0e20},
{0x0622, 0x0740, 0x4460, 0x02e0},
{0x04e0, 0x0262, 0x0720, 0x4640}};
short disp_hex[16];
short fall_hex[16];
short left_hex[16];
short right_hex[16];
short rotate_hex[16];
void setup() {
// put your setup code here, to run once:
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,INPUT_PULLUP);
pinMode(9,INPUT_PULLUP);
pinMode(10,INPUT_PULLUP);
}
void loop() {
// put your main code here, to run repeatedly:
move_block();
rotate();
fall();
data_make();
disp();
}
boolean left_check(){
if (left_count == 46 + fixed_count)
return true;
return false;
}
boolean right_check(){
if (right_count == 46 + fixed_count)
return true;
return false;
}
void move_block(){
if (digitalRead(9) == 0){
move_count_l++;
if (move_count_l > 30){
move_count_l = 0;
if (left_check())
x_pos++;
}
}
else
move_count_l = 30;
if (digitalRead(10) == 0){
move_count_r++;
if (move_count_r > 30){
move_count_r = 0;
if (right_check())
x_pos--;
}
}
else
move_count_r = 30;
}
boolean rotate_check(){
if (rotate_count == 46 + fixed_count)
return true;
return false;
}
void rotate(){
if (digitalRead(7) == 0){
if(!rotate_flag){
rotate_flag = true;
if(rotate_check())
muki++;
if (muki > 3)
muki = 0;
}
}
else {
rotate_flag = false;
}
}
boolean fall_check(){
if (fall_count == 46 + fixed_count)
return true;
return false;
}
void fall(){
fall_speed_count++;
if (fall_speed_count > 100){
fall_speed_count = 0;
if(fall_check())
y_pos++;
else
fixed_flag = true;
}
}
void data_make(){
if (fixed_flag){
for (int i = 0;i < 16;i++)
data_hex[i] = disp_hex[i];
fixed_count = fixed_count + 4;
x_pos = 6;
y_pos = 0;
select++;
if (select > 6)
select = 0;
}
fixed_flag = false;
for (int i = 0;i < 16;i++)
rotate_hex[i] = right_hex[i] = left_hex[i] = fall_hex[i] = disp_hex[i] = data_hex[i];
int d = muki + 1;
if (d > 3)
d = 0;
for (int i = 0;i < 4;i++){
disp_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos;
fall_hex[i + y_pos + 1] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos;
left_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos + 1;
right_hex[i + y_pos] |= ((block[select][muki] >> 4 * i) & 0xf) << x_pos - 1;
rotate_hex[i + y_pos] |= ((block[select][d] >> 4 * i) & 0xf) << x_pos;
}
}
void disp(){
fall_count = 0;
left_count = 0;
right_count = 0;
rotate_count = 0;
for (int i = 0;i < 16;i++) {
for (int j = 0;j < 16;j++) {
digitalWrite(2,LOW);
if ((disp_hex[i] & 0x8000 >> j) != 0)
digitalWrite(2,HIGH);
if ((fall_hex[i] & 0x8000 >> j) != 0)
fall_count++;
if ((left_hex[i] & 0x8000 >> j) != 0)
left_count++;
if ((right_hex[i] & 0x8000 >> j) != 0)
right_count++;
if ((rotate_hex[i] & 0x8000 >> j) != 0)
rotate_count++;
digitalWrite(4,HIGH);
digitalWrite(4,LOW);
}
digitalWrite(5,HIGH);
digitalWrite(5,LOW);
}
digitalWrite(6,HIGH);
digitalWrite(6,LOW);
}
太字が追加部分
回転が制限されている様子
今回の回転の制限も前回と同様です。ブロックの重なりで判定します。
判定方法はLEDの点灯(仮想)数を数えて(例1個目のブロックの場合は46個)少なければ重なっている。
重なっていれば回転できないと判断。
rotate_hex[i + y_pos] |= ((block[select][d] >> 4 * i) & 0xf) << x_pos;のdが次の方向を指定
この方法だと壁、ブロックの側面の両方に対応できる。
次回は横1列揃うと1段落とすプログラムを作って行きます。
では、また。