恐龙完整回路
沿预先生成的完整回路前进,用较多移动换取更低的逐步计算开销。
使用说明
- 可作为独立游戏脚本运行。成本模型中的 new 指这个版本,原生 A/B 测试也用它与旧基线比较。
运行前提与限制
独立脚本需要 32×32 农场、恐龙科技和足够支付一局苹果的材料;每局开始与结束都会清场,运行前停止其他无人机。
当前轻量捷径保留了原策略的增长死路,不保证每局填满。起点 (0,0)、苹果依次为 (0,1) 和 (1,0) 就是已知反例;遇到死路后收尾并停止。
20 个随机种子的本地模型中,轻量版与旧版移动步数一致,算法主体预计 tick 减少约 92.3%。这是成本模型估算,尚未由游戏引擎实测确认;综合脚本中的恐龙实现仍是旧策略。
运行环境:游戏内代码窗口。说明由 AI 辅助整理;更多对照版本、测试和记录见恐龙与骨头目录。
完整源码
dinosaur_32_full_cycle_experiment.py · 107 行。代码块右上角可复制完整代码。
# The Farmer Was Replaced - standalone 32x32 dinosaur snake farm.
# Run in the game, with no other drones working on the farm.
# Each round clears the entire farm before and after playing.
# Requires Dinosaurs and enough apple materials for a full round.
# A complete Hamilton cycle guarantees coverage without shortcut dead ends.
# Directions are built once; each movement needs no body tracking or search.
WORLD_SIZE = 32
def dino_cycle_index(x, y):
if y == 0:
return x
if x == 0:
return WORLD_SIZE * WORLD_SIZE - y
if y % 2 == 1:
return WORLD_SIZE + (y - 1) * (WORLD_SIZE - 1) + WORLD_SIZE - 1 - x
return WORLD_SIZE + (y - 1) * (WORLD_SIZE - 1) + x - 1
def build_dino_route():
# Every entry is the direction leaving that Hamilton-cycle index.
# Reserve column 0 for the return path from the top to the origin.
route = []
for x in range(WORLD_SIZE - 1):
route.append(East)
for y in range(1, WORLD_SIZE):
route.append(North)
direction = East
if y % 2 == 1:
direction = West
for x in range(WORLD_SIZE - 2):
route.append(direction)
route.append(West)
for y in range(WORLD_SIZE - 1):
route.append(South)
return route
def follow_dino_route(route, head_index, target_index):
# Split at the wrap point: no modulo, position queries, scoring or queue
# operations in the movement loop. The game tracks growth and the tail.
if target_index < head_index:
for index in range(head_index, WORLD_SIZE * WORLD_SIZE):
if not move(route[index]):
return False
head_index = 0
for index in range(head_index, target_index):
if not move(route[index]):
return False
return True
def dinosaur_once(route):
if num_unlocked(Unlocks.Dinosaurs) == 0:
quick_print("Dinosaur farming stopped: Dinosaurs is not unlocked.")
return False
cost = get_cost(Entities.Apple)
if cost == None:
quick_print("Dinosaur farming stopped: apple cost is unavailable.")
return False
for item in cost:
if num_items(item) < cost[item] * WORLD_SIZE * WORLD_SIZE:
quick_print("Dinosaur farming stopped: not enough apple materials.")
return False
start_ticks = get_tick_count()
start_bones = num_items(Items.Bone)
clear()
change_hat(Hats.Dinosaur_Hat)
head_index = dino_cycle_index(get_pos_x(), get_pos_y())
apples = 0
steps = 0
next_apple = measure()
while next_apple != None:
target_index = dino_cycle_index(next_apple[0], next_apple[1])
if target_index == head_index:
break
if not follow_dino_route(route, head_index, target_index):
break
steps += (target_index - head_index) % (WORLD_SIZE * WORLD_SIZE)
head_index = target_index
apples += 1
# Reaching the current apple reveals the following apple.
next_apple = measure()
change_hat(Hats.Straw_Hat)
clear()
elapsed = get_tick_count() - start_ticks
bones = num_items(Items.Bone) - start_bones
quick_print("Dinosaur round: apples", apples, "moves", steps, "ticks", elapsed, "bones", bones)
if next_apple != None or apples != WORLD_SIZE * WORLD_SIZE - 1:
quick_print("Dinosaur farming stopped: round ended before full coverage.")
return False
return True
def main():
if get_world_size() != WORLD_SIZE:
quick_print("Dinosaur script requires a 32x32 farm.")
return
route = build_dino_route()
while dinosaur_once(route):
pass
main()