文章目錄
僅為自動化演示,實際2048判定邏輯需要更加嚴謹
參考代碼
# 使用提醒:
# 1. xbot包提供軟件自動化、數據表格、Excel、日志、AI等功能
# 2. package包提供訪問當前應用數據的功能,如獲取元素、訪問全局變量、獲取資源文件等功能
# 3. 當此模塊作為流程獨立運行時執行main函數
# 4. 可視化流程中可以通過"調用模塊"的指令使用此模塊import xbot
from xbot import print, sleep
from .import package
from .package import variables as glv
import numpy as np
import random
from xbot import win32class Game2048:def __init__(self):"""初始化2048游戲自動化"""self.web_page = Noneself.board_size = 4self.directions = ['up', 'down', 'left', 'right']def start_game(self):"""啟動游戲并初始化"""try:# 打開2048游戲網頁self.web_page = xbot.web.create(url="https://shop.yingdao.com/2048/index.html",mode="chrome")sleep(2) # 等待頁面加載# 點擊開始游戲按鈕(如果有)start_btn = self.web_page.find_by_xpath('//a[@id="newgamebutton"]')if start_btn:start_btn.click()sleep(1)return Trueexcept Exception as e:print(f"啟動游戲失敗: {e}")return Falsedef get_board_state(self):"""獲取當前游戲棋盤狀態""" try:# 查找所有數字單元格number_cells = self.web_page.find_all_by_xpath('//div[contains(@class,"number-cell")]')number_arr = [int(item.get_text()) if item.get_text().strip() else 0 for item in number_cells]board = np.array(number_arr, dtype=int).reshape(self.board_size, self.board_size)return boardexcept Exception as e:print(f"獲取棋盤狀態失敗: {e}")return Nonedef make_move(self, direction):"""執行移動操作"""try:# 映射方向到鍵盤按鍵key_map = {'up': '{UP}','down': '{DOWN}','left': '{LEFT}','right': '{RIGHT}'}# 發送鍵盤事件win32.send_keys(keys=key_map[direction],send_key_delay=50,delay_after=1)sleep(0.3) # 等待動畫效果return Trueexcept Exception as e:print(f"執行移動失敗: {e}")return Falsedef simple_ai_move(self, board):"""簡單AI策略決定下一步移動"""# 這里可以實現更復雜的AI算法# 示例:隨機選擇一個有效方向valid_moves = []for direction in self.directions:# 模擬移動看是否有效new_board = self.simulate_move(board.copy(), direction)if not np.array_equal(new_board, board):valid_moves.append(direction)return random.choice(valid_moves) if valid_moves else Nonedef simulate_move(self, board, direction):"""模擬2048移動后的棋盤狀態(包含合并邏輯)"""new_board = np.zeros((self.board_size, self.board_size), dtype=int)if direction == 'up':for col in range(self.board_size):column = board[:, col]non_zero = column[column != 0] # 獲取非零數字if len(non_zero) == 0: # 如果全零,直接跳過new_board[:, col] = columncontinue# 合并相鄰相同數字merged = []i = 0while i < len(non_zero):if i + 1 < len(non_zero) and non_zero[i] == non_zero[i + 1]:merged.append(non_zero[i] * 2) # 合并i += 2 # 跳過下一個數字(已合并)else:merged.append(non_zero[i])i += 1# 填充到新列new_column = np.zeros(self.board_size, dtype=int)new_column[:len(merged)] = mergednew_board[:, col] = new_columnelif direction == 'down':for col in range(self.board_size):column = board[:, col]non_zero = column[column != 0]if len(non_zero) == 0: # 如果全零,直接跳過new_board[:, col] = columncontinue# 從下往上合并merged = []i = len(non_zero) - 1while i >= 0:if i - 1 >= 0 and non_zero[i] == non_zero[i - 1]:merged.insert(0, non_zero[i] * 2) # 合并i -= 2else:merged.insert(0, non_zero[i])i -= 1new_column = np.zeros(self.board_size, dtype=int)new_column[-len(merged):] = mergednew_board[:, col] = new_columnelif direction == 'left':for row in range(self.board_size):row_data = board[row, :]non_zero = row_data[row_data != 0]if len(non_zero) == 0: # 如果全零,直接跳過new_board[row, :] = row_datacontinue# 從左往右合并merged = []i = 0while i < len(non_zero):if i + 1 < len(non_zero) and non_zero[i] == non_zero[i + 1]:merged.append(non_zero[i] * 2)i += 2else:merged.append(non_zero[i])i += 1new_row = np.zeros(self.board_size, dtype=int)new_row[:len(merged)] = mergednew_board[row, :] = new_rowelif direction == 'right':for row in range(self.board_size):row_data = board[row, :]non_zero = row_data[row_data != 0]if len(non_zero) == 0: # 如果全零,直接跳過new_board[row, :] = row_datacontinue# 從右往左合并merged = []i = len(non_zero) - 1while i >= 0:if i - 1 >= 0 and non_zero[i] == non_zero[i - 1]:merged.insert(0, non_zero[i] * 2)i -= 2else:merged.insert(0, non_zero[i])i -= 1new_row = np.zeros(self.board_size, dtype=int)new_row[-len(merged):] = mergednew_board[row, :] = new_rowreturn new_boarddef auto_play(self, max_moves=1000):"""自動玩游戲主循環"""if not self.start_game():returnmove_count = 0while move_count < max_moves:try: # 獲取當前棋盤狀態board = self.get_board_state() print("board",board)if board is None:print("無法獲取棋盤狀態")breakprint(f"當前棋盤狀態(移動{move_count}次):")print(board)# 決定下一步移動direction = self.simple_ai_move(board)print("direction",direction)if not direction:print("沒有有效移動,游戲可能結束")breakprint(f"AI決定移動方向: {direction}")# 執行移動self.make_move(direction)move_count += 1# 短暫暫停sleep(0.1)except KeyboardInterrupt:print("用戶中斷自動游戲")breakexcept Exception as e:print(f"游戲過程中出錯: {e}")breakprint("自動游戲結束")def main(args):game = Game2048()game.auto_play()