Merge branch 'player_move' into 'master'

Modularity on interfaces

See merge request ynerant/dungeon-battle!2
This commit is contained in:
ynerant 2020-10-16 18:31:59 +02:00
commit dd88782a4c
5 changed files with 106 additions and 4 deletions

View File

@ -1,7 +1,12 @@
#!/usr/bin/env python #!/usr/bin/env python
from enum import Enum
class Map: class Map:
"""
Object that represents a Map with its width, height
and the whole tiles, with their custom properties.
"""
width: int width: int
height: int height: int
tiles: list tiles: list
@ -14,17 +19,48 @@ class Map:
@staticmethod @staticmethod
def load(filename: str): 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: with open(filename, "r") as f:
file = f.read() file = f.read()
return Map.load_from_string(file) return Map.load_from_string(file)
@staticmethod @staticmethod
def load_from_string(content: str): def load_from_string(content: str):
"""
Load a map represented by its characters and build a Map object.
"""
lines = content.split("\n") lines = content.split("\n")
lines = [line for line in lines if line] lines = [line for line in lines if line]
height = len(lines) height = len(lines)
width = len(lines[0]) 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: class Entity:

View File

@ -5,7 +5,10 @@ from dungeonbattle.interfaces import Map
class TestInterfaces(unittest.TestCase): class TestInterfaces(unittest.TestCase):
def test_map(self) -> None: 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.width, 2)
self.assertEqual(m.height, 2) self.assertEqual(m.height, 2)
self.assertEqual(m.draw_string(), "ab\ncd") self.assertEqual(m.draw_string(), ".█\n█.")

View File

@ -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], '🐿')

17
example_map.txt Normal file
View File

@ -0,0 +1,17 @@
███████ █████████████
█.....█ █...........█
█.....█ █████...........█
█.....█ █...............█
█.█████ █.███...........█
█.█ █.█ █...........█
█.█ █.█ █████████████
█.█ █.█
█.████ █.█
█....█ █.█
████.███████████████████.█
█.....................█ █████████████████
█.....................█ █...............█
█.....................███████...............█
█...........................................█
█.....................███████...............█
███████████████████████ █████████████████

3
main.py Normal file → Executable file
View File

@ -1,4 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
from dungeonbattle.proof_of_concept import proof_of_concept
if __name__ == "__main__": if __name__ == "__main__":
print("Hello world!") proof_of_concept()