トップページ > 電子工作インデックス > テトリス > 7. 一列判定消し関数
ブロックが横一列そろっているか確認し、そろっている場合はその列を消去、 上の段を1段下げて表示、得点を加算します。 連鎖に対応するために、ブロックの切れ目が見つかるまで永久ループ→切れ目が 見つかったらbreak…という構造になっています。
このテトリスのハードの仕様上、ブロックは1行分でも、配列としては2行分のLEDを 使っているので、列の消去&得点のカウントは2行単位で行います。また、壁の厚さは LED2つ分なので、そのことも考慮します。
液晶用表示機にスコアを出すsocore_out()関数は後述です。
//********************************************************************
//グローバル変数
//得点用の変数
unsigned long int score;
//********************************************************************
//一列消し関数
void check_lines(void)
{
//for文用変数
int i,j,k;
//1列埋まっているかを確認するための変数
char flag;
//連鎖のカウント用
int lines=0;
while(1)
{
//y方向の、タテの行をまず指定します。
for(i=2;i<36;i++)
{
//最初にflagを1にしておきます。
flag = 1;
//各行において、x方向に動いて、ブロックで埋まっているかチェック。
for(j=2;j<22;j++)
{
//背景の配列backを対象に、調査します。
if(back[i][j] == 0)
{
//もしブロックの切れ目があれば、flagを"0"にします。
flag = 0;
}
}
//1列すべてブロックで埋まっていれば、for文を抜けて、その列を消去しに行く。
//この時、変数iは消去する行の番号を保持してます。
if(flag == 1) break;
}
//for文を最後までまわしきって、ブロックで埋まった行が無い場合(flagが"0")は、
//whileループを抜けて得点の清算に行きます。
if(flag == 0) break;
//連鎖用変数をインクリメント
lines++;
//消した列の分だけ、下にずらします。
//変数iは消去する列の番号です。(上のfor文から持ってきた)
for(k=i;k>0;k--)
{
for(j=1;j<22;j++)
{
back[k][j] = back[k-1][j];
}
}
}
//↑ここまでがwhile(1)ループです。
//--------------------------------------------------------------------
//↓while(1)をbreak後の処理
//消したラインの数によって、スコアを加算。
//さらにブロック破壊音を出し、液晶に得点を表示し、終了します。
//2行単位でカウントする点に注意…。
switch(lines)
{
case 2:
score+=100;
voice2();
socre_out();
break;
case 4:
score+=300;
voice2();
socre_out();
break;
case 6:
score+=500;
voice2();
socre_out();
break;
case 8:
score+=1000;
voice2();
socre_out();
break;
}
}
//********************************************************************