Python 3プログラミング実戦Tetrisロボット(game類)

6535 ワード

シリーズ記事の入り口
『Python 3プログラミング実戦Tetrisロボット』
gameクラス
ゲームロジック制御クラスは、インタフェースとTetrisクラスの間の接着者であり、インタフェースのマウスやキーボードイベントを受け入れ、Tetrisクラスを操作し、ゲームロジックを実現する.単一ブロックの操作はTetrisですでに実現されており,gameクラスは主に消行アルゴリズム,新しいブロックの発生,ゲーム速度制御などを実現している.
せっけい構想
消層アルゴリズムの簡単な処理は,1行を発見し,1行を除去することである.本プロジェクトでは、消去可能なすべての行を見つけ、行番号を配列に格納し、一度に消去するテクニックを使用します.ゲームの速度の制御は、タイマーを使って実現されますが、pythonのタイマーは他の言語と少し違い、新しいタイマーオブジェクトが絶えず発生し、違和感を感じ始めますが、重視していません.後で確認する、メモリの漏れが発生し、tkinterを使用する.afterが置き換えられました.
そうかんていすう
SCORES = (0,1,3,7,10)      #       

STEPUPSCORE = 50           #    50 ,        
STEPUPINTERVAL = 100       #        ,         100  

具体的な実装
ゲーム状態変数
game.gameRunningStatus
  • 0:ゲーム未開始
  • 1:手動ゲーム
  • 2:ゲーム再生
  • 5:ゲーム一時停止
  • ゲームを始める
    def start(self):
        self.gameRunningStatus = 1
        self.gameSpeedInterval = 1000        #       
        self.gameSpeed = 1                   #       
        self.gameLevels = 0                  #    
        self.gameScores = 0                  #    
        self.app.updateGameInfo(1,0,0)       #        
        self.canvas.delete(ALL)              #       
        self.nextCanvas.delete(ALL)          #         
        initGameRoom()                       #          
    
        self.tetris = Tetris(self.canvas, 4, 0, random.randint(0,6))             #          
        for i in range(random.randint(0,4)):                                     #       ,     
            self.tetris.rotate()
        self.nextTetris = Tetris(self.nextCanvas, 1, 1, random.randint(0,6))     #         
        for i in range(random.randint(0,4)):                                     #         (  )
            self.nextTetris.rotate()
    
        self.tick = Timer(self.gameSpeedInterval / 1000, self.tickoff)           #          
        self.tick.start()

    次のブロックを生成
    ゲーム制御の主な関数は、ブロックが底部に落下した後、消層、統計スコア、速度等級判定、ゲームが終了したか否か判定、および次のブロックをゲーム空間に移動し、次のブロックを生成して次のブロック表示空間に表示する.
    def generateNext(self):
        cleanLevels = self.clearRows()                               #        
        if cleanLevels > 0:                                          #     ,    
            self.gameLevels += cleanLevels
            self.gameScores += SCORES[cleanLevels]
            if self.gameScores / STEPUPSCORE >= self.gameSpeed:
                self.gameSpeed += 1
                self.gameSpeedInterval -= STEPUPINTERVAL
            self.app.updateGameInfo(self.gameSpeed, self.gameLevels, self.gameScores)
        self.tetris = Tetris(self.canvas, 4, 0, self.nextTetris.getTetrisShape())    #   nexTetris     
        for i in range(self.nextTetris.getRotateCount()):
            if not self.tetris.rotate():
                break
        if self.tetris.canPlace(4, 0):                   #         
            self.nextCanvas.delete(ALL)                  #      ,              
            self.nextTetris = Tetris(self.nextCanvas, 1, 1, random.randint(0,6))
            for i in range(random.randint(0,4)):
                self.nextTetris.rotate()
        else:                                            #     
            self.gameRunningStatus = 0
            self.canvas.create_text(150, 200, text = "Game is over!", fill="white", font = "Times 28 italic bold")
            self.app.setStartButtonText("Start")
            print("game is over!")

    統計消去可能レイヤ
    clearRows関数は、消去可能なレイヤを検索し、消去可能なレイヤの総数を返します.
    def clearRows(self):
        occupyLines = []                  #         
        h = 20
        while h > 0:
            allOccupy = 0
            for i in range(1, 11):
                if GameRoom[h][i]:
                    allOccupy += 1        # block  
            if allOccupy == 10:           #   
                occupyLines.append(h)     #     
            elif allOccupy == 0:          #      ,    
                break
            h -= 1
        if len(occupyLines) > 0:          #     
            self.doCleanRows(occupyLines) #      
        return len(occupyLines)

    消層関数
    消層関数は、clearRows関数に基づいて統計された消層可能な行番号に基づいて、ゲーム空間の満行を除去します.アルゴリズムの難点は,2つの変数を同時に制御することであり,1つはゲーム空間を下から上へ遍歴する一方,満行以上の空間データを下へ移動し,下へ移動するステップ長は除去された行数とする.
    def doCleanRows(self, lines):
        index = 0                                 #           
        h = lines[index]                          #       
        while h >= 0:                             #               
            if index < len(lines) and h == lines[index]:         #       
                index += 1                        #       1
                for j in range(1, 11):
                    GameRoom[h][j] = 0            #         
                    for b in self.canvas.find_closest(\         # Canvas    
                        j * BLOCKSIDEWIDTH - HALFBLOCKWIDTH, \
                        h  * BLOCKSIDEWIDTH - HALFBLOCKWIDTH):
                        self.canvas.delete(b)
            else:                                 #         
                count = 0                         #     ,  ,        
                for j in range(1, 11):
                    if GameRoom[h][j] == 1:
                        count += 1
                        GameRoom[h + index][j] = GameRoom[h][j]     #   index  ,      ,         
                        GameRoom[h][j] = 0
                        for b in self.canvas.find_closest(j * BLOCKSIDEWIDTH - HALFBLOCKWIDTH, h  * BLOCKSIDEWIDTH - HALFBLOCKWIDTH):
                            self.canvas.move(b, 0, index * BLOCKSIDEWIDTH)
                if count == 0:                   #        ,    
                    break
            h -= 1

    ブロック制御
    ブロック制御はすでにTetrisクラスで実現されており、gameクラスでは、現在のブロックにイベントを転送するだけでよい.moveDownEnd-ブロック直下関数が1つだけ追加されました.
    def moveDownEnd(self):
        while self.moveDown():      #     ,      
            pass

    ゲームスピードコントロール
    ゲームの速度制御は簡単で、down関数をタイミングよくトリガーするだけでいいです.
    def tickoff(self):
        if self.gameRunningStatus == 1:
            self.moveDown()
            self.tick = Timer(self.gameSpeedInterval / 1000, self.tickoff)
            self.tick.start()

    コンテンツ予告
    タイマの使用により、新しいスレッドが導入され、リソース競合の問題が発生し、注文するとスレッド競合が解決します.
    プロジェクトアドレス
    https://gitee.com/zhoutk/ptetris
     
    https://github.com/zhoutk/ptetris

    実行方法
    1. install python3, git
    2. git clone https://gitee.com/zhoutk/ptetris (or download and unzip source code)
    3. cd ptetris
    4. python3 tetris
    
    This project surpport windows, linux, macOs
    
    on linux, you must install tkinter first, use this command:  
    sudo apt install python3-tk

    関連項目
    C++版、プロジェクトアドレスを実現しました.
    https://gitee.com/zhoutk/qtetris