commit f13ce0450b1457abb062f61d2a3bf2d3925a67e8 Author: Yi-Ting Shih Date: Mon Nov 10 03:07:40 2025 +0800 Chore: checkpoint 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