友達4ブロック-ココア盲


四つのレンズ

質問の概要


ブラインド公債を通じた新入社員のライアンが新しいゲームの開発を担当する.今回発売されるタイトルは「友達4ブロック」
同じ形状のカメラレンズブロック2×これは2つの形で4つ貼ってあると、消えていくにつれて点数が得られるゲームです.

プレートが上に示されている場合、ライアンは2を得ることができます.×2ブロック×7、コンソール×2×2で配置された4つのブロックはクリアされます.同じブロックに複数の2を含む×2に含めることができ、消去条件を満たす2×2複数の形があれば、一気に消すことができます.
ブロックがクリアされると、上のブロックが下に落ち、空白を埋めます.
空白のスペースを埋めたら、再び2×2つの同じ形の塊が集まると、再び消され、繰り返し落下します.
TTTANT
RRFACC
RRRFCC
TRRRAA
TTMMMF
TMMTTJ
各文字は、ライアン(R)、ムージ(M)、アピチ(A)、フロド(F)、ニオ(N)、トゥゲン(T)、ジェシー(J)、コン(C)を表す.
指定されたブロックの最初の配置を入力すると、削除されたブロックが全部で何個あるかを判断するプログラムを作成します.

問題を解く


実装を中心とした問題は,各機能の手法に従ってモジュール化して実現した.
4ブロックを参照すると、現在のインデックスで下、右、右の対角線が同じブロックであるかどうかを比較します.
2個以上4個のブロックが重複している場合を扱うために,閲覧時にブロックを直ちに削除せず,その後単独で削除処理を行った.
最後に積み木を下ろせ!
def down(m, n, board):
    for x in reversed(range(1, m)):
        for y in range(n):
            if board[x][y] == ' ':
                c_x = x
                while board[c_x][y] == " ":
                    c_x -= 1
                    if c_x < 1: break

                board[x] = board[x][:y] + board[c_x][y] + board[x][y+1:]
                board[c_x] = board[c_x][:y] + " " + board[c_x][y+1:]
                    

def deleting(board, t):
    for x, y in t:
        board[x] = board[x][:y] + " " + board[x][y+1:]
        
    t.clear()
    

def exploring(m, n, board, t):
    point = [(0,1), (1,0), (1,1)]
    
    for x in range(m-1):
        for y in range(n-1):
            if board[x][y] == ' ': continue
            four_B = True
            for p_x, p_y in point:
                if board[x][y] != board[x+p_x][y+p_y] :
                    four_B = False
                    break
            if four_B:
                t.add((x, y))
                for p_x, p_y in point:
                    t.add((x+p_x, y+p_y))
    return t


def solution(m, n, board):
    answer = 0
    t = set()
    exploring(m, n, board, t)
    
    while t:
        answer += len(t)
        deleting(board, t)
        down(m, n, board)
        exploring(m, n, board, t)   
    
    return answer