コラム / テトリスぽいもの / 32



さて、
消せる行があるかチェックする処理ですが、
「全ての行についてループしながら、
 その行のフラグ全てについてループしてチェックし、
 消せる行かどうかチェックする」
という処理になります。
二次元配列が出てきてちょっと複雑になりそうですね。
というわけで、また処理をわけます。
自分が命令を作るのは、
なんらかの処理が複雑で、あとでわからなくなりそうなときとか、
その部分で何をするかを、
命令の名前だけでわかるようにしたいときとかです。
そうすれば、あとでソースを見ても、
「どうやって実装されているのかはわからないが、
 この部分で何をしたいのかはわかる」
という事になります。
さて、処理をわけるなら、
「指定された行は削除可能か」
という処理が妥当です。
アッー!!!
間違えた!
「消せる行があるかチェックする処理の中で
 指定された行が削除可能かどうか調べる」
ってものすごい無意味でした
「消せる行の有無がわかる時点で、
 それがどの行かはわかっているのに、
 有無しか返さないと、
 消せる行がどれか、調べなおさなければならない」
ですから。二度手間です。
指定された行は削除可能か
って関数は作りますが、
その外側で、
「消せる行があるかないか」
という関数は作るのをやめましょう。
では、指定された行は削除可能か、定義部です。
   TMapBlocks = Class(TObject)
   private
   public
       (略)
       function isFull(at:integer):Boolean;
       (略)
   end;
実装部です。
function TMapBlocks.isFull(at:integer):Boolean;
var i:integer;
begin
   for i:=0 to 9 do begin
       if not isBlock(i,at) then begin
           Result:=False;
           Exit;
       end;
   end;
   Result:=True;
end;
forで横方向にループしています。
中では、isBlock関数をつかって、
指定された行の中の、ループ対象のブロックが、
あるかないか調べます。
もし無い場合は、
Resultを偽にしてExit;、つまり、
関数の返り値をFalseにして関数を終わります。
これで、行のループにつき、
一箇所でもブロックが無い部分があったら、
削除不能、という結果を返す
という事が表現できます。
もし、ブロックが無い部分がその行になければ、
ループを無事ぬけるので、
最後の、
Result:=True;
が実行されて、
「指定された行は削除可能」
という結果が返せます。
さて、次回では
今つくった関数と、前回つくった手続きを使って、
「削除可能な行がなくなるまで無限ループし、
 削除可能な行があれば、削除処理を呼び出す。」
という命令を作ります。