diff --git a/dungeonbattle/interfaces.py b/dungeonbattle/interfaces.py index 7824134..5823352 100644 --- a/dungeonbattle/interfaces.py +++ b/dungeonbattle/interfaces.py @@ -1,7 +1,12 @@ #!/usr/bin/env python +from enum import Enum class Map: + """ + Object that represents a Map with its width, height + and the whole tiles, with their custom properties. + """ width: int height: int tiles: list @@ -14,17 +19,48 @@ class Map: @staticmethod def load(filename: str): + """ + Read a file that contains the content of a map, and build a Map object. + """ with open(filename, "r") as f: file = f.read() return Map.load_from_string(file) @staticmethod def load_from_string(content: str): + """ + Load a map represented by its characters and build a Map object. + """ lines = content.split("\n") lines = [line for line in lines if line] height = len(lines) width = len(lines[0]) - return Map(width, height, lines, []) + tiles = [[Tile(c) + for x, c in enumerate(line)] for y, line in enumerate(lines)] + return Map(width, height, tiles, []) + + def draw_string(self) -> str: + """ + Draw the current map as a string object that can be rendered + in the window. + """ + return "\n".join("".join(tile.value for tile in line) + for line in self.tiles) + + +class Tile(Enum): + EMPTY = ' ' + WALL = '█' + FLOOR = '.' + + def is_wall(self) -> bool: + return self == Tile.WALL + + def can_walk(self) -> bool: + """ + Check if an entity (player or not) can move in this tile. + """ + return not self.is_wall() class Entity: diff --git a/dungeonbattle/interfaces_test.py b/dungeonbattle/interfaces_test.py index 479a9ac..849e28b 100644 --- a/dungeonbattle/interfaces_test.py +++ b/dungeonbattle/interfaces_test.py @@ -5,7 +5,10 @@ from dungeonbattle.interfaces import Map class TestInterfaces(unittest.TestCase): def test_map(self) -> None: - m = Map.load_from_string("ab\ncd\n") + """ + Create a map and check that it is well parsed. + """ + m = Map.load_from_string(".█\n█.\n") self.assertEqual(m.width, 2) self.assertEqual(m.height, 2) - self.assertEqual(m.draw_string(), "ab\ncd") + self.assertEqual(m.draw_string(), ".█\n█.") diff --git a/dungeonbattle/proof_of_concept.py b/dungeonbattle/proof_of_concept.py new file mode 100644 index 0000000..9bd2dea --- /dev/null +++ b/dungeonbattle/proof_of_concept.py @@ -0,0 +1,45 @@ +from .interfaces import Map, Tile +from .term_manager import TermManager + + +def proof_of_concept() -> None: + """ + Read an example map, parse it, then the (squirrel) player can move freely. + """ + # Load the example map + m = Map.load("example_map.txt") + + # Create the context manager to manipulate the screen + with TermManager() as term_manager: + stdscr = term_manager.screen + + # Draw the full map + stdscr.addstr(0, 0, m.draw_string()) + stdscr.refresh() + + cur = [1, 6] # (y,x) + # We are a squirrel + stdscr.addstr(1, 6, '🐿') + stdscr.refresh() + + while True: + # Get movements of the user + key = stdscr.getkey() + stdscr.addstr(cur[0], cur[1], Tile.FLOOR.value) + next_pos = cur[:] + if key == 'z' or key == 'KEY_UP': + next_pos[0] = cur[0] - 1 + if key == 's' or key == 'KEY_DOWN': + next_pos[0] = cur[0] + 1 + if key == 'q' or key == 'KEY_LEFT': + next_pos[1] = cur[1] - 1 + if key == 'd' or key == 'KEY_RIGHT': + next_pos[1] = cur[1] + 1 + # Check if we stay in the bounds + if 0 <= next_pos[0] < m.height and 0 <= next_pos[0] < m.width: + next_tile = m.tiles[next_pos[0]][next_pos[1]] + # Check if the new position is valid + if next_tile.can_walk(): + cur = next_pos + # Draw the squirrel + stdscr.addstr(cur[0], cur[1], '🐿') diff --git a/example_map.txt b/example_map.txt new file mode 100644 index 0000000..bc0c464 --- /dev/null +++ b/example_map.txt @@ -0,0 +1,17 @@ + ███████ █████████████ + █.....█ █...........█ + █.....█ █████...........█ + █.....█ █...............█ + █.█████ █.███...........█ + █.█ █.█ █...........█ + █.█ █.█ █████████████ + █.█ █.█ + █.████ █.█ + █....█ █.█ + ████.███████████████████.█ + █.....................█ █████████████████ + █.....................█ █...............█ + █.....................███████...............█ + █...........................................█ + █.....................███████...............█ + ███████████████████████ █████████████████ diff --git a/main.py b/main.py old mode 100644 new mode 100755 index 1158de2..0eb26bf --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +from dungeonbattle.proof_of_concept import proof_of_concept if __name__ == "__main__": - print("Hello world!") + proof_of_concept()