人工知能に関する断創録

このブログでは人工知能のさまざまな分野について調査したことをまとめています(更新停止: 2019年12月31日)

ブロックの積み上げ

ブロックを積めるようにします。

tetris06.jar

ブロックの積み上げ

まず一番大枠を見てみます。MainPanel.javaのゲームループを見てください。ブロックの落下(2006/5/28)でブロックが落下する処理block.move(Block.DOWN)をゲームループに追加しました。

ブロックが落下中に他のブロックにぶつかったときブロックが積み上がります。そこでblock.move(Block.DOWN)で他のブロックにぶつかったときtrue、ぶつからないときにfalseを返すように変更してます。もしぶつかったら次のブロックを生成しています。

    /**
     * ゲームループ
     */
    public void run() {
        while (true) {
            // ブロックを下方向へ移動する
            boolean isFixed = block.move(Block.DOWN);
            if (isFixed) {  // ブロックが固定されたら
                // 次のブロックをランダムに作成
                nextBlock = createBlock(field);
                block = nextBlock;
            }

            repaint();
            
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

ブロックの下方移動

次にブロックが下向きに移動するときの処理です。Block.javaのmove()です。

            case DOWN :
                newPos = new Point(pos.x, pos.y + 1);
                if (field.isMovable(newPos, block)) {
                    pos = newPos;
                } else {  // 移動できない=他のブロックとぶつかる=固定する
                    // ブロックをフィールドに固定する
                    field.fixBlock(pos, block);
                    // 固定されたらtrueを返す
                    return true;
                }
                break;

もしブロックが移動可能(isMovable()がtrue)ならそのまま移動し、他のブロックとぶつかって移動できない場合(isMovable()がfalse)ならブロックを固定します(fixBlock)。先ほど説明したようにmove()は移動できない場合にtrue を返します。

ここで下向き移動(DOWN)で他のブロックにぶつかって移動できない場合のみブロックを固定することに注意してください。左右移動では移動できなくても固定しません。

ブロックの固定

最後にブロックを固定する処理です。

    /**
     * 落ちきったブロックをボードに固定する
     * 
     * @param pos ブロックの位置
     * @param block ブロック
     */
    public void fixBlock(Point pos, int[][] block) {
        for (int i = 0; i < Block.ROW; i++) {
            for (int j = 0; j < Block.COL; j++) {
                if (block[i][j] == 1) {
                    if (pos.y + i < 0) continue;
                    // フィールドをブロックで埋める
                    field[pos.y + i][pos.x + j] = 1;
                }
            }
        }
    }

posの位置にブロックを固定します。fieldに1を埋めると壁と同じブロック(灰色ブロック)になり、固定されます。