Urara_Chiya

dinosaur_farmer.py

Oct 19th, 2025
1,673
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.14 KB | None | 0 0
  1. # ==============================================================================
  2. # 恐龙模式 (贪吃蛇) 自动化脚本 (dinosaur_farmer_v4.py)
  3. #
  4. # 版本 4: 移除了所有 """...""" 形式的文档字符串。
  5. #
  6. # 策略:
  7. # 1. 保证在调用 measure() 时,无人机正位于一个苹果上。
  8. # 2. 采用动态寻路:每移动一步都重新计算到目标的最优路径,以应对
  9. #    自身尾巴(移动障碍物)的变化。
  10. # 3. 自动完成整个游戏、收获、重玩的循环。
  11. #
  12. # 严格遵守所有编程限制。
  13. # ==============================================================================
  14.  
  15. from utils import *
  16.  
  17. # ------------------------------------------------------------------------------
  18. # 配置与常量
  19. # ------------------------------------------------------------------------------
  20. START_X = 0
  21. START_Y = 0
  22.  
  23. DIRECTION_VECTORS = {
  24.     North: (0, 1),
  25.     East: (1, 0),
  26.     South: (0, -1),
  27.     West: (-1, 0)
  28. }
  29. OPPOSITE_DIRECTIONS = {
  30.     North: South,
  31.     South: North,
  32.     East: West,
  33.     West: East
  34. }
  35.  
  36. # ------------------------------------------------------------------------------
  37. # 辅助函数
  38. # ------------------------------------------------------------------------------
  39.  
  40. def manhattan_distance(x1, y1, x2, y2):
  41.     return abs(x1 - x2) + abs(y1 - y2)
  42.  
  43. # 准备开始一轮恐龙游戏,结束时无人机应位于第一个苹果上。
  44. def setup_game():
  45.     quick_print("正在准备新一轮的恐龙游戏...")
  46.     clear()
  47.     move_to(START_X, START_Y)
  48.    
  49.     # 假设每次生成苹果需要1个仙人掌
  50.     if num_items(Items.Cactus) < get_world_size() * get_world_size():
  51.         quick_print("警告: 仙人掌数量可能不足以填满整个地图。")
  52.  
  53.     # 装备帽子,这会在无人机下方生成第一个苹果
  54.     quick_print("装备恐龙帽...")
  55.     change_hat(Hats.Dinosaur_Hat)
  56.    
  57.     # 检查苹果是否成功生成
  58.     if get_entity_type() != Entities.Apple:
  59.         quick_print("错误:装备帽子后未生成苹果。")
  60.         return False
  61.        
  62.     return True
  63.  
  64. # ------------------------------------------------------------------------------
  65. # 核心寻路算法
  66. # ------------------------------------------------------------------------------
  67.  
  68. # 全局变量,用于在递归调用中共享状态
  69. path_solution = []
  70. visited_grid = []
  71. apple_x = 0
  72. apple_y = 0
  73.  
  74. def find_path_recursive(current_x, current_y):
  75.     global path_solution
  76.     global visited_grid
  77.     global apple_x
  78.     global apple_y
  79.  
  80.     if current_x == apple_x and current_y == apple_y:
  81.         return True
  82.  
  83.     visited_grid[current_y][current_x] = True
  84.    
  85.     possible_moves = []
  86.     directions_to_check = [North, East, South, West]
  87.     for direction in directions_to_check:
  88.         dx, dy = DIRECTION_VECTORS[direction]
  89.         next_x, next_y = current_x + dx, current_y + dy
  90.        
  91.         world_size = get_world_size()
  92.         if 0 <= next_x < world_size and 0 <= next_y < world_size:
  93.             if not visited_grid[next_y][next_x]:
  94.                 dist = manhattan_distance(next_x, next_y, apple_x, apple_y)
  95.                 possible_moves.append([dist, direction])
  96.  
  97.     n = len(possible_moves)
  98.     for i in range(n):
  99.         for j in range(0, n - i - 1):
  100.             if possible_moves[j][0] > possible_moves[j+1][0]:
  101.                 temp = possible_moves[j]
  102.                 possible_moves[j] = possible_moves[j+1]
  103.                 possible_moves[j+1] = temp
  104.  
  105.     for move_info in possible_moves:
  106.         direction = move_info[1]
  107.        
  108.         path_solution.append(direction)
  109.         dx, dy = DIRECTION_VECTORS[direction]
  110.        
  111.         if find_path_recursive(current_x + dx, current_y + dy):
  112.             return True
  113.            
  114.         path_solution.pop()
  115.            
  116.     return False
  117.  
  118. def find_path_to_apple(start_x, start_y, target_x, target_y, snake_body):
  119.     global path_solution
  120.     global visited_grid
  121.     global apple_x
  122.     global apple_y
  123.    
  124.     apple_x = target_x
  125.     apple_y = target_y
  126.     path_solution = []
  127.    
  128.     world_size = get_world_size()
  129.  
  130.     visited_grid = []
  131.     for _ in range(world_size):
  132.         row = []
  133.         for _ in range(world_size):
  134.             row.append(False)
  135.         visited_grid.append(row)
  136.    
  137.     # 蛇的身体是障碍物
  138.     for segment in snake_body:
  139.         visited_grid[segment[1]][segment[0]] = True
  140.  
  141.     if find_path_recursive(start_x, start_y):
  142.         return path_solution
  143.     else:
  144.         return None
  145.  
  146. # ------------------------------------------------------------------------------
  147. # 主游戏逻辑
  148. # ------------------------------------------------------------------------------
  149.  
  150. def play_dinosaur_game():
  151.     if not setup_game():
  152.         change_hat(Hats.Green_Hat) # 如果设置失败,换回绿帽以重置状态
  153.         return
  154.  
  155.     snake_body = [[get_pos_x(), get_pos_y()]]
  156.     game_over = False
  157.  
  158.     while not game_over:
  159.         # 此时无人机正位于一个苹果上,安全调用 measure()
  160.         measured_pos = measure()
  161.         if not measured_pos:
  162.             quick_print("错误: measure() 未返回位置。可能是游戏结束的信号。")
  163.             break
  164.        
  165.         target_x, target_y = measured_pos
  166.         quick_print("下一个苹果在: (" + str(target_x) + ", " + str(target_y) + ")")
  167.        
  168.         # 第一次寻路,规划从当前苹果到下一个苹果的完整路径
  169.         head_x, head_y = snake_body[0]
  170.         path = find_path_to_apple(head_x, head_y, target_x, target_y, snake_body)
  171.  
  172.         if not path:
  173.             quick_print("被困住了!找不到初始路径。游戏结束。")
  174.             break
  175.  
  176.         # 吃掉当前苹果并开始移动
  177.         # 移动第一步,意味着“吃掉”了脚下的苹果,尾巴需要增长
  178.         direction_to_move = path[0]
  179.         if move(direction_to_move):
  180.             new_head_x, new_head_y = get_pos_x(), get_pos_y()
  181.             snake_body.insert(0, [new_head_x, new_head_y])
  182.             # 尾巴增长:不执行 snake_body.pop()
  183.             quick_print("吃到苹果!尾巴长度: " + str(len(snake_body)))
  184.         else:
  185.             quick_print("错误:初始移动失败。")
  186.             break
  187.            
  188.         # 循环移动,直到到达目标苹果
  189.         while get_pos_x() != target_x or get_pos_y() != target_y:
  190.             # 动态寻路:每一步都重新计算路径,因为蛇身在移动
  191.             head_x, head_y = snake_body[0]
  192.             current_path = find_path_to_apple(head_x, head_y, target_x, target_y, snake_body)
  193.            
  194.             if not current_path:
  195.                 quick_print("移动途中被困住!找不到路径。游戏结束。")
  196.                 game_over = True
  197.                 break
  198.  
  199.             direction_to_move = current_path[0]
  200.             if move(direction_to_move):
  201.                 new_head_x, new_head_y = get_pos_x(), get_pos_y()
  202.                 snake_body.insert(0, [new_head_x, new_head_y])
  203.                 snake_body.pop() # 正常移动,尾巴前进
  204.             else:
  205.                 quick_print("错误:中途移动失败,路径规划可能出错。")
  206.                 game_over = True
  207.                 break
  208.        
  209.         if game_over:
  210.             break
  211.  
  212.         # 检查是否已满
  213.         if len(snake_body) >= get_world_size() * get_world_size():
  214.             quick_print("恭喜!填满了整个地图!")
  215.             break
  216.  
  217.     # 游戏结束,收获骨头
  218.     tail_length = len(snake_body)
  219.     bones_earned = tail_length * tail_length
  220.     quick_print("最终尾巴长度: " + str(tail_length))
  221.     quick_print("预计获得骨头: " + str(bones_earned))
  222.    
  223.     quick_print("正在更换帽子以收获骨头...")
  224.     change_hat(Hats.Green_Hat) # 换掉帽子以收获
  225.     quick_print("收获完成!")
  226.  
  227.  
  228. # ==============================================================================
  229. # 主函数
  230. # ==============================================================================
  231.  
  232. def main():
  233.     while True:
  234.         play_dinosaur_game()
  235.         quick_print("======== 完成一轮恐龙挑战,准备开始下一轮... ========")
  236.  
  237. if __name__ == "__main__":
  238.     main()
  239.  
Advertisement
Add Comment
Please, Sign In to add comment