From e71fcfdf4f9c2eb42fd33e6a9cffbb4a26f9fdcc Mon Sep 17 00:00:00 2001 From: Matej Focko Date: Tue, 29 Nov 2022 15:21:48 +0100 Subject: [PATCH] feat(ib002,ib111): add backtracking exercise Signed-off-by: Matej Focko --- ib002/04-recursion/karel_1.md | 164 ++++ static/files/ib002/karel_1/.zipit | 0 static/files/ib002/karel_1/generate_mazes.py | 21 + static/files/ib002/karel_1/karel_tk.py | 791 +++++++++++++++++++ static/files/ib002/karel_1/maze007.kw | 34 + static/files/ib002/karel_1/maze008.kw | 34 + static/files/ib002/karel_1/maze009.kw | 34 + static/files/ib002/karel_1/maze010.kw | 34 + static/files/ib002/karel_1/maze011.kw | 34 + static/files/ib002/karel_1/maze012.kw | 34 + static/files/ib002/karel_1/maze013.kw | 34 + static/files/ib002/karel_1/maze014.kw | 34 + static/files/ib002/karel_1/maze015.kw | 34 + static/files/ib002/karel_1/maze016.kw | 34 + static/files/ib002/karel_1/maze017.kw | 34 + static/files/ib002/karel_1/maze018.kw | 34 + static/files/ib002/karel_1/maze019.kw | 34 + static/files/ib002/karel_1/maze020.kw | 34 + static/files/ib002/karel_1/maze021.kw | 34 + static/files/ib002/karel_1/maze022.kw | 34 + static/files/ib002/karel_1/maze023.kw | 34 + static/files/ib002/karel_1/maze024.kw | 34 + static/files/ib002/karel_1/maze025.kw | 34 + static/files/ib002/karel_1/maze026.kw | 34 + static/files/ib002/karel_1/maze027.kw | 34 + static/files/ib002/karel_1/maze028.kw | 34 + static/files/ib002/karel_1/maze029.kw | 34 + static/files/ib002/karel_1/maze030.kw | 34 + static/files/ib002/karel_1/maze031.kw | 34 + static/files/ib002/karel_1/maze032.kw | 34 + static/files/ib002/karel_1/maze033.kw | 34 + static/files/ib002/karel_1/maze034.kw | 34 + static/files/ib002/karel_1/maze035.kw | 34 + static/files/ib002/karel_1/maze036.kw | 34 + static/files/ib002/karel_1/maze037.kw | 34 + static/files/ib002/karel_1/maze038.kw | 34 + static/files/ib002/karel_1/maze039.kw | 34 + static/files/ib002/karel_1/maze040.kw | 34 + static/files/ib002/karel_1/maze041.kw | 34 + static/files/ib002/karel_1/maze042.kw | 34 + static/files/ib002/karel_1/maze069.kw | 32 + static/files/ib002/karel_1/maze666.kw | 30 + static/files/ib002/karel_1/maze_skel.kw | 34 + static/files/ib002/karel_1/skeleton.py | 28 + static/files/ib002/karel_1/stairs.kw | 17 + static/files/ib002/karel_1/stairs2.kw | 20 + static/img/ib002/karel_1/maze.png | Bin 0 -> 25402 bytes static/img/ib002/karel_1/stairs.png | Bin 0 -> 43984 bytes 48 files changed, 2361 insertions(+) create mode 100644 ib002/04-recursion/karel_1.md create mode 100644 static/files/ib002/karel_1/.zipit create mode 100644 static/files/ib002/karel_1/generate_mazes.py create mode 100644 static/files/ib002/karel_1/karel_tk.py create mode 100644 static/files/ib002/karel_1/maze007.kw create mode 100644 static/files/ib002/karel_1/maze008.kw create mode 100644 static/files/ib002/karel_1/maze009.kw create mode 100644 static/files/ib002/karel_1/maze010.kw create mode 100644 static/files/ib002/karel_1/maze011.kw create mode 100644 static/files/ib002/karel_1/maze012.kw create mode 100644 static/files/ib002/karel_1/maze013.kw create mode 100644 static/files/ib002/karel_1/maze014.kw create mode 100644 static/files/ib002/karel_1/maze015.kw create mode 100644 static/files/ib002/karel_1/maze016.kw create mode 100644 static/files/ib002/karel_1/maze017.kw create mode 100644 static/files/ib002/karel_1/maze018.kw create mode 100644 static/files/ib002/karel_1/maze019.kw create mode 100644 static/files/ib002/karel_1/maze020.kw create mode 100644 static/files/ib002/karel_1/maze021.kw create mode 100644 static/files/ib002/karel_1/maze022.kw create mode 100644 static/files/ib002/karel_1/maze023.kw create mode 100644 static/files/ib002/karel_1/maze024.kw create mode 100644 static/files/ib002/karel_1/maze025.kw create mode 100644 static/files/ib002/karel_1/maze026.kw create mode 100644 static/files/ib002/karel_1/maze027.kw create mode 100644 static/files/ib002/karel_1/maze028.kw create mode 100644 static/files/ib002/karel_1/maze029.kw create mode 100644 static/files/ib002/karel_1/maze030.kw create mode 100644 static/files/ib002/karel_1/maze031.kw create mode 100644 static/files/ib002/karel_1/maze032.kw create mode 100644 static/files/ib002/karel_1/maze033.kw create mode 100644 static/files/ib002/karel_1/maze034.kw create mode 100644 static/files/ib002/karel_1/maze035.kw create mode 100644 static/files/ib002/karel_1/maze036.kw create mode 100644 static/files/ib002/karel_1/maze037.kw create mode 100644 static/files/ib002/karel_1/maze038.kw create mode 100644 static/files/ib002/karel_1/maze039.kw create mode 100644 static/files/ib002/karel_1/maze040.kw create mode 100644 static/files/ib002/karel_1/maze041.kw create mode 100644 static/files/ib002/karel_1/maze042.kw create mode 100644 static/files/ib002/karel_1/maze069.kw create mode 100644 static/files/ib002/karel_1/maze666.kw create mode 100644 static/files/ib002/karel_1/maze_skel.kw create mode 100644 static/files/ib002/karel_1/skeleton.py create mode 100644 static/files/ib002/karel_1/stairs.kw create mode 100644 static/files/ib002/karel_1/stairs2.kw create mode 100644 static/img/ib002/karel_1/maze.png create mode 100644 static/img/ib002/karel_1/stairs.png diff --git a/ib002/04-recursion/karel_1.md b/ib002/04-recursion/karel_1.md new file mode 100644 index 0000000..1b2dcbc --- /dev/null +++ b/ib002/04-recursion/karel_1.md @@ -0,0 +1,164 @@ +--- +title: Recursion and backtracking with Robot Karel +description: | + A problem with too many restrictions. +tags: +- python +- karel +- recursion +- backtracking +--- + +- [Sources](pathname://files/ib002/karel_1) + +## Introduction + +In this exercise we will be working with a Robot Karel and with a »very« limited +resources. The point of this exercise is to show how powerful recursion and +backtracking can be even without anything else at your hand. + +## Your environment and problem description + +### Environment + +You are given a robot that is present in a maze and is looking for an exit. Maze +consists of different walls and exit is marked with a single so-called „beeper“. + +Walking into a wall results in a permanent damage of the robot. + +### Interface + +You can control the robot using the following interface: + +- actions ​­— you can use them to change the current state of the robot and its + surroundings + - `robot.step()` — moves robot one step further + - `robot.turn_left()` — turns robot 90-degrees counter-clockwise + - notice that you are not given `turn_right` or `turn_around`, but feel free + to implement them yourself + - `robot.pick_beeper()` and opposite operation `robot.put_beeper()` — that + allows you to either pick or put „beeper“ from or onto the current position +- queries — you can use them to check the current state of the robot and its + surroundings + - `robot.beepers_present()` — to check if there are any beepers at the robot's + current location + - `robot.left_is_clear()` — to check if you can step to the left + - analogically for `front` and `right` + +:::caution + +Helper functions / procedures are allowed. Return values are allowed. + +**Variables are prohibited!** + +::: + +### Problem + +Your task is to decide whether there is an exit from the maze or not. You can see +an example of a maze here: + +![Image of the maze](/img/ib002/karel_1/maze.png) + +## Simple problem to get familiar with the robot + +If you feel completely lost after the previous description, let me start you off +with a simpler problem. + +You are standing in front of the stairs, your task is to walk up the stairs. + +You can see an example of such map here: + +![Image of the stairs](/img/ib002/karel_1/stairs.png) + +## Brainstorm the idea + +As a first step write down any ideas and things that you have noticed or came to +your mind. Ideally: + +- Write down a nested list of the problems, e.g. + + :::info Example + + Problem: I want to find out whether the display on smartphone should rotate. + + - Check if display has been rotated + - Read data from some sensor + - From what sensor + - In what format are the data I have read? + - How do I communicate with the sensor? + - What is the meaning of the data that I got? + - How can I process it? + + ::: +- Write down list of problems that can happen, e.g. + + :::info Example continued + + Following the same problem. + + - What if the sensor doesn't work? + - What if the data doesn't conform to the specification? + - What if my formulas are wrong? + + ::: +- Write down **anything** you consider important to solving the problem, e.g. + + :::info Example continued once again + + - I could probably use gyroscope. + - I should probably look up the datasheet for that module. + - I could write some tests to verify that my computations are correct. + + ::: + +## »Rough« pseudocode + +As a next step write a **mock up** of a pseudocode solving the problem, you are +allowed to use comments as placeholders for bigger chunks of code. + +Those comments are also a very good hints for decomposition and short, but +descriptive, commnets (if they are short enough and you decide not to factor them +out to separate functions). + +:::tip + +The smaller the function is, the easier it is to test it and argue about its +correctness. + +::: + +## »Proper« pseudocode + +If you are satisfied with the _»rough« pseudocode_, it's time to convert it into +a proper one. Get rid of the uncertain pieces of functionality and replace them +with proper pseudocode, i.e. list of the things that should happen in its place. + +## Library + +If you got here, and you **actually** wrote down the pseudocode, you can try your +solution after downloading the sources linked at the beginning. If you download +the ZIP-file, you can there: + +- `generate_mazes.py` - that was used to generate the same maze with beepers in + different locations +- `karel_tk.py` - library which can run Karel given the his world + - documentation can be found [here](https://www.fi.muni.cz/~xfocko/ib111/10/docs/) + - also requires Tk Python library to be installed (it should be included in + majority of Python installations) +- `*.kw` - which represent multiple worlds for Karel I have prepared +- `skeleton.py` - skeleton for your solution, needs to be put in the same directory + as `karel_tk.py` and takes path to the world as a first argument, example usage: + + $ python3 skeleton.py stairs.kw + + - of course, this file can be renamed ;) + +## Solution + +Solution to this problem will be released as a second part, so that you can try +it out by yourself without any influence of „example solution“. + +If you want to get any feedback, feel free to mail me your solution (including +all the steps that lead to your final solution, if you wish to get feedback on +those too). \ No newline at end of file diff --git a/static/files/ib002/karel_1/.zipit b/static/files/ib002/karel_1/.zipit new file mode 100644 index 0000000..e69de29 diff --git a/static/files/ib002/karel_1/generate_mazes.py b/static/files/ib002/karel_1/generate_mazes.py new file mode 100644 index 0000000..8b19fd8 --- /dev/null +++ b/static/files/ib002/karel_1/generate_mazes.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +from itertools import product + + +def generate_map(template: str, st: int, ave: int) -> str: + return template.format(st=st, ave=ave) + + +def main(): + template = None + with open("maze_skel.kw", "r") as f: + template = f.read() + + for st, ave in product(range(1, 7), range(1, 7)): + with open("maze{:03d}.kw".format(st * 6 + ave), "w") as out: + print(generate_map(template, st, ave), file=out) + + +if __name__ == "__main__": + main() diff --git a/static/files/ib002/karel_1/karel_tk.py b/static/files/ib002/karel_1/karel_tk.py new file mode 100644 index 0000000..e988c4e --- /dev/null +++ b/static/files/ib002/karel_1/karel_tk.py @@ -0,0 +1,791 @@ +from dataclasses import dataclass +from enum import Enum, IntEnum +from functools import wraps +from itertools import product +from math import radians, sin, cos +from sys import stderr +import tkinter as tk +from typing import Tuple, Union + + +def check_before(precondition): + """ + Decorator for running methods before executing a method. + + Args: + call_before: Function to be called before executing a method. + + Returns: + Parametrized decorator that can be used to wrap method with the + `call_before`. + """ + + def parametrized(f): + @wraps(f) + def wrapper(self, *args, **kwargs): + if not precondition(self, *args, **kwargs, fn=f): + return + return f(self, *args, **kwargs) + + return wrapper + + return parametrized + + +def after(call_after): + """ + Decorator for running methods after executing a method. + + Args: + call_after: Function to be called after executing a method. + + Returns: + Parametrized decorator that can be used to wrap method with the + `call_after`. + """ + + def parametrized(f): + @wraps(f) + def wrapper(self, *args, **kwargs): + result = f(self, *args, **kwargs) + call_after(self, *args, **kwargs, fn=f) + return result + + return wrapper + + return parametrized + + +def skip_for_summary(f): + """ + Decorator used for skipping a function call if the Karel is running + in a summary mode. + """ + + @wraps(f) + def wrapper(self, *args, **kwargs): + if self.summary_mode: + return + return f(self, *args, **kwargs) + + return wrapper + + +class Block(IntEnum): + """ + Represents a field in the world of the Robot Karel. + It can be either clear or a wall. + """ + + Clear = 0 + Wall = -1 + + +# Constants for major angles +EAST, NORTH, WEST, SOUTH = 0, 90, 180, 270 + + +# @dataclass(frozen=True, slots=True) +@dataclass(frozen=True) +class _Direction: + """ + angle: Represents heading of the Robot Karel + """ + + angle: int + + @property + def vector(self) -> Tuple[int, int]: + """ + Get a direction vector in the current direction the robot is heading. + + Returns: + Pair of ints, representing a vector of (dx, dy). + """ + angle, x, y = radians(self.angle), 1, 0 + return ( + x * round(cos(angle)) - y * round(sin(angle)), + x * round(sin(angle)) + y * round(cos(angle)), + ) + + @property + def in_world(self) -> str: + """ + Get a character that is being put in the graphical representation of + the Robot Karel. + + Returns: + Character to be put in the world. + """ + return { + Direction.East.value: ">", + Direction.North.value: "^", + Direction.West.value: "<", + Direction.South.value: "v", + # Direction.East.value: "⮞", + # Direction.North.value: "⮝", + # Direction.West.value: "⮜", + # Direction.South.value: "⮟", + }[self] + + @property + def as_string(self) -> str: + """ + Returns a string with a direction for Tk label. + + Returns: + Label of the direction + """ + return { + Direction.East.value: "east", + Direction.North.value: "north", + Direction.West.value: "west", + Direction.South.value: "south", + }[self] + + def __add__(self, angle: int) -> "_Direction": + return _Direction((360 + self.angle + angle) % 360) + + +class Direction(Enum): + """ + Provides constants of directions Karel can face. + """ + + East = _Direction(EAST) + North = _Direction(NORTH) + West = _Direction(WEST) + South = _Direction(SOUTH) + + +class KarelWindow: + def __init__(self, karel: "Karel", scale: int, font: str): + self.size = 32 * scale + + self.steps = tk.Label(text=karel.steps, anchor="e") + self.steps.grid(row=0, column=0, sticky="e") + + self.last_cmd = tk.Label(text=karel.last_command, anchor="w") + self.last_cmd.grid(row=0, column=1, columnspan=3, sticky="w") + + tk.Label(text="CORNER").grid(row=1, column=0) + tk.Label(text="FACING").grid(row=1, column=1) + tk.Label(text="BEEP-BAG").grid(row=1, column=2) + tk.Label(text="BEEP-CORNER").grid(row=1, column=3) + + self.corner = tk.Label() + self.corner.grid(row=2, column=0) + + self.facing = tk.Label() + self.facing.grid(row=2, column=1) + + self.beep_bag = tk.Label() + self.beep_bag.grid(row=2, column=2) + + self.beep_corner = tk.Label() + self.beep_corner.grid(row=2, column=3) + + self.canvas = tk.Canvas( + width=((karel.world.width + 1) // 2 + 2) * self.size, + height=((karel.world.height + 1) // 2 + 2) * self.size, + background="black", + ) + self.canvas.grid(column=0, row=3, columnspan=4) + + self.font = f"{font} {int(12 * scale)}" + + self.__draw_world(karel.world) + self.render(karel) + + def __draw_world(self, world: "World"): + m, n = (world.height + 1) // 2, (world.width + 1) // 2 + + # NUMBERS + self.canvas.create_text( + self.size // 2, + self.size, + text="ST.", + fill="white", + anchor="s", + font=self.font, + ) + for i in range(m): + self.canvas.create_text( + self.size - 8, + (i + 2) * self.size - self.size // 2, + text=(m - i), + anchor="e", + fill="white", + font=self.font, + ) + y = ((m + 1) * self.size) + 8 + self.canvas.create_text( + (n + 1) * self.size + self.size // 2, + y, + text="AVE.", + fill="white", + anchor="n", + font=self.font, + ) + for i in range(n): + self.canvas.create_text( + (i + 2) * self.size - self.size // 2, + y, + text=(i + 1), + anchor="n", + fill="white", + font=self.font, + ) + + # BORDER + self.canvas.create_rectangle( + self.size, + self.size, + self.size * (n + 1), + self.size * (m + 1), + fill="", + outline="white", + ) + + for row, col in product(range(world.height), range(world.width)): + block = world.data[row][col] + if row % 2 == 0 and col % 2 == 0: + self.__print_beeper(world, block or ".", row // 2, col // 2) + elif block == Block.Wall: + size = self.size + x = size + col // 2 * size + y = (world.width + 1) // 2 * size - row // 2 * size + if row % 2 == 1 and col % 2 == 0: + self.canvas.create_line(x, y, x + size, y, fill="white") + elif row % 2 == 0: + x += size + self.canvas.create_line(x, y, x, y + size, fill="white") + + self.canvas.update() + + def __print_beeper( + self, world: "World", beeper: Union[str, int], row: int, column: int + ): + self.canvas.create_text( + (column + 1) * self.size + self.size // 2, + ((world.height + 1) // 2 - row) * self.size + self.size // 2, + text=str(beeper), + anchor="center", + fill="white", + font=self.font, + ) + + def render(self, karel: "Karel"): + self.facing["text"] = karel.direction.as_string + + self.steps["text"] = karel.steps + self.last_cmd["text"] = karel.last_command + self.corner["text"] = f"({(karel.x + 2) // 2}, {(karel.y + 2) // 2})" + self.beep_bag["text"] = karel.beepers + self.beep_corner["text"] = karel.world.data[karel.y][karel.x] + + i, j = (karel.y + 2) // 2, (karel.x + 2) // 2 + size = self.size + x, y = j * size, ((karel.world.height + 1) // 2 - i + 1) * size + self.canvas.create_rectangle( + x + 1, y + 1, x + size - 1, y + size - 1, fill="black" + ) + + karel_on_map = karel.direction.in_world + self.canvas.create_text( + x + size // 2, + y + size // 2, + text=karel_on_map, + font=self.font + " bold", + fill="yellow", + anchor="center", + ) + + self.canvas.update() + self.canvas.after(karel.step_delay) + + def update(self, karel: "Karel", dx: int, dy: int): + block = karel.world.data[karel.y - 2 * dy][karel.x - 2 * dx] + + i, j = (karel.y - 2 * dy) // 2, (karel.x - 2 * dx) // 2 + x, y = (j + 1) * self.size, ( + (karel.world.height + 1) // 2 - i + ) * self.size + + self.canvas.create_rectangle( + x + 1, y + 1, x + self.size - 1, y + self.size - 1, fill="black" + ) + self.__print_beeper(karel.world, block or ".", i, j) + + def error(self, karel: "Karel", message: str): + self.render(karel) + + self.last_cmd["foreground"] = "red" + self.last_cmd["text"] = f"Error Shutoff! ({message})" + + +class World: + def __init__(self, width, height, data): + self.width = width * 2 - 1 + self.height = height * 2 - 1 + self.data = [ + [0 for _ in range(self.width)] for _ in range(self.height) + ] + + if self.width > 30 or self.height > 30: + raise ValueError( + "The given world is greater than the max values of [{}x{}]".format( + 30, 30 + ) + ) + + self._parse_world(data) + + def __parse_wall(self, column, row, orientation, line): + column = column * 2 - 2 + row = row * 2 - 2 + + if column % 2 == 1 or row % 2 == 1: + raise ValueError("Wrong position of the wall") + + if orientation == "E": + column += 1 + elif orientation == "W": + column -= 1 + elif orientation == "N": + row += 1 + elif orientation == "S": + row -= 1 + else: + raise ValueError( + "Unknown wall orientation '{}' on line {} in world file".format( + orientation, line + ) + ) + + self.data[row][column] = Block.Wall + if column % 2 == 1 and row % 2 == 0: + if row + 1 < self.height: + self.data[row + 1][column] = Block.Wall + if row - 1 >= 0: + self.data[row - 1][column] = Block.Wall + else: + if column + 1 < self.width: + self.data[row][column + 1] = Block.Wall + if column - 1 >= 0: + self.data[row][column - 1] = Block.Wall + + def __parse_beepers(self, column, row, count): + column = column * 2 - 2 + row = row * 2 - 2 + self.data[row][column] = count + + def _parse_world(self, world_content): + for i, line in enumerate(world_content, 1): + if not line: + continue + + block, column, row, arg = [part.upper() for part in line.split()] + if block == "W": + self.__parse_wall(int(column), int(row), arg, i) + elif block == "B": + self.__parse_beepers(int(column), int(row), int(arg)) + else: + raise ValueError( + "Unknown block character '{}' on line {} in world file".format( + block, i + ) + ) + + +class Karel: + def __init__( + self, filename, summary_mode=False, scale=1, font="monospace" + ): + """ + Turn Karel on. + + Args: + filename: Path to the file containing Karel's world and initial + settings. + summary_mode: Disable rendering of the Karel's world in the window. + + Defaults to `False`. + scale: Change the scaling factor of the font used to render Karel's + world. + + Defaults to `1`. + font: Change the default monospace font that is used to render the + world. + + Defaults to `"monospace"`. + """ + self.summary_mode = summary_mode + + world_content = None + with open(filename) as world_file: + world_content = world_file.read() + + first_line, world = world_content.split("\n", maxsplit=1) + width, height, x, y, direction, beepers = first_line.split() + direction = direction.upper() + + self.world = World(int(width), int(height), world.split("\n")) + self.x, self.y = int(x) * 2 - 2, int(y) * 2 - 2 + + if direction == "S": + self.direction = Direction.South.value + elif direction == "W": + self.direction = Direction.West.value + elif direction == "E": + self.direction = Direction.East.value + elif direction == "N": + self.direction = Direction.North.value + else: + raise ValueError("Unknown Karel's direction") + + self.beepers = int(beepers) + + self.steps = 0 + self.step_delay = 1000 + self.is_running = True + self.last_command = "turn_on" + + self._initialize_window(scale, font) + + @skip_for_summary + def _initialize_window(self, scale, font): + """ + Initializes a window where the Karel is drawn. + """ + self._window = KarelWindow(self, scale, font) + + @skip_for_summary + def __update(self, dx, dy): + """ + Updates Karel's position in the window. + + Args: + dx: Change along the horizontal axis. + dy: Change along the vertical axis. + """ + self._window.update(self, dx, dy) + + def __render(self, fn, *args, **kwargs): + """ + Updates step counter and last command for Karel. + If the robot is not running in a summary mode, then the window + is rendered once again. + """ + if not self.is_running: + return + + self.steps += 1 + self.last_command = fn.__name__ + + if not self.summary_mode: + self._window.render(self) + + def __error(self, message): + """ + Provides error handling. + + Args: + message: Error message to be shown. + """ + if not self.summary_mode: + self._window.error(self, message) + self.is_running = False + else: + print(f"Error Shutoff! ({message})", file=stderr) + + @skip_for_summary + def __deinit(self): + tk.mainloop() + + def __check_state(self, *args, **kwargs): + """ + Assures that commands are not run while the robot is not running. + + Robot is not running when error has occurred. + """ + return self.is_running + + @check_before(__check_state) + def beepers_in_bag(self): + """ + Check if there are any beepers in the Karel's bag. + + Returns: + `True` if there is at least one beeper in Karel's beeper bag, + `False` otherwise. + """ + return self.beepers > 0 + + def no_beepers_in_bag(self): + """ + Check if there are no beepers in the Karel's bag. + + Returns: + `True` if there is no beeper in Karel's beeper bag, `False` otherwise. + """ + return not self.beepers_in_bag() + + @check_before(__check_state) + def front_is_clear(self): + """ + Check if there is no wall in front of Karel. + + Returns: + `True` if there is no obstacle in front of Karel, `False` otherwise. + """ + dx, dy = self.direction.vector + if not ( + 0 <= self.x + dx < self.world.width + and 0 <= self.y + dy < self.world.height + ): + return False + + if self.world.data[self.y + dy][self.x + dx] == Block.Wall: + return False + + return True + + def front_is_blocked(self): + """ + Check if there is a wall in front of Karel. + + Returns: + `True` if there is an obstacle in front of Karel, `False` otherwise. + """ + return not self.front_is_clear() + + @check_before(__check_state) + def __side_is_clear(self, d): + """ + Helper function for determining whether the sides of Karel are clear. + + Args: + d: Counterclockwise change in angle of Karel's heading. + + Returns: + `True` if the side after applying the `d` counterclokwise turn + is clear, `False` otherwise. + """ + original_direction = self.direction + self.direction = self.direction + d + + is_clear = self.front_is_clear() + self.direction = original_direction + + return is_clear + + def left_is_clear(self): + """ + Check if there is no wall to the left side of Karel. + + Returns: + `True` if there is no obstacle to the left side of Karel, + `False` otherwise. + """ + return self.__side_is_clear(90) + + def left_is_blocked(self): + """ + Check if there is a wall to the left side of Karel. + + Returns: + `True` if there is an obstacle to the left side of Karel, + `False` otherwise. + """ + return not self.left_is_clear() + + def right_is_clear(self): + """ + Check if there is no wall to the right side of Karel. + + Returns: + `True` if there is no obstacle to the right side of Karel, + `False` otherwise. + """ + return self.__side_is_clear(-90) + + def right_is_blocked(self): + """ + Check if there is a wall to the right side of Karel. + + Returns: + `True` if there is an obstacle to the right side of Karel, + `False` otherwise. + """ + return not self.right_is_clear() + + @check_before(__check_state) + def facing_north(self): + """ + Check if Karel is facing north. + + Returns: + `True` if Karel is facing north, `False` otherwise. + """ + return self.direction == Direction.North + + def not_facing_north(self): + """ + Check if Karel is »not« facing north. + + Returns: + `True` if Karel is »not« facing north, `False` otherwise. + """ + return not self.facing_north() + + @check_before(__check_state) + def facing_south(self): + """ + Check if Karel is facing south. + + Returns: + `True` if Karel is facing south, `False` otherwise. + """ + return self.direction == Direction.South + + def not_facing_south(self): + """ + Check if Karel is »not« facing south. + + Returns: + `True` if Karel is »not« facing south, `False` otherwise. + """ + return not self.facing_south() + + @check_before(__check_state) + def facing_east(self): + """ + Check if Karel is facing east. + + Returns: + `True` if Karel is facing east, `False` otherwise. + """ + return self.direction == Direction.East + + def not_facing_east(self): + """ + Check if Karel is »not« facing east. + + Returns: + `True` if Karel is »not« facing east, `False` otherwise. + """ + return not self.facing_east() + + @check_before(__check_state) + def facing_west(self): + """ + Check if Karel is facing west. + + Returns: + `True` if Karel is facing west, `False` otherwise. + """ + return self.direction == Direction.West + + def not_facing_west(self): + """ + Check if Karel is »not« facing west. + + Returns: + `True` if Karel is »not« facing west, `False` otherwise. + """ + return not self.facing_west() + + @check_before(__check_state) + def beepers_present(self): + """ + Check whether Karel stands on a position that has any beepers present. + + Returns: + `True` if there is at least one beeper present on the current + position, `False` otherwise. + """ + return self.world.data[self.y][self.x] > 0 + + def no_beepers_present(self): + """ + Check whether Karel stands on a position that has no beepers present. + + Returns: + `True` if there is no beeper present on the current position, + `False` otherwise. + """ + return not self.beepers_present() + + @check_before(__check_state) + @after(__render) + def step(self): + """ + Move Karel one position in the direction he's facing. + """ + if not self.front_is_clear(): + return self.__error("Can't move this way") + + dx, dy = self.direction.vector + self.x += 2 * dx + self.y += 2 * dy + self.__update(dx, dy) + + @check_before(__check_state) + @after(__render) + def turn_left(self): + """ + Turn Karel counterclockwise, i.e. left, by 90 degrees. + """ + self.direction = self.direction + 90 + + @after(__render) + def turn_off(self): + """ + Turn Karel off. + """ + self.is_running = False + self.__deinit() + + @check_before(__check_state) + @after(__render) + def put_beeper(self): + """ + Take a beeper from Karel's beeper bag and put on the current position. + """ + if self.beepers <= 0: + return self.__error("Karel has no beeper to put at the corner") + + self.world.data[self.y][self.x] += 1 + self.beepers -= 1 + + @check_before(__check_state) + @after(__render) + def pick_beeper(self): + """ + Pick a beeper from the current position and put it into Karel's + beeper bag. + """ + if self.world.data[self.y][self.x] <= 0: + return self.__error("There is no beeper at the corner") + + self.world.data[self.y][self.x] -= 1 + self.beepers += 1 + + def set_step_delay(self, delay): + """ + Set delay of a Karel's step. + + Args: + delay: Delay of one step in milliseconds. + """ + self.step_delay = delay + + def get_step_delay(self): + """ + Get current delay of a Karel's step. + + Returns: + Current delay in milliseconds. + """ + return self.step_delay diff --git a/static/files/ib002/karel_1/maze007.kw b/static/files/ib002/karel_1/maze007.kw new file mode 100644 index 0000000..b95426f --- /dev/null +++ b/static/files/ib002/karel_1/maze007.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 1 1 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze008.kw b/static/files/ib002/karel_1/maze008.kw new file mode 100644 index 0000000..de0a9b4 --- /dev/null +++ b/static/files/ib002/karel_1/maze008.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 1 2 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze009.kw b/static/files/ib002/karel_1/maze009.kw new file mode 100644 index 0000000..18a3f09 --- /dev/null +++ b/static/files/ib002/karel_1/maze009.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 1 3 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze010.kw b/static/files/ib002/karel_1/maze010.kw new file mode 100644 index 0000000..43ffb94 --- /dev/null +++ b/static/files/ib002/karel_1/maze010.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 1 4 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze011.kw b/static/files/ib002/karel_1/maze011.kw new file mode 100644 index 0000000..741527d --- /dev/null +++ b/static/files/ib002/karel_1/maze011.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 1 5 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze012.kw b/static/files/ib002/karel_1/maze012.kw new file mode 100644 index 0000000..89579d9 --- /dev/null +++ b/static/files/ib002/karel_1/maze012.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 1 6 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze013.kw b/static/files/ib002/karel_1/maze013.kw new file mode 100644 index 0000000..895731d --- /dev/null +++ b/static/files/ib002/karel_1/maze013.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 2 1 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze014.kw b/static/files/ib002/karel_1/maze014.kw new file mode 100644 index 0000000..b732cfc --- /dev/null +++ b/static/files/ib002/karel_1/maze014.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 2 2 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze015.kw b/static/files/ib002/karel_1/maze015.kw new file mode 100644 index 0000000..d028262 --- /dev/null +++ b/static/files/ib002/karel_1/maze015.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 2 3 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze016.kw b/static/files/ib002/karel_1/maze016.kw new file mode 100644 index 0000000..79d6f8d --- /dev/null +++ b/static/files/ib002/karel_1/maze016.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 2 4 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze017.kw b/static/files/ib002/karel_1/maze017.kw new file mode 100644 index 0000000..25ce9dc --- /dev/null +++ b/static/files/ib002/karel_1/maze017.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 2 5 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze018.kw b/static/files/ib002/karel_1/maze018.kw new file mode 100644 index 0000000..8ad01cf --- /dev/null +++ b/static/files/ib002/karel_1/maze018.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 2 6 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze019.kw b/static/files/ib002/karel_1/maze019.kw new file mode 100644 index 0000000..fc9ea4f --- /dev/null +++ b/static/files/ib002/karel_1/maze019.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 3 1 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze020.kw b/static/files/ib002/karel_1/maze020.kw new file mode 100644 index 0000000..08658f6 --- /dev/null +++ b/static/files/ib002/karel_1/maze020.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 3 2 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze021.kw b/static/files/ib002/karel_1/maze021.kw new file mode 100644 index 0000000..ea739ef --- /dev/null +++ b/static/files/ib002/karel_1/maze021.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 3 3 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze022.kw b/static/files/ib002/karel_1/maze022.kw new file mode 100644 index 0000000..3736978 --- /dev/null +++ b/static/files/ib002/karel_1/maze022.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 3 4 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze023.kw b/static/files/ib002/karel_1/maze023.kw new file mode 100644 index 0000000..3f8b615 --- /dev/null +++ b/static/files/ib002/karel_1/maze023.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 3 5 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze024.kw b/static/files/ib002/karel_1/maze024.kw new file mode 100644 index 0000000..1966ace --- /dev/null +++ b/static/files/ib002/karel_1/maze024.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 3 6 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze025.kw b/static/files/ib002/karel_1/maze025.kw new file mode 100644 index 0000000..b654219 --- /dev/null +++ b/static/files/ib002/karel_1/maze025.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 4 1 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze026.kw b/static/files/ib002/karel_1/maze026.kw new file mode 100644 index 0000000..ebaf8bd --- /dev/null +++ b/static/files/ib002/karel_1/maze026.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 4 2 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze027.kw b/static/files/ib002/karel_1/maze027.kw new file mode 100644 index 0000000..924f3f5 --- /dev/null +++ b/static/files/ib002/karel_1/maze027.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 4 3 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze028.kw b/static/files/ib002/karel_1/maze028.kw new file mode 100644 index 0000000..df6c8c2 --- /dev/null +++ b/static/files/ib002/karel_1/maze028.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 4 4 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze029.kw b/static/files/ib002/karel_1/maze029.kw new file mode 100644 index 0000000..f742654 --- /dev/null +++ b/static/files/ib002/karel_1/maze029.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 4 5 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze030.kw b/static/files/ib002/karel_1/maze030.kw new file mode 100644 index 0000000..54b00ec --- /dev/null +++ b/static/files/ib002/karel_1/maze030.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 4 6 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze031.kw b/static/files/ib002/karel_1/maze031.kw new file mode 100644 index 0000000..f8beac8 --- /dev/null +++ b/static/files/ib002/karel_1/maze031.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 5 1 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze032.kw b/static/files/ib002/karel_1/maze032.kw new file mode 100644 index 0000000..0c54b03 --- /dev/null +++ b/static/files/ib002/karel_1/maze032.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 5 2 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze033.kw b/static/files/ib002/karel_1/maze033.kw new file mode 100644 index 0000000..b03209d --- /dev/null +++ b/static/files/ib002/karel_1/maze033.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 5 3 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze034.kw b/static/files/ib002/karel_1/maze034.kw new file mode 100644 index 0000000..2682e25 --- /dev/null +++ b/static/files/ib002/karel_1/maze034.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 5 4 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze035.kw b/static/files/ib002/karel_1/maze035.kw new file mode 100644 index 0000000..d6981b1 --- /dev/null +++ b/static/files/ib002/karel_1/maze035.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 5 5 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze036.kw b/static/files/ib002/karel_1/maze036.kw new file mode 100644 index 0000000..35cd0b6 --- /dev/null +++ b/static/files/ib002/karel_1/maze036.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 5 6 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze037.kw b/static/files/ib002/karel_1/maze037.kw new file mode 100644 index 0000000..5361d58 --- /dev/null +++ b/static/files/ib002/karel_1/maze037.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 6 1 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze038.kw b/static/files/ib002/karel_1/maze038.kw new file mode 100644 index 0000000..2bf360c --- /dev/null +++ b/static/files/ib002/karel_1/maze038.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 6 2 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze039.kw b/static/files/ib002/karel_1/maze039.kw new file mode 100644 index 0000000..3f5fc81 --- /dev/null +++ b/static/files/ib002/karel_1/maze039.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 6 3 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze040.kw b/static/files/ib002/karel_1/maze040.kw new file mode 100644 index 0000000..dd2a661 --- /dev/null +++ b/static/files/ib002/karel_1/maze040.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 6 4 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze041.kw b/static/files/ib002/karel_1/maze041.kw new file mode 100644 index 0000000..93198c7 --- /dev/null +++ b/static/files/ib002/karel_1/maze041.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 6 5 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze042.kw b/static/files/ib002/karel_1/maze042.kw new file mode 100644 index 0000000..d09efdc --- /dev/null +++ b/static/files/ib002/karel_1/maze042.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B 6 6 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze069.kw b/static/files/ib002/karel_1/maze069.kw new file mode 100644 index 0000000..c87840f --- /dev/null +++ b/static/files/ib002/karel_1/maze069.kw @@ -0,0 +1,32 @@ +6 6 1 1 E 72 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N diff --git a/static/files/ib002/karel_1/maze666.kw b/static/files/ib002/karel_1/maze666.kw new file mode 100644 index 0000000..23b6387 --- /dev/null +++ b/static/files/ib002/karel_1/maze666.kw @@ -0,0 +1,30 @@ +6 6 2 1 E 72 + +B 6 3 1 + +W 2 1 N +W 3 1 N +W 4 1 N + +W 2 5 N +W 3 5 N +W 4 5 N + +W 1 2 E +W 1 3 E +W 1 4 E +W 1 5 E + +W 4 2 E +W 2 3 E +W 2 4 E +W 4 5 E + +W 5 1 E +W 5 2 E +W 5 4 E +W 5 5 E +W 5 6 E + +W 6 3 N +W 6 3 S \ No newline at end of file diff --git a/static/files/ib002/karel_1/maze_skel.kw b/static/files/ib002/karel_1/maze_skel.kw new file mode 100644 index 0000000..abc53ee --- /dev/null +++ b/static/files/ib002/karel_1/maze_skel.kw @@ -0,0 +1,34 @@ +6 6 1 1 E 72 + +B {st} {ave} 1 + +W 1 1 E +W 1 3 E +W 1 4 E +W 1 5 N + +W 2 1 N +W 2 2 E +W 2 2 N +W 2 4 N +W 2 5 E + +W 3 2 N +W 3 3 N +W 3 4 E +W 3 5 E + +W 4 1 E +W 4 1 N +W 4 3 E +W 4 3 N +W 4 4 E +W 4 5 E + +W 5 2 E +W 5 2 N +W 5 4 E +W 5 5 N +W 5 6 E + +W 6 4 N \ No newline at end of file diff --git a/static/files/ib002/karel_1/skeleton.py b/static/files/ib002/karel_1/skeleton.py new file mode 100644 index 0000000..4b37da5 --- /dev/null +++ b/static/files/ib002/karel_1/skeleton.py @@ -0,0 +1,28 @@ +from karel_tk import Karel + +import sys + + +class SuperKarel(Karel): + # you can define your own helper functions on Karel here, if you wish to + + def run(self): + # TODO + pass + + +def main(): + if len(sys.argv) != 2: + print("Please provide a path to the world as an argument.") + return + + k = SuperKarel(sys.argv[1], scale=3, font="Iosevka\\ Term") + k.set_step_delay(500) + + k.run() + + k.turn_off() + + +if __name__ == "__main__": + main() diff --git a/static/files/ib002/karel_1/stairs.kw b/static/files/ib002/karel_1/stairs.kw new file mode 100644 index 0000000..d0cc80a --- /dev/null +++ b/static/files/ib002/karel_1/stairs.kw @@ -0,0 +1,17 @@ +9 9 1 1 E 0 +W 2 1 E +W 3 2 S +W 3 2 E +W 4 3 S +W 4 3 E +W 5 4 S +W 5 4 E +W 6 5 S +W 7 4 W +W 7 3 W +W 7 2 W +W 7 1 W + +B 3 2 1 +B 4 3 1 +B 5 4 1 diff --git a/static/files/ib002/karel_1/stairs2.kw b/static/files/ib002/karel_1/stairs2.kw new file mode 100644 index 0000000..6453ace --- /dev/null +++ b/static/files/ib002/karel_1/stairs2.kw @@ -0,0 +1,20 @@ +9 9 1 1 E 0 + +W 1 1 E +W 2 1 N + +W 3 2 S +W 3 2 E +W 4 3 S +W 4 3 E +W 5 4 S +W 5 4 E +W 6 5 S +W 7 4 W +W 7 3 W +W 7 2 W +W 7 1 W + +B 3 2 1 +B 4 3 1 +B 5 4 1 diff --git a/static/img/ib002/karel_1/maze.png b/static/img/ib002/karel_1/maze.png new file mode 100644 index 0000000000000000000000000000000000000000..914cb66769236611d07ec1e35cd5d00aee4d7a1b GIT binary patch literal 25402 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 ($j9p0pVD-MQTFO}=DZUj`!c?2v#p!ou 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