From f13ce0450b1457abb062f61d2a3bf2d3925a67e8 Mon Sep 17 00:00:00 2001 From: Yi-Ting Shih Date: Mon, 10 Nov 2025 03:07:40 +0800 Subject: [PATCH] Chore: checkpoint --- __builtins__.py | 1307 +++++++++++++++++++++++++++++++++++++++++++++++ cactus.py | 103 ++++ farm24.py | 37 ++ farm32.py | 44 ++ hats.py | 15 + leaderboard.py | 1 + maze.py | 54 ++ mix.py | 39 ++ pumpkin.py | 38 ++ save.json | 1 + snake.py | 135 +++++ solve.py | 16 + sunflower.py | 133 +++++ utils.py | 91 ++++ 14 files changed, 2014 insertions(+) create mode 100644 __builtins__.py create mode 100644 cactus.py create mode 100644 farm24.py create mode 100644 farm32.py create mode 100644 hats.py create mode 100644 leaderboard.py create mode 100644 maze.py create mode 100644 mix.py create mode 100644 pumpkin.py create mode 100644 save.json create mode 100644 snake.py create mode 100644 solve.py create mode 100644 sunflower.py create mode 100644 utils.py diff --git a/__builtins__.py b/__builtins__.py new file mode 100644 index 0000000..e603140 --- /dev/null +++ b/__builtins__.py @@ -0,0 +1,1307 @@ +# This file gives Python type definitions to TFWR builtins to allow editing code with Python editors. +# Note that the games language is not Python and these definitions are only an approximation. +# Contributed by @Noon, @KlingonDragon, @dieckie and @Flekay on the TFWR Discord server. + +from typing import Any, Optional, Iterable, Tuple, Dict +from builtins import type, bool, int, float, str, list, set, dict + + +# ------------------------------------------------------------------------------- +class Item: + """A member of the Items Class""" + + +class Items: + Bone: Item + """The bones of an ancient creature.""" + + Cactus: Item + """Obtained by harvesting sorted cacti.""" + + Carrot: Item + """Obtained by harvesting carrots.""" + + Fertilizer: Item + """Call `use_item(Items.Fertilizer)` to instantly remove 2s from the plants remaining grow time.""" + + Gold: Item + """Found in treasure chests in mazes.""" + + Hay: Item + """Obtained by cutting grass.""" + + Piggy: Item + """This item has been removed from the game but remains as a nostalgia trophy.""" + + Power: Item + """Obtained by harvesting sunflowers. The drone automatically uses this to move twice as fast.""" + + Pumpkin: Item + """Obtained by harvesting pumpkins.""" + + Water: Item + """Used to water the ground by calling `use_item(Items.Water)`.""" + + Weird_Substance: Item + """Call `use_item(Items.Weird_Substance)` on a bush to grow a maze, or on other plants to toggle their infection status.""" + + Wood: Item + """Obtained from bushes and trees.""" + + +# ------------------------------------------------------------------------------- +class Hat: + """A member of the Hats class""" + +class Hats: + Brown_Hat: Hat + """A brown hat.""" + + Cactus_Hat: Hat + """A hat shaped like a cactus.""" + + Carrot_Hat: Hat + """A hat shaped like a carrot.""" + + Dinosaur_Hat: Hat + """Equip it to start the dinosaur game.""" + + Gold_Hat: Hat + """A golden hat.""" + + Gold_Trophy_Hat: Hat + """A golden trophy hat.""" + + Golden_Cactus_Hat: Hat + """A golden hat shaped like a cactus.""" + + Golden_Carrot_Hat: Hat + """A golden hat shaped like a carrot.""" + + Golden_Gold_Hat: Hat + """A golden version of the gold hat.""" + + Golden_Pumpkin_Hat: Hat + """A golden hat shaped like a pumpkin.""" + + Golden_Sunflower_Hat: Hat + """A golden hat shaped like a sunflower.""" + + Golden_Tree_Hat: Hat + """A golden hat shaped like a tree.""" + + Gray_Hat: Hat + """A gray hat.""" + + Green_Hat: Hat + """A green hat.""" + + Pumpkin_Hat: Hat + """A hat shaped like a pumpkin.""" + + Purple_Hat: Hat + """A purple hat.""" + + Silver_Trophy_Hat: Hat + """A silver trophy hat.""" + + Straw_Hat: Hat + """The default hat.""" + + Sunflower_Hat: Hat + """A hat shaped like a sunflower.""" + + The_Farmers_Remains: Hat + """The remains of the farmer.""" + + Top_Hat: Hat + """A fancy top hat.""" + + Traffic_Cone: Hat + """A traffic cone hat.""" + + Traffic_Cone_Stack: Hat + """A stack of traffic cones as a hat.""" + + Tree_Hat: Hat + """A hat shaped like a tree.""" + + Wizard_Hat: Hat + """A magical wizard hat.""" + + Wood_Trophy_Hat: Hat + """A wooden trophy hat.""" + +# ------------------------------------------------------------------------------- +class Leaderboard: + """A member of the Leaderboards class""" + +class Leaderboards: + Cactus: Leaderboard + """Farm 33554432 cacti with multiple drones.""" + + Cactus_Single: Leaderboard + """Farm 131072 cacti with a single drone on an 8x8 farm.""" + + Carrots: Leaderboard + """Farm 2000000000 carrots with multiple drones.""" + + Carrots_Single: Leaderboard + """Farm 100000000 carrots with a single drone on an 8x8 farm.""" + + Dinosaur: Leaderboard + """Farm 33488928 bones with multiple drones.""" + + Fastest_Reset: Leaderboard + """The most prestigious category. Completely automate the game from a single farm plot to unlocking the leaderboards again.""" + + Hay: Leaderboard + """Farm 2 000 000 hay with multiple drones.""" + + Hay_Single: Leaderboard + """Farm 10 000 000 hay with a single drone on an 8x8 farm.""" + + Maze: Leaderboard + """Farm 9 863 168 gold with multiple drones.""" + + Maze_Single: Leaderboard + """Farm 616 448 gold with a single drone on an 8x8 farm.""" + + Pumpkins: Leaderboard + """Farm 2 000 000 pumpkins with multiple drones.""" + + Pumpkins_Single: Leaderboard + """Farm 1 000 000 pumpkins with a single drone on an 8x8 farm.""" + + Sunflowers: Leaderboard + """Farm 10 000 power with multiple drones.""" + + Sunflowers_Single: Leaderboard + """Farm 10 000 power with a single drone on an 8x8 farm.""" + + Wood: Leaderboard + """Farm 10 000 000 000 wood with multiple drones.""" + + Wood_Single: Leaderboard + """Farm 500 000 000 wood with a single drone on an 8x8 farm.""" + +# ------------------------------------------------------------------------------- +class Entity: + """A member of the Entities Class""" + +class Entities: + Apple: Entity + """Dinosaurs love them apparently.""" + + Bush: Entity + """ + A small bush that drops `Items.Wood`. + + Average seconds to grow: 4 + Grows on: grassland or soil + """ + + Cactus: Entity + """ + Cacti come in 10 different sizes (0-9). When harvested, adjacent cacti that are in sorted order will also be harvested recursively. + You receive cactus equal to the number of harvested cacti squared. + + Average seconds to grow: 1 + Grows on: soil + """ + + Carrot: Entity + """ + Carrots! + + Average seconds to grow: 6 + Grows on: soil + """ + + Dead_Pumpkin: Entity + """ + One in five pumpkins dies when it grows up, leaving behind a dead pumpkin. Dead pumpkins are useless and disappear when something new is planted. + `can_harvest()` always returns `False` on dead pumpkins. + """ + + Dinosaur: Entity + """ + A piece of the tail of the dinosaur hat. When wearing the dinosaur hat, the tail is dragged behind the drone filling previously moved tiles. + + Average seconds to grow: 0.2 + Grows on: grassland or soil + """ + + Grass: Entity + """ + Grows automatically on grassland. Harvest it to obtain `Items.Hay`. + + Average seconds to grow: 0.5 + Grows on: grassland or soil + """ + + Hedge: Entity + """Part of the maze.""" + + Pumpkin: Entity + """ + Pumpkins grow together when they are next to other fully grown pumpkins. About 1 in 5 pumpkins dies when it grows up. + When you harvest a pumpkin you get `Items.Pumpkin` equal to the number of pumpkins in the mega pumpkin cubed. + + Average seconds to grow: 2 + Grows on: soil + """ + + Sunflower: Entity + """ + Sunflowers collect the power from the sun. Harvesting them will give you `Items.Power`. + If you harvest a sunflower with the maximum number of petals (and there are at least 10 sunflowers) you get 5x bonus power. + + Average seconds to grow: 5 + Grows on: soil + """ + + Treasure: Entity + """A treasure that contains gold equal to the side length of the maze in which it is hidden. It can be harvested like a plant.""" + + Tree: Entity + """ + Trees drop more wood than bushes. They take longer to grow if other trees grow next to them. + + Average seconds to grow: 7 + Grows on: grassland or soil + """ + + +# ------------------------------------------------------------------------------- +class Ground: + """A member of the Grounds Class""" + + +class Grounds: + Grassland: Ground + """The default ground. Grass will automatically grow on it.""" + + Soil: Ground + """Calling `till()` turns the ground into this. Calling `till()` again changes it back to grassland.""" + + +# ------------------------------------------------------------------------------- +class Unlock: + """A member of the Unlocks Class""" + + +class Unlocks: + Auto_Unlock: Unlock + """Automatically unlock things.""" + + Cactus: Unlock + """ + Unlock: Cactus! + Upgrade: Increases the yield and cost of cactus. + """ + + Carrots: Unlock + """ + Unlock: Till the soil and plant carrots. + Upgrade: Increases the yield and cost of carrots. + """ + + Costs: Unlock + """Allows access to the cost of things.""" + + Debug: Unlock + """Tools to help with debugging programs.""" + + Debug_2: Unlock + """Functions to temporarily slow down the execution and make the grid smaller.""" + + Dictionaries: Unlock + """Get access to dictionaries and sets.""" + + Dinosaurs: Unlock + """ + Unlock: Majestic ancient creatures. + Upgrade: Increases the yield and cost of dinosaurs. + """ + + Expand: Unlock + """ + Unlock: Expands the farm land and unlocks movement. + Upgrade: Expands the farm. This also clears the farm. + """ + + Fertilizer: Unlock + """Reduces the remaining growing time of the plant under the drone by 2 seconds.""" + + Functions: Unlock + """Define your own functions.""" + + Grass: Unlock + """Increases the yield of grass.""" + + Hats: Unlock + """Unlocks new hat colors for your drone.""" + + Import: Unlock + """Import code from other files.""" + + Leaderboard: Unlock + """Join the leaderboard for the fastest reset time.""" + + Lists: Unlock + """Use lists to store lots of values.""" + + Loops: Unlock + """Unlocks a simple while loop.""" + + Mazes: Unlock + """ + Unlock: A maze with a treasure in the middle. + Upgrade: Increases the gold in treasure chests. + """ + + Megafarm: Unlock + """Unlocks multiple drones and drone management functions.""" + + Operators: Unlock + """Arithmetic, comparison and logic operators.""" + + Plant: Unlock + """Unlocks planting.""" + + Polyculture: Unlock + """Use companion planting to increase the yield.""" + + Pumpkins: Unlock + """ + Unlock: Pumpkins! + Upgrade: Increases the yield and cost of pumpkins. + """ + + Senses: Unlock + """The drone can see what's under it and where it is.""" + + Simulation: Unlock + """Unlocks simulation functions for testing and optimization.""" + + Speed: Unlock + """Increases the speed of the drone.""" + + Sunflowers: Unlock + """ + Unlock: Sunflowers and Power. + Upgrade: Increases the power gained from sunflowers. + """ + + The_Farmers_Remains: Unlock + """Unlocks the special hat 'The Farmers Remains'.""" + + Timing: Unlock + """Functions to help measure performance.""" + + Top_Hat: Unlock + """Unlocks the fancy Top Hat.""" + + Trees: Unlock + """ + Unlock: Unlocks trees. + Upgrade: Increases the yield of bushes and trees. + """ + + Utilities: Unlock + """Unlocks the `min()`, `max()` and `abs()` functions.""" + + Variables: Unlock + """Assign values to variables.""" + + Watering: Unlock + """Water the plants to make them grow faster.""" + + +# ------------------------------------------------------------------------------- +class Direction: + """ + A direction, e.g. North. + """ + + +North = Direction() +""" +The direction north, i.e. up. +""" + +East = Direction() +""" +The direction east, i.e. right. +""" +South = Direction() +""" +The direction south, i.e. down. +""" +West = Direction() +""" +The direction west, i.e. left. +""" + + +# ------------------------------------------------------------------------------- +def harvest() -> bool: + """ + Harvests the entity under the drone. + If you harvest an entity that can't be harvested, it will be destroyed. + + returns `True` if an entity was removed, `False` otherwise. + + takes `200` ticks to execute if an entity was removed, `1` tick otherwise. + + example usage: + ``` + harvest() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def can_harvest() -> bool: + """ + Used to find out if plants are fully grown. + + returns `True` if there is an entity under the drone that is ready to be harvested, `False` otherwise. + + takes `1` tick to execute. + + example usage: + ``` + if can_harvest(): + harvest() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def plant(entity: Entity) -> bool: + """ + Spends the cost of the specified `entity` and plants it under the drone. + It fails if you can't afford the plant, the ground type is wrong or there's already a plant there. + + returns `True` if it succeeded, `False` otherwise. + + takes `200` ticks to execute if it succeeded, `1` tick otherwise. + + example usage: + ``` + plant(Entities.Bush) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def move(direction: Direction) -> bool: + """ + Moves the drone into the specified `direction` by one tile. + If the drone moves over the edge of the farm it wraps back to the other side of the farm. + + - `East ` = right + - `West ` = left + - `North` = up + - `South` = down + + returns `True` if the drone has moved, `False` otherwise. + + takes `200` ticks to execute if the drone has moved, `1` tick otherwise. + + example usage: + ``` + move(North) + ``` + """ + ... + +# ------------------------------------------------------------------------------- +def can_move(direction: Direction) -> bool: + """ + Checks if the drone can move in the specified `direction`. + + returns `True` if the drone can move, `False` otherwise. + + takes `1` tick to execute. + + example usage: + ``` + if can_move(North): + move(North) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def swap(direction: Direction) -> bool: + """ + Swaps the entity under the drone with the entity next to the drone in the specified `direction`. + - Doesn't work on all entities. + - Also works if one (or both) of the entities are `None`. + + returns `True` if it succeeded, `False` otherwise. + + takes `200` ticks to execute on success, `1` tick otherwise. + + example usage: + ``` + swap(North) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def till() -> None: + """ + Tills the ground under the drone into soil. If it's already soil it will change the ground back to grassland. + + returns `None` + + takes `200` ticks to execute. + + example usage: + ``` + till() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_pos_x() -> int: + """ + Gets the current x position of the drone. + The x position starts at `0` in the `West` and increases in the `East` direction. + + returns a number representing the current x coordinate of the drone. + + takes `1` tick to execute. + + example usage: + ``` + x, y = get_pos_x(), get_pos_y() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_pos_y() -> int: + """ + Gets the current y position of the drone. + The y position starts at `0` in the `South` and increases in the `North` direction. + + returns a number representing the current y coordinate of the drone. + + takes `1` tick to execute. + + example usage: + ``` + x, y = get_pos_x(), get_pos_y() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_world_size() -> int: + """ + Get the current size of the farm. + + returns the side length of the grid in the north to south direction. + + takes `1` tick to execute. + + example usage: + ``` + for i in range(get_world_size()): + move(North) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_entity_type() -> Entity | None: + """ + Find out what kind of entity is under the drone. + + returns `None` if the tile is empty, otherwise returns the type of the entity under the drone. + + takes `1` tick to execute. + + example usage: + ``` + if get_entity_type() == Entities.Grass: + harvest() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_ground_type() -> Ground: + """ + Find out what kind of ground is under the drone. + + returns the type of the ground under the drone. + + takes `1` tick to execute. + + example usage: + ``` + if get_ground_type() != Grounds.Soil: + till() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_time() -> float: + """ + Get the current game time. + + returns the time in seconds since the start of the game. + + takes `1` tick to execute. + + example usage: + ``` + start = get_time() + + do_something() + + time_passed = get_time() - start + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_tick_count() -> int: + """ + Used to measure the number of ticks performed. + + returns the number of ticks performed since the start of execution. + + takes `0` tick to execute. + + example usage: + ``` + do_something() + + print(get_tick_count()) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def use_item(item: Item, n: int = 1) -> bool: + """ + Attempts to use the specified `item` `n` times. Can only be used with some items including `Items.Water`, `Items.Fertilizer` and `Items.Weird_Substance`. + + returns `True` if an item was used, `False` if the item can't be used or you don't have enough. + + takes `200` ticks to execute if it succeeded, `1` tick otherwise. + + example usage: + ``` + if use_item(Items.Fertilizer): + print("Fertilizer used successfully") + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_water() -> float: + """ + Get the current water level under the drone. + + returns the water level under the drone as a number between `0` and `1`. + + takes `1` tick to execute. + + example usage: + ``` + if get_water() < 0.5: + use_item(Items.Water) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def do_a_flip() -> None: + """ + Makes the drone do a flip! This action is not affected by speed upgrades. + + returns `None` + + takes 1s to execute. + + example usage: + ``` + while True: + do_a_flip() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def pet_the_piggy() -> None: + """ + Pets the piggy! This action is not affected by speed upgrades. + + returns `None` + + takes 1s to execute. + + example usage: + ``` + while True: + pet_the_piggy() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def print(*something: Any) -> None: + """ + Prints `something` into the air above the drone using smoke. This action is not affected by speed upgrades. + Multiple values can be printed at once. + + returns `None` + + takes 1s to execute. + + example usage: + ``` + print('ground:', get_ground_type()) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def set_execution_speed(speed: float) -> None: + """ + Limits the speed at which the program is executed to better see what's happening. + + - A `speed` of `1` is the speed the drone has without any speed upgrades. + - A `speed` of `10` makes the code execute `10` times faster and corresponds to the speed of the drone after `9` speed upgrades. + - A `speed` of `0.5` makes the code execute at half of the speed without speed upgrades. This can be useful to see what the code is doing. + + If `speed` is faster than the execution can currently go it will just go at max speed. + + If `speed` is `0` or negative, the speed is changed back to max speed. + The effect will also stop when the execution stops. + + returns `None` + + takes `200` ticks to execute. + + example usage: + ``` + set_execution_speed(1) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def set_world_size(size: float) -> None: + """ + Limits the size of the farm to better see what's happening. + Also clears the farm and resets the drone position. + - Sets the farm to a `size` x `size` grid. + - The smallest `size` possible is `3`. + - A `size` smaller than `3` will change the grid back to its full size. + - The effect will also stop when the execution stops. + + returns `None` + + takes `200` ticks to execute. + + example usage: + ``` + set_world_size(5) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def num_items(item: Item) -> float: + """ + Find out how much of `item` you currently have. + + returns the number of `item` currently in your inventory. + + takes `1` tick to execute. + + example usage: + ``` + if num_items(Items.Fertilizer) > 0: + use_item(Items.Fertilizer) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_cost(thing: Entity | Item | Unlock, level: Optional[int] = None) -> Dict[Item, float] | None: + """ + Gets the cost of a `thing` + + If `thing` is an entity: get the cost of planting it. + If `thing` is an unlock: get the cost of unlocking it at the specified level. + + - returns a dictionary with items as keys and numbers as values. Each item is mapped to how much of it is needed. + - returns `None` for unlocks that are already unlocked (when no level specified). + - The optional `level` parameter specifies the upgrade level for unlocks. + + takes `1` tick to execute. + + example usage: + ``` + cost = get_cost(Unlocks.Carrots) + for item in cost: + if num_items(item) < cost[item]: + print('not enough items to unlock carrots') + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def clear() -> None: + """ + Removes everything from the farm, moves the drone back to position `(0,0)` and changes the hat back to the default. + + returns `None` + + takes `200` ticks to execute. + + example usage: + ``` + clear() + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def get_companion() -> Tuple[Entity, Tuple[int, int]] | None: + """ + Get the companion preference of the plant under the drone. + + returns a tuple of the form `(companion_type, (companion_x_position, companion_y_position))` or `None` if there is no companion. + + takes `1` tick to execute. + + example usage: + ``` + companion = get_companion() + if companion != None: + plant_type, (x, y) = companion + print("Companion:", plant_type, "at", x, ",", y) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def unlock(unlock: Unlock) -> bool: + """ + Has exactly the same effect as clicking the button corresponding to `unlock` in the research tree. + + returns `True` if the unlock was successful, `False` otherwise. + + takes `200` ticks to execute if it succeeded, `1` tick otherwise. + + example usage: + ``` + unlock(Unlocks.Carrots) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def num_unlocked(thing: Unlock | Entity | Ground | Item) -> int: + """ + Used to check if an unlock, entity, ground, item or hat is already unlocked. + + returns `1` plus the number of times `thing` has been upgraded if `thing` is upgradable. Otherwise returns `1` if `thing` is unlocked, `0` otherwise. + + takes `1` tick to execute. + + example usage: + ``` + if num_unlocked(Unlocks.Carrots) > 0: + plant(Entities.Carrot) + else: + print("Carrots not unlocked yet") + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def measure(direction: Optional[Direction] = None) -> float | Tuple[int, int] | None: + """ + Can measure some values on some entities. The effect of this depends on the entity. + + overloads: + `measure()`: measures the entity under the drone. + `measure(direction)`: measures the neighboring entity in the `direction` of the drone. + + Sunflower: returns the number of petals. + Maze: returns the position of the current treasure from anywhere in the maze. + Cactus: returns the size. + Dinosaur: returns the number corresponding to the type. + All other entities: returns `None`. + + takes `1` tick to execute. + + example usage: + ``` + num_petals = measure() + treasure_pos = measure() # Works anywhere in maze + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def leaderboard_run(leaderboard: Leaderboard, file_name: str, speedup: float) -> None: + """ + Starts a timed run for the `leaderboard` using the specified `file_name` as a starting point. + `speedup` sets the starting speedup. + + returns `None` + + takes `200` ticks to execute. + + example usage: + ``` + leaderboard_run(Leaderboards.Fastest_Reset, "full_run", 256) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def simulate(filename: str, sim_unlocks: Dict[Unlocks, float] | Iterable[Unlocks] | type[Unlocks], sim_items: Dict[Item, float], sim_globals: Dict[str, Any], seed: float, speedup: float) -> float: + """ + Starts a simulation for the leaderboard using the specified `file_name` as a starting point. + + `sim_unlocks`: A sequence containing the starting unlocks. + + `sim_items`: A dict mapping items to amounts. The simulation starts with these items. + + `sim_globals`: A dict mapping variable names to values. The simulation starts with these variables in the global scope. + + `seed`: The random seed of the simulation. Must be a positive integer. + + `speedup`: The starting speedup. + + returns the time it took to run the simulation. + + takes `200` ticks to execute. + + example usage: + + ``` + filename = "f1" + sim_unlocks = Unlocks + sim_items = {Items.Carrot : 10000, Items.Hay : 50} + sim_globals = {"a" : 13} + seed = 0 + speedup = 64 + run_time = simulate(filename, sim_unlocks, sim_items, sim_globals, seed, speedup) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def quick_print(*something: Any) -> None: + """ + Prints a value just like `print()` but it doesn't stop to write it into the air so it can only be found on the output page. + + returns `None` + + takes `0` ticks to execute. + + example usage: + ``` + quick_print('hi mom') + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def random() -> float: + """ + Samples a random number between 0 (inclusive) and 1 (exclusive). + + returns the random number. + + takes `1` ticks to execute. + + example usage: + ``` + def random_elem(list): + index = random() * len(list) // 1 + return list[index] + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def len(obj): + """ + Returns the number of items in an object. + + returns the length of the object. + + takes `1` tick to execute. + + example usage: + ``` + my_list = [1, 2, 3] + length = len(my_list) # 3 + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def range(start, stop=None, step=1): + """ + Returns a sequence of numbers from start (inclusive) to stop (exclusive). + + returns a range object. + + takes `1` tick to execute. + + example usage: + ``` + for i in range(5): + print(i) # 0, 1, 2, 3, 4 + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def str(obj: Any) -> str: + """ + Converts an object to its string representation. + + returns the string representation of the object. + + takes `1` tick to execute. + + example usage: + ``` + string = str(1000) + print(string) # prints "1000" + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def min(*args: Any) -> Any: + """ + Gets the minimum of a sequence of elements or several passed arguments. + Can be used on numbers and strings. + + `min(a,b,c)`: Returns the minimum of `a`, `b` and `c`. + `min(sequence)`: Returns the minimum of all values in a sequence. + + returns the minimum value from the arguments. + + takes #comparisons ticks to execute. + + example usage: + ``` + smallest = min(1, 5, 3, 2) + smallest_from_list = min([3, 6, 34, 16]) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def max(*args: Any) -> Any: + """ + Gets the maximum of a sequence of elements or several passed arguments. + Can be used on numbers and strings. + + `max(a,b,c)`: Returns the maximum of `a`, `b` and `c`. + `max(sequence)`: Returns the maximum of all values in a sequence. + + returns the maximum value from the arguments. + + takes #comparisons ticks to execute. + + example usage: + ``` + largest = max(1, 5, 3, 2) + largest_from_list = max([3, 6, 34, 16]) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def abs(x: float) -> float: + """ + Returns the absolute value of a number. + + returns the absolute value of x. + + takes `1` tick to execute. + + example usage: + ``` + positive = abs(-5) + print(positive) # prints 5 + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def change_hat(hat: Hat) -> None: + """ + Changes the hat of the drone to the specified `hat`. + + returns `None` + + takes `200` ticks to execute. + + example usage: + ``` + change_hat(Hats.Dinosaur_Hat) + ``` + ... + """ + ... + + +# ------------------------------------------------------------------------------- +def spawn_drone(function: str) -> Any: + """ + Spawns a new drone in the same position as the drone that ran the `spawn_drone(function)` command. The new drone then begins executing the specified function. After it is done, it will disappear automatically. + + returns the handle of the new drone or `None` if all drones are already spawned. + + takes `200` ticks to execute if a drone was spawned, `1` otherwise. + + example: + ``` + def harvest_column(): + for _ in range(get_world_size()): + harvest() + move(North) + + while True: + if spawn_drone(harvest_column): + move(East) + ``` + """ + ... + + +# ------------------------------------------------------------------------------- +def wait_for(drone: Any) -> Any: + """ + Waits until the given drone terminates. + + returns the return value of the function that the drone was running. + + takes `1` tick to execute if the awaited drone is already done. + + example: + ``` + def get_entity_type_in_direction(dir): + move(dir) + return get_entity_type() + + def zero_arg_wrapper(): + return get_entity_type_in_direction(North) + handle = spawn_drone(zero_arg_wrapper) + print(wait_for(handle)) + ``` + """ + ... + +# ------------------------------------------------------------------------------- +def has_finished(drone: Any) -> Any: + """ + Checks if the given drone has finished. + + returns `True` if the drone has finished, `False` otherwise. + + takes `1` tick to execute. + + example: + ``` + drone = spawn_drone(function) + while not has_finished(drone): + do_something_else() + result = wait_for(drone) + ``` + """ + ... + +# ------------------------------------------------------------------------------- +def max_drones() -> int: + """ + returns the maximum number of drones that you can have in the farm. + + takes `1` tick to execute. + + example: + ``` + while num_drones() < max_drones(): + spawn_drone("some_file_name") + move(East) + ``` + """ + ... + +# ------------------------------------------------------------------------------- +def num_drones() -> int: + """ + returns the number of drones currently in the farm. + + takes `1` tick to execute. + + example: + ``` + while num_drones() < max_drones(): + spawn_drone("some_file_name") + move(East) + ``` + """ + ... diff --git a/cactus.py b/cactus.py new file mode 100644 index 0000000..60481b5 --- /dev/null +++ b/cactus.py @@ -0,0 +1,103 @@ +import utils, solve + +def grow(xl, xr, yl, yr): + def init(): + def fillx(x): + def ret(): + for y in range(yl, yr): + utils.mv(x, y) + utils.soil() + utils.water() + utils.replant(Entities.Cactus) + return ret + + drowns = list() + for x in range(xl+1, xr): + drown = None + while drown == None: + drown = spawn_drone(fillx(x)) + drowns.append(drown) + fillx(xl)() + for drown in drowns: + wait_for(drown) + + def run(): + def sortx(x): + def ret(): + l, r = yl, yr-1 + while l < r: + for i in range(l, r): + utils.mv(x, i) + cur, nxt = utils.meas(), utils.meas(North) + if nxt < cur: + swap(North) + r -= 1 + for i in range(r, l, -1): + utils.mv(x, i) + cur, nxt = utils.meas(), utils.meas(South) + if nxt > cur: + swap(South) + l += 1 + return ret + + drowns = list() + for x in range(xl+1, xr): + drown = None + while drown == None: + drown = spawn_drone(sortx(x)) + drowns.append(drown) + sortx(xl)() + for drown in drowns: + wait_for(drown) + + def sorty(y): + def ret(): + l, r = xl, xr-1 + while l < r: + for i in range(l, r): + utils.mv(i, y) + cur, nxt = utils.meas(), utils.meas(East) + if nxt < cur: + swap(East) + r -= 1 + for i in range(r, l, -1): + utils.mv(i, y) + cur, nxt = utils.meas(), utils.meas(West) + if nxt > cur: + swap(West) + l += 1 + return ret + + drowns = list() + for y in range(yl+1, yr): + drown = None + while drown == None: + drown = spawn_drone(sorty(y)) + drowns.append(drown) + sorty(yl)() + for drown in drowns: + wait_for(drown) + + utils.harv() + + init() + + return (init, run) + +def check(): + def init(): + pass + + def run(): + if num_items(Items.Cactus) >= 33554432: + return True + return (init, run) + +if __name__ == '__main__': + set_world_size(32) + clear() + + solve.run([ + grow.cactus(0, 32, 0, 32), + check(), + ])() diff --git a/farm24.py b/farm24.py new file mode 100644 index 0000000..7e37cc1 --- /dev/null +++ b/farm24.py @@ -0,0 +1,37 @@ +import solve, utils +import sunflower, mix, pumpkin, cactus, maze + +base24 = [ + sunflower.growbase(0, 8, 0, 2), + sunflower.grow(0, 8, 2, 8), +] + +mixs24 = [ + [mix.grow(0, 4, 8, 16)], + [mix.grow(4, 8, 8, 16)], + [mix.grow(0, 4, 16, 24)], + [mix.grow(4, 8, 16, 24)], + + [pumpkin.grow(8, 16, 8)], + [pumpkin.grow(16, 8, 8)], + + [cactus.grow( 8, 16, 8, 16)], + [cactus.grow(16, 24, 16, 24)], +] + +mazes24 = [ + [maze.grow( 8, 0, 8)], + [maze.grow(16, 0, 8)], +] + +def farm24(): + set_world_size(24) + clear() + + for maze in mazes24: + utils.spawn(solve.run(maze, 4000)) + for mix in mixs24: + utils.spawn(solve.run(mix)) + solve.run(base24)() + +farm24() diff --git a/farm32.py b/farm32.py new file mode 100644 index 0000000..ec160ab --- /dev/null +++ b/farm32.py @@ -0,0 +1,44 @@ +import solve, grow, utils + +base32 = [ + grow.sunflower_base(0, 2, 24, 32), + grow.sunflower(2, 8, 24, 32), +] + +mixs32 = [ + [grow.three_mix(0, 4, 0, 8)], + [grow.three_mix(4, 8, 0, 8)], + [grow.three_mix(0, 4, 8, 16)], + [grow.three_mix(4, 8, 8, 16)], + [grow.three_mix(0, 4, 16, 24)], + [grow.three_mix(4, 8, 16, 24)], + + [grow.pumpkin( 8, 0, 8)], + [grow.pumpkin(16, 8, 8)], + [grow.pumpkin( 8, 16, 8)], + [grow.pumpkin(16, 24, 8)], + + [grow.cactus(16, 24, 0, 8)], + [grow.cactus( 8, 16, 8, 16)], + [grow.cactus(16, 24, 16, 24)], + [grow.cactus( 8, 16, 24, 32)], +] + +mazes32 = [ + [grow.maze(24, 0, 8)], + [grow.maze(24, 8, 8)], + [grow.maze(24, 16, 8)], + [grow.maze(24, 24, 8)], +] + +def farm32(): + set_world_size(32) + clear() + + for maze in mazes32: + utils.spawn(solve.run(maze, 4000)) + for mix in mixs32: + utils.spawn(solve.run(mix)) + solve.run(base32)() + +farm32() diff --git a/hats.py b/hats.py new file mode 100644 index 0000000..f015d2e --- /dev/null +++ b/hats.py @@ -0,0 +1,15 @@ +def poop(hat): + def ret(): + change_hat(hat) + while True: + do_a_flip() + return ret + +spawn_drone(poop(Hats.Gray_hat)) +spawn_drone(poop(Hats.Purple_hat)) +spawn_drone(poop(Hats.Green_hat)) +spawn_drone(poop(Hats.Brown_hat)) +spawn_drone(poop(Hats.Dinosaur_hat)) +change_hat(Hats.The_Farmers_Remains) +while True: + do_a_flip() diff --git a/leaderboard.py b/leaderboard.py new file mode 100644 index 0000000..5435cc7 --- /dev/null +++ b/leaderboard.py @@ -0,0 +1 @@ +leaderboard_run(Leaderboards.Dinosaur, "snake", 10000) diff --git a/maze.py b/maze.py new file mode 100644 index 0000000..678644e --- /dev/null +++ b/maze.py @@ -0,0 +1,54 @@ +import solve, utils +import sunflower + +d = [North, West, South, East] +def grow(xl, yl, n, repeat=1): + cd = 0 + cnt = 0 + substance = n * 2**(num_unlocked(Unlocks.Mazes) - 1) + + def init(): + global cnt + + cnt = 0 + utils.mv(xl+n/2, yl+n/2) + utils.grass() + plant(Entities.Bush) + + def run(): + global cd + global cnt + + if cnt == 0: + init() + use_item(Items.Weird_Substance, substance) + + typ = get_entity_type() + while typ != Entities.Treasure: + if typ != Entities.Hedge: + init() + use_item(Items.Weird_Substance, substance) + if can_move(d[(cd+1)%4]): + cd = (cd+1)%4 + if move(d[cd]): + typ = get_entity_type() + continue + else: + cd = (cd+3)%4 + + cnt += 1 + if cnt >= repeat: + harvest() + cnt = 0 + else: + use_item(Items.Weird_Substance, substance) + + return (init, run) + +if __name__ == '__main__': + set_world_size(32) + utils.spawn(solve.run([ + sunflower.growbase(0, 2, 0, 8), + sunflower.grow(2, 8, 0, 8), + ])) + solve.run([grow(0, 0, 32)])() diff --git a/mix.py b/mix.py new file mode 100644 index 0000000..6c6d2ca --- /dev/null +++ b/mix.py @@ -0,0 +1,39 @@ +import utils + +def grow(xl, xr, yl, yr): + def init(): + for x in range(xl, xr): + l, r, d = yl, yr, 1 + if x%2 == 1: + l, r, d = yr-1, yl-1, -1 + for y in range(l, r, d): + utils.mv(x, y) + typ = x%2 + y%2 + if typ == 0: + utils.grass() + if typ == 1: + utils.grass() + if typ == 2: + utils.soil() + + def run(): + for x in range(xl, xr): + l, r, d = yl, yr, 1 + if x%2 == 1: + l, r, d = yr-1, yl-1, -1 + for y in range(l, r, d): + utils.mv(x, y) + utils.water() + utils.harv() + typ = x%2 + y%2 + if typ == 0: + pass # weed + if typ == 1: + if get_entity_type() == Entities.Grass: + plant(Entities.Tree) + if typ == 2: + utils.replant(Entities.Carrot) + return (init, run) + +if __name__ == '__main__': + pass diff --git a/pumpkin.py b/pumpkin.py new file mode 100644 index 0000000..6571883 --- /dev/null +++ b/pumpkin.py @@ -0,0 +1,38 @@ +import utils + +def grow(xl, yl, n): + def init(): + for x in range(xl, xl+n): + l, r, d = yl, yl+n, 1 + if x%2 == 1: + l, r, d = yl+n-1, yl-1, -1 + for y in range(l, r, d): + utils.mv(x, y) + utils.soil() + + def run(): + check = list() + for x in range(xl, xl+n): + l, r, d = yl, yl+n, 1 + if x%2 == 1: + l, r, d = yl+n-1, yl-1, -1 + for y in range(l, r, d): + utils.mv(x, y) + utils.water() + utils.replant(Entities.Pumpkin) + check.append((x, y)) + + while len(check): + nxt = list() + for x, y in check: + utils.mv(x, y) + if not can_harvest(): + nxt.append((x, y)) + if get_entity_type() == Entities.Dead_Pumpkin: + plant(Entities.Pumpkin) + check = nxt + + utils.mv(xl, yl) + utils.harv() + + return (init, run) diff --git a/save.json b/save.json new file mode 100644 index 0000000..7c30161 --- /dev/null +++ b/save.json @@ -0,0 +1 @@ +{"items":{"serializeList":[{"name":"hay","nr":732862776.0},{"name":"wood","nr":4085470918.0},{"name":"carrot","nr":1111796064.0},{"name":"pumpkin","nr":109301095.0},{"name":"cactus","nr":371811694.0},{"name":"bone","nr":30887608.0},{"name":"weird_substance","nr":428014.0},{"name":"gold","nr":20484298.0},{"name":"water","nr":1232080.0},{"name":"fertilizer","nr":25358.0}]},"dockedFiles":[{"key":"cactus","value":"maze"},{"key":"farm24","value":"farm32"},{"key":"hats","value":"utils"},{"key":"leaderboard","value":"farm24"},{"key":"maze","value":"snake"},{"key":"pumpkin","value":"mix"},{"key":"sunflower","value":"pumpkin"},{"key":"utils","value":"solve"}],"minimizedFiles":["farm24","farm32","leaderboard"],"openFilePositions":[{"key":"cactus","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"farm24","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"farm32","value":{"x":-634.2324829101563,"y":2230.040283203125}},{"key":"hats","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"leaderboard","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"maze","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"mix","value":{"x":-1656.432861328125,"y":1936.912841796875}},{"key":"pumpkin","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"snake","value":{"x":-693.8130493164063,"y":1927.7490234375}},{"key":"solve","value":{"x":-2349.65087890625,"y":2051.2119140625}},{"key":"sunflower","value":{"x":825.1744995117188,"y":158.076904296875}},{"key":"utils","value":{"x":825.1744995117188,"y":158.076904296875}}],"openFileScrollPositions":[{"key":"cactus","value":1007.769775390625},{"key":"farm24","value":450.0},{"key":"farm32","value":149.98077392578126},{"key":"hats","value":0.0},{"key":"leaderboard","value":0.0},{"key":"maze","value":299.99945068359377},{"key":"mix","value":0.0},{"key":"pumpkin","value":-0.0008544921875},{"key":"snake","value":2418.223388671875},{"key":"solve","value":0.00030517578125},{"key":"sunflower","value":0.0},{"key":"utils","value":599.9998779296875}],"openFileSizes":[{"key":"cactus","value":{"x":0.0,"y":0.0}},{"key":"farm24","value":{"x":0.0,"y":0.0}},{"key":"farm32","value":{"x":0.0,"y":0.0}},{"key":"hats","value":{"x":0.0,"y":0.0}},{"key":"leaderboard","value":{"x":0.0,"y":0.0}},{"key":"maze","value":{"x":0.0,"y":0.0}},{"key":"mix","value":{"x":0.0,"y":0.0}},{"key":"pumpkin","value":{"x":0.0,"y":0.0}},{"key":"snake","value":{"x":0.0,"y":0.0}},{"key":"solve","value":{"x":0.0,"y":0.0}},{"key":"sunflower","value":{"x":0.0,"y":0.0}},{"key":"utils","value":{"x":0.0,"y":0.0}}],"openDocPages":[],"unlocks":["grass_10","soil","harvest","pass","do_a_flip","pet_the_piggy","grassland","hay","straw_hat","while","true","false","break","continue","loops","speed_5","can_harvest","if","else","elif","expand_9","move","north","south","east","west","for","range","get_world_size","wood","bush","entities","clear","plant","change_hat","gray_hat","purple_hat","green_hat","brown_hat","hats","traffic_cone","and","or","not","operators","carrots_10","carrot","till","can_trade","trade","items","carrot_seed","get_entity_type","get_ground_type","grounds","get_pos_x","get_pos_y","none","num_items","num_unlocked","senses","watering_9","water","use_item","get_water","trees_10","tree","tree_hat","sunflower_seed","sunflower","power","get_active_power","measure","sunflowers","pumpkins_10","pumpkin","pumpkin_seed","dead_pumpkin","carrot_hat","variables","functions","def","return","global","from","import","fertilizer_4","weird_substance","append","remove","pop","insert","len","list","lists","traffic_cone_stack","print","quick_print","unlocks","str","debug","pumpkin_hat","sunflower_hat","swap","cactus_seed","cactus_6","get_companion","polyculture_5","hedge","treasure","gold","can_move","mazes_6","dicts","sets","add","dict","set","dictionaries","get_cost","costs","min","max","abs","random","utilities","get_time","get_tick_count","timing","unlock","auto_unlock","wizard_hat","cactus_hat","gold_hat","megafarm_5","get_drone_id","num_drones","max_drones","wait_for","spawn_drone","has_finished","dinosaurs_6","dinosaur","egg","bone","dinosaur_hat","apple","set_execution_speed","set_world_size","debug_2","simulate","simulation","leaderboard_run","leaderboards","leaderboard","golden_cactus_hat","the_farmers_remains"],"version":3} \ No newline at end of file diff --git a/snake.py b/snake.py new file mode 100644 index 0000000..31cad25 --- /dev/null +++ b/snake.py @@ -0,0 +1,135 @@ +import solve, utils + +def grow(): + N = get_world_size() + apple = None + path = 0 + length = 0 + + def mv(x, y, d, irq=False): + global apple + global path + global length + + move(d) + path += 1 + if (x, y) == apple: + apple = measure() + length += 1 + return irq and path >= length + + def goto(tx, ty, irq=False): + if irq and path >= length: + return + + x, y = get_pos_x(), get_pos_y() + + for i in range(max(0, tx-x)): + x += 1 + if mv(x, y, East, irq): + return + for i in range(max(0, x-tx)): + x -= 1 + if mv(x, y, West, irq): + return + + for i in range(max(0, ty-y)): + y += 1 + if mv(x, y, North, irq): + return + for i in range(max(0, y-ty)): + y -= 1 + if mv(x, y, South, irq): + return + + + def init(): + global apple + global length + + change_hat(Hats.Gray_Hat) + utils.mv(0, 0) + change_hat(Hats.Dinosaur_Hat) + + apple = measure() + path = 0 + length = 1 + + def run(): + global apple + global path + + if apple == None or length == N*N: + init() + return + + path = 0 + for x in range(N): + if x%2 == 0: + goto(x, 1, True) + goto(x, N-1, True) + else: + goto(x, N-1, True) + goto(x, 1, True) + + x, y = apple + if within((x, y), (0, N-1, 1, N)): + goto(x, y) + + goto(N-1, 1) + goto(N-1, 0) + goto(0, 0) + + x, y = apple + + return (init, run) + +def growlong(): + N = get_world_size() + + def init(): + change_hat(Hats.Gray_Hat) + utils.mv(0, 0) + change_hat(Hats.Dinosaur_Hat) + + def run(): + for i in range(N): + if i%2 == 0: + if not utils.mv(i, 1): + init() + return + if not utils.mv(i, N-1): + init() + return + else: + if not utils.mv(i, N-1): + init() + return + if not utils.mv(i, 1): + init() + return + if not utils.mv(N-1, 0): + init() + return + if not utils.mv(0, 0): + init() + return + + return (init, run) + +def check(): + def init(): + pass + + def run(): + if num_items(Items.Bone) >= 33488928: + return True + + return (init, run) + +if __name__ == '__main__': + set_world_size(2) + solve.run([ + growlong(), + # check(), + ])() diff --git a/solve.py b/solve.py new file mode 100644 index 0000000..4627e66 --- /dev/null +++ b/solve.py @@ -0,0 +1,16 @@ +import utils + +def run(ops, delay=0): + def ret(): + for init, run in ops: + init() + + begin = get_tick_count() + while get_tick_count()-begin < delay: + do_a_flip() + + while True: + for init, run in ops: + if run(): + return + return ret diff --git a/sunflower.py b/sunflower.py new file mode 100644 index 0000000..fa4ae21 --- /dev/null +++ b/sunflower.py @@ -0,0 +1,133 @@ +import utils, solve + +def growbase(xl, xr, yl, yr): + def init(): + utils.mv(xl, yl) + def fillx(x): + def ret(): + for y in range(yl, yr): + utils.mv(x, y) + utils.soil() + utils.replant(Entities.Sunflower) + while utils.meas() != 7: + harvest() + plant(Entities.Sunflower) + return ret + + drowns = list() + for x in range(xl+1, xr): + drown = None + while drown == None: + drown = spawn_drone(fillx(x)) + drowns.append(drown) + fillx(xl)() + for drown in drowns: + wait_for(drown) + + def run(): + pass + + return (init, run) + + +def grow(xl, xr, yl, yr): + def init(): + utils.mv(xl, yl) + def fillx(x): + def ret(): + for y in range(yl, yr): + utils.mv(x, y) + utils.water() + utils.soil() + utils.replant(Entities.Sunflower) + return ret + + drowns = list() + for x in range(xl+1, xr): + drown = None + while drown == None: + drown = spawn_drone(fillx(x)) + drowns.append(drown) + fillx(xl)() + for drown in drowns: + wait_for(drown) + + def run(): + pos = list() + for i in range(7, 15+1): + pos.append(list()) + + for x in range(xl, xr): + l, r, d = yl, yr, 1 + if x%2 == 1: + l, r, d = yr-1, yl-1, -1 + for y in range(l, r, d): + utils.mv(x, y) + cur = measure()-7 + pos[cur].append((x, y)) + + for p in pos: + for x, y in p: + utils.mv(x, y) + while not utils.harv(): + pass + + init() + + return (init, run) + +def growparallel(xl, xr, yl, yr): + def init(): + utils.mv(xl, yl) + def fillx(x): + def ret(): + for y in range(yl, yr): + utils.mv(x, y) + utils.water() + utils.soil() + utils.replant(Entities.Sunflower) + return ret + + drowns = list() + for x in range(xl+1, xr): + drown = None + while drown == None: + drown = spawn_drone(fillx(x)) + drowns.append(drown) + fillx(xl)() + for drown in drowns: + wait_for(drown) + + def run(): + def harvx(k, x): + def ret(): + for y in range(yl, yr): + utils.mv(x, y) + if measure() == k: + while not utils.harv(): + pass + return ret + + for k in range(15, 6, -1): + drowns = list() + for x in range(xl+1, xr): + drown = None + while drown == None: + drown = spawn_drone(harvx(k, x)) + drowns.append(drown) + harvx(k, xl)() + for drown in drowns: + wait_for(drown) + + init() + + return (init, run) + +if __name__ == '__main__': + set_world_size(8) + clear() + + solve.run([ + growbase(0, 8, 0, 2), + grow(0, 8, 2, 8), + ])() diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..17fa63c --- /dev/null +++ b/utils.py @@ -0,0 +1,91 @@ +N = get_world_size() + +def within(p, r): + return ( + r[0] <= p[0] and + p[0] < r[1] and + r[2] <= p[1] and + p[1] < r[3] + ) + +def mv(tx, ty, wrap=False): + x = get_pos_x() + if wrap: + east_step = (tx + N - x) % N + west_step = (x + N - tx) % N + + if east_step < west_step: + for i in range(east_step): + if not move(East): + return False + else: + for i in range(west_step): + if not move(West): + return False + else: + for i in range(max(0, tx-x)): + if not move(East): + return False + for i in range(max(0, x-tx)): + if not move(West): + return False + + y = get_pos_y() + + if wrap: + north_step = (ty + N - y) % N + south_step = (y + N - ty) % N + + if north_step < south_step: + for i in range(north_step): + if not move(North): + return False + else: + for i in range(south_step): + if not move(South): + return False + else: + for i in range(max(0, ty-y)): + if not move(North): + return False + for i in range(max(0, y-ty)): + if not move(South): + return False + + return True + +def water(): + if get_water() < 0.5: + use_item(Items.Water) + +def grass(): + typ = get_ground_type() + if typ != Grounds.Grassland: + till() + +def soil(): + typ = get_ground_type() + if typ != Grounds.Soil: + till() + +def harv(): + if can_harvest(): + harvest() + return True + return False + +def replant(entity): + typ = get_entity_type() + if typ != entity: + harvest() + plant(entity) + +def spawn(func, x=0, y=0): + mv(x, y) + spawn_drone(func) + +def meas(arg=None): + ret = None + while ret == None: + ret = measure(arg) + return ret