diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 5109195..c9f3e7c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -5,12 +5,11 @@ on: [push] jobs: build: - # windows-latest does not work runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest] - python-version: [3.7, 3.8, 3.9.0-beta.5] + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.7, 3.8, 3.9] steps: - uses: actions/checkout@v2 @@ -31,11 +30,7 @@ jobs: # stop the build if there are Python syntax errors or undefined names flake8 karel_robot --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. - flake8 karel_robot \ - --count --exit-zero --statistics \ - --max-complexity=10 \ - --per-file-ignores='karel_robot/run/*:F405 F403' \ - --max-line-length=88 + flake8 karel_robot --count --exit-zero --statistics --max-complexity=10 --per-file-ignores='karel_robot/run/*:F405 F403' --max-line-length=88 - name: Test with pytest run: | pytest tests --junitxml=junit/test-results-${{ matrix.python-version }}.xml diff --git a/README.md b/README.md index 32c5d62..59999b2 100755 --- a/README.md +++ b/README.md @@ -86,9 +86,9 @@ These are the functions you can use to command Karel after importing from `karel | `set_karel_beepers(None)`| Set Karel's beepers, with `None` as inf. | | `set_speed(100)` | How fast Karel moves, 0 to 100 | | `pause()` | Pause execution, press any key to continue | -| `message(text, pause)` | Show a text message to user. | -| `save()` | Save the map in file specified by `--output`. | -| `exit()` | End execution | +| `message(text, pause)` | Show a text message to user. | +| `save()` | Save the map in file specified by `--output`. | +| `exit()` | End execution | Note that the map is loaded and screen started in the moment of import: @@ -147,7 +147,8 @@ python3 YOUR_PROGRAM.py # -m YOUR_MAP.km or other options Press Q to quit or P to pause program. Program pauses when Karel tries to make an illegal move. -### Example treasure +### Example treasure πŸ’° +
Click to expand! Run the program `treasure.py` (also below) with worlds `00` - `03_window`. @@ -181,16 +182,17 @@ The idea comes from a [paper on cooperative learning in CS1](https://dl.acm.org/
-### Langton's ant +### Langton's ant 🐜 +
Click to expand! + Here is a short animation of Karel playing Langton's ant.[[wiki]](https://en.wikipedia.org/wiki/Langton%27s_ant)

langton_optimized

- The program `ant.py` (also below) uses a single beeper to mark a tile as "Black" and Karel can pick it up to make it "White". The ant moves seemingly randomly, but makes a nice picture in about 11000 steps. @@ -279,17 +281,17 @@ which you then END. These statements are the simple building blocks you can use and combine with your new procedures: -| Statement | Note | -| :-----------------------------------------: | ------------------------------------------------------------ | -| MOVE | Karel steps forward. | -| LEFT | Karel turns 90Β° left - note that there is no `RIGHT` :) | -| PUT | Karel puts down one beeper. | -| PICK | Karel picks up one beeper. | -| SKIP | Does nothing - like `pass` in Python. | -| IFWALL βœ“ 𐄂 | If `front_is_blocked()` then `pass` else `move()` | -| IFMARK βœ“ 𐄂 | If `beeper_is_present()` then `pick_beeper()` else `put_beeper()` | +| Statement | Note | +| :-----------------------------------------: | --------------------------------------------------------------------- | +| MOVE | Karel steps forward. | +| LEFT | Karel turns 90Β° left - note that there is no `RIGHT` :) | +| PUT | Karel puts down one beeper. | +| PICK | Karel picks up one beeper. | +| SKIP | Does nothing - like `pass` in Python. | +| IFWALL βœ“ 𐄂 | If `front_is_blocked()` then run the first procedure else the second | +| IFMARK βœ“ 𐄂 | If `beeper_is_present()` then run the first procedure else the second | -The interpret in `karel_robot.parsers.interpret` is used by the `karel` executable: +The interpret in `karel_robot.parsers.interpret` is used by the `karel` executable script: ```sh karel --program programs/graph/3_treasure.ks --map world/maze/treasure/07.km2 --speed 20 @@ -312,4 +314,4 @@ If you want to contribute, check out the `karel_robot` folder [README](karel_rob This project is released under GNU GPLv3 (or later) license in hopes that it will be useful. You are encouraged to share this *freely* and can even sell it provided everyone will still be able to read and modify -the source code, just like you are and keeps the license. :wink: +the source code (just like you are) and keeps the license. :wink: diff --git a/karel_robot/README.md b/karel_robot/README.md index 67e4707..1960302 100755 --- a/karel_robot/README.md +++ b/karel_robot/README.md @@ -16,7 +16,7 @@ def example(window): window.put_beeper() def main(): - with open("../world/1_window.km") as m: + with open("../world/1_window.km", encoding="utf8") as m: m = MapParser(lines=m, new_style_map=False) with WindowOpen( diff --git a/karel_robot/robot.py b/karel_robot/robot.py index eb252fb..945e460 100755 --- a/karel_robot/robot.py +++ b/karel_robot/robot.py @@ -20,7 +20,7 @@ as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Foobar is distributed in the hope that it will be useful, + The package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -38,6 +38,7 @@ class Point(NamedTuple): """ Better way to access 2-vector of ints, otherwise same as tuple. """ + x: int y: int diff --git a/karel_robot/tiles.py b/karel_robot/tiles.py index a0c0f5c..7a0dc67 100755 --- a/karel_robot/tiles.py +++ b/karel_robot/tiles.py @@ -22,7 +22,7 @@ as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Foobar is distributed in the hope that it will be useful, + The package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -63,7 +63,7 @@ class Empty(Tile): blocking: bool = False def __str__(self): - return '.' + return "." def __repr__(self): return "Empty()" diff --git a/karel_robot/window.py b/karel_robot/window.py index fd17428..5c5a2cf 100755 --- a/karel_robot/window.py +++ b/karel_robot/window.py @@ -20,7 +20,7 @@ as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - Foobar is distributed in the hope that it will be useful, + The package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. @@ -61,6 +61,7 @@ class Window(BoardView): class Colors: """ Curses colors for printing in terminal. """ + # TODO: rename to actual colors? wall: int empty: int karel: int @@ -322,7 +323,10 @@ def message(self, text: str, color: int = None, pause: bool = False): text = text + " Press any key to continue" self.message_win.insertln() if text: - self.message_win.addstr(0, 0, text[: self.x_screen], color) + text = ( + text if len(text) < self.x_screen else text[: self.x_screen - 4] + "..." + ) + self.message_win.addstr(0, 0, text, color) self.message_win.refresh() if pause: handle = self.handle.copy() diff --git a/programs/oop.py b/programs/oop.py index 182d6a5..48b07d7 100755 --- a/programs/oop.py +++ b/programs/oop.py @@ -18,8 +18,8 @@ def main(): Also it might just be safer then leaving it to Python garbage collector ;) """ - with open("../world/1_window.km") as m: - m = MapParser(lines=m, new_style_map=True) + with open("../world/1_window.km", encoding="utf8") as m: + m = MapParser(lines=m, new_style_map=False) with WindowOpen( karel=m.karel, tiles=m.karel_map, x_map=m.width, y_map=m.height diff --git a/setup.py b/setup.py index dcd66db..2b56cbe 100755 --- a/setup.py +++ b/setup.py @@ -4,14 +4,14 @@ """ import setuptools -with open("README.md", "r") as fh: +with open("README.md", "r", encoding="utf8") as fh: long_description = fh.read().replace( - "images", "https://github.com/xsebek/karel/blob/master/images" + "images/", "https://raw.githubusercontent.com/xsebek/karel/master/images/" ) setuptools.setup( name="karel_robot", - version="1.0.1", + version="1.1.0", author="OndΕ™ej Ε ebek", author_email="xsebek@fi.muni.cz", description="Karel the Robot simple library and interactive executable", @@ -28,5 +28,8 @@ "Intended Audience :: Education ", ], python_requires=">=3.6", + install_requires=[ + "windows-curses >= 2.2; platform_system=='Windows'" + ], entry_points={"console_scripts": ["karel=karel_robot.run.main:main"]}, )