diff --git a/dinosaurs.py b/dinosaurs.py index 188c809..f285eb3 100644 --- a/dinosaurs.py +++ b/dinosaurs.py @@ -55,6 +55,8 @@ import helpers # Fully traversing a very large farm can take a long time and you might not actually need that many bones. Feel # free to use set_world_size() to change the size of the farm to something more convenient. +dumb_mode = True + last_move = None next_x = -1 next_y = -1 @@ -66,80 +68,187 @@ OPPOSITE = { West: East } +tail = [] +tail_length = 0 + def any_other_move_available(): for d in [North, East, South, West]: - if last_move is not None and d == OPPOSITE[last_move]: + if last_move != None and d == OPPOSITE[last_move]: continue if can_move(d): return True return False -def safe_move(direction): - global last_move - - # Only forbid reversal if another move exists - if last_move is not None and direction == OPPOSITE[last_move]: - if any_other_move_available(): - return False - - moved = move(direction) - if moved: - last_move = direction - return moved - def reset(): global last_move global next_x global next_y + global tail + global tail_length last_move = None next_x = -1 next_y = -1 + tail = [] + tail_length = 0 + +def safe_move(direction): + global last_move + global tail + global tail_length + + # Prevent immediate reversal only if some other move exists + if last_move != None and direction == OPPOSITE[last_move]: + if any_other_move_available(): + return False + + if not can_move(direction): + return False + + moved = move(direction) + if moved: + last_move = direction + + tail.insert(0, (get_pos_x(), get_pos_y())) + if len(tail) > tail_length: + tail.pop() + + return True + + return False + + +def flood_can_reach_tail(head, simulated_tail): + # Breadth First Search - can head reach tail end if tail (except last) is blocked? + world = get_world_size() + + if len(simulated_tail) == 0: + return True + + blocked = set(simulated_tail[:-1]) + target = simulated_tail[-1] + + queue = [head] + visited = {head} + + while queue: + x, y = queue.pop(0) + if (x, y) == target: + return True + + for dx, dy in [(0, 1), (1, 0), (0, -1), (-1, 0)]: + nx = x + dx + ny = y + dy + if 0 <= nx < world and 0 <= ny < world: + pos = (nx, ny) + if (pos not in blocked) and (pos not in visited): + visited.add(pos) + queue.append(pos) + + return False + + +def move_one_step_towards(tx, ty): + # A tiny greedy stepper to head toward a target (helps get unstuck) + cx = get_pos_x() + cy = get_pos_y() + dx = tx - cx + dy = ty - cy + + preferred = [] + + if abs(dx) >= abs(dy): + if dx > 0: + preferred.append(East) + elif dx < 0: + preferred.append(West) + if dy > 0: + preferred.append(North) + elif dy < 0: + preferred.append(South) + else: + if dy > 0: + preferred.append(North) + elif dy < 0: + preferred.append(South) + if dx > 0: + preferred.append(East) + elif dx < 0: + preferred.append(West) + + for d in preferred + [North, East, South, West]: + if safe_move(d): + return True + + return False + def clear_grid(): - columns_per_drone = get_world_size() / max_drones() - for x in range(columns_per_drone): - for y in range(get_world_size()): + columns_per_drone = get_world_size() // max_drones() + for _ in range(columns_per_drone): + for _ in range(get_world_size()): till() safe_move(North) safe_move(East) def move_to_coords_avoiding_tail(x, y): - global last_move - if get_pos_x() == x and get_pos_y() == y: return while True: - current_x = get_pos_x() - current_y = get_pos_y() + cx = get_pos_x() + cy = get_pos_y() - dx = x - current_x - dy = y - current_y + dx = x - cx + dy = y - cy moved = False + preferred = [] if abs(dx) >= abs(dy): if dx > 0: - moved = safe_move(East) + preferred.append(East) elif dx < 0: - moved = safe_move(West) + preferred.append(West) + + if dy > 0: + preferred.append(North) + elif dy < 0: + preferred.append(South) else: if dy > 0: - moved = safe_move(North) + preferred.append(North) elif dy < 0: - moved = safe_move(South) + preferred.append(South) - # Fallbacks - if not moved: - for d in [North, East, South, West]: - if safe_move(d): - moved = True - break + if dx > 0: + preferred.append(East) + elif dx < 0: + preferred.append(West) + + # Try the preferred direction, then any direction + for d in preferred + [North, East, South, West]: + if safe_move(d): + moved = True + break - # We're completely stuck so just claim the rewards if not moved: + # If we still have a tail, see if we can reach the tail end. + if tail_length > 1 and len(tail) > 0: + head = (get_pos_x(), get_pos_y()) + can_escape = flood_can_reach_tail(head, tail) + + if can_escape: + # We're not truly stuck, our greedy choices boxed us in. + # Unstick by walking toward the tail end a few steps. + tx, ty = tail[-1] + for _ in range(10): + if move_one_step_towards(tx, ty): + break + continue + + # Truly stuck sp let's harvest and restart change_hat(Hats.Straw_Hat) reset() change_hat(Hats.Dinosaur_Hat) @@ -148,15 +257,53 @@ def move_to_coords_avoiding_tail(x, y): if get_pos_x() == x and get_pos_y() == y: return +def do_dumb(): + global tail_length + + # 32x32 grid + world_size = get_world_size() + moving_up = True + + move(North) + + for x in range(world_size): + for y in range(world_size - 2): + if get_entity_type() == Entities.Apple: + tail_length = tail_length + 1 + + if moving_up: + move(North) + if get_entity_type() == Entities.Apple: + tail_length = tail_length + 1 + else: + move(South) + if get_entity_type() == Entities.Apple: + tail_length = tail_length + 1 + move(East) + if get_entity_type() == Entities.Apple: + tail_length = tail_length + 1 + moving_up = not moving_up + + # now move back to 0,0 + move(South) + if get_entity_type() == Entities.Apple: + tail_length = tail_length + 1 + for x in range(world_size): + move(West) + if get_entity_type() == Entities.Apple: + tail_length = tail_length + 1 + + if tail_length > 900: + harvest() def process(): - global next_x - global next_y + global tail_length + global dumb_mode reset() world_size = get_world_size() - columns_per_drone = world_size / max_drones() + columns_per_drone = world_size // max_drones() i = 0 while i < world_size: @@ -167,8 +314,17 @@ def process(): clear_grid() change_hat(Hats.Dinosaur_Hat) + tail_length = 1 + + if dumb_mode: + while True: + do_dumb() + else: + while True: + next_x, next_y = measure() - while True: - next_x, next_y = measure() - safe_move(North) - move_to_coords_avoiding_tail(next_x, next_y) \ No newline at end of file + # Apple is eaten on the next move, tail grows by 1 + tail_length = tail_length + 1 + + safe_move(North) + move_to_coords_avoiding_tail(next_x, next_y) \ No newline at end of file