項目實踐:重力四子棋遊戲


在此基礎之上做出了修改

class GravityConnectFour:   #創建類
    def __init__(self):
        # 創建6行7列的空棋盤,用 '.' 表示還沒有落子的棋格
        self.rows = 6
        self.cols = 7
        self.board = [['.' for _ in range(self.cols)] 
                      for _ in range(self.rows)]    #初始化棋盤格,全部用.填充,先填滿一行,再換行
        self.current_player = 'X'  # X 代表玩家1,O 代表玩家2
        
    #顯示遊戲棋盤(這塊是讓豆包幫我做的,我覺得up主的棋盤不太好看)
    def display_board(self):
        # 打印列號
        print("  " + " ".join(map(str, range(1, self.cols + 1))))   
        print("-" * (self.cols * 2 + 3))
        
        # 打印棋盤內容
        for row in self.board:
            print("| " + " ".join(row) + " |")
        
        print("-" * (self.cols * 2 + 3))
        
    #獲取指定列中下一個可落子的行號(從底部往上找)
    def get_next_open_row(self, col):
        for r in range(self.rows - 1, -1, -1):
            if self.board[r][col] == '.':
                return r
        return -1  # 如果列已滿,返回-1
    
    #檢查落子是否有效
    def is_valid_move(self, col):
        # 檢查列號是否在有效範圍內
        if col < 0 or col >= self.cols:
            return False
        # 檢查列是否已滿:如果第一行(即頂部)是空的,説明列未滿
        return self.board[0][col] == '.'  
    
    #將棋子放到指定列的最下方空位
    def drop_piece(self, col):
        row = self.get_next_open_row(col)
        if row != -1:
            self.board[row][col] = self.current_player
            return row
        return -1  # 如果落子失敗,返回-1

    #檢查在指定位置落子後是否形成四子連線(即看贏了沒有),最搞的一part
    def check_win(self, row, col):

        piece = self.current_player
        # 檢查四個方向的連線:水平、垂直、主對角、副對角
        directions = [(0, 1),  # 水平向右
                     (1, 0),  # 垂直向下
                     (1, 1),  # 主對角線
                     (1, -1)]  # 副對角線
        
        for dr, dc in directions:
            # 統計在當前方向上連續的相同棋子數量
            count = 1  # 當前位置已經有一個棋子

            # 正向檢查(向一個方向延伸)
            r, c = row + dr, col + dc
            while 0 <= r < self.rows and 0 <= c < self.cols and self.board[r][c] == piece:
                count += 1
                r += dr
                c += dc
                
            # 反向檢查(向相反方向延伸)
            r, c = row - dr, col - dc
            while 0 <= r < self.rows and 0 <= c < self.cols and self.board[r][c] == piece:
                count += 1
                r -= dr
                c -= dc
                
            # 如果連續四個或更多相同棋子,返回勝利
            if count >= 4:
                return True
            
        return False
    
    #檢查棋盤是否已滿(檢查頂部行是否都有棋子)
    def is_board_full(self):
        for col in range(self.cols):
            if self.board[0][col] == '.':
                return False
        return True
    #切換當前玩家
    def switch_player(self):
        self.current_player = 'O' if self.current_player == 'X' else 'X'
    
    #獲取並驗證玩家輸入
    def get_player_input(self):
        while True:
            try:
                col_input = input(f"玩家 {self.current_player},請輸入要落子的列號 (1-{self.cols}): ")
                # 檢查是否為數字
                col = int(col_input)
                # 檢查列號是否在有效範圍內
                if 1 <= col <= self.cols:
                    # 將列號轉換為0索引
                    col_idx = col - 1
                    # 檢查列是否已滿
                    if self.is_valid_move(col_idx):
                        return col_idx
                    else:
                        print("該列已滿,請選擇其他列。")
                else:
                    print(f"無效列號,請輸入1-{self.cols}之間的數字。")
            except ValueError:
                print("無效輸入,請輸入數字列號。")
    #重置遊戲棋盤和狀態
    def reset_game(self):
        self.board = [['.' for _ in range(self.cols)] for _ in range(self.rows)]
        self.current_player = 'X'
        
    #遊戲主循環
    def play(self):
        print("歡迎來到重力四子棋遊戲!")
        print("玩家1使用 X,玩家2使用 O")
        print("遊戲規則:率先在棋盤上形成連續4個相同棋子(橫、豎、斜向均可)的玩家獲勝\n")
        
        play_again = True
        
        while play_again:
            
            # 重置遊戲
            self.reset_game()
            
            # 顯示初始棋盤
            self.display_board()
            
            game_over = False
            
            while not game_over:
                
                # 獲取玩家輸入並落子
                col = self.get_player_input()
                row = self.drop_piece(col)
                
                # 顯示更新後的棋盤
                self.display_board()
                
                # 檢查是否獲勝
                if self.check_win(row, col):
                    print(f"\n🎉 恭喜玩家 {self.current_player} 獲勝! 🎉")
                    game_over = True
                # 檢查是否平局
                elif self.is_board_full():
                    print("\n😐 棋盤已滿,遊戲平局!😐")
                    game_over = True
                else:
                    # 切換到下一個玩家
                    self.switch_player()
            
            # 詢問是否重新開始遊戲
            while True:
                answer = input("\n是否要重新開始遊戲? (y/n): ").lower()
                if answer == 'y':
                    play_again = True
                    break
                elif answer == 'n':
                    play_again = False
                    break
                else:
                    print("無效輸入,請輸入 y 或 n")
        
        print("\n感謝您玩重力四子棋遊戲!再見!")

# 啓動遊戲
if __name__ == "__main__":
    game = GravityConnectFour()
    game.play()