Merge remote-tracking branch 'origin/master' into display
# Conflicts: # dungeonbattle/entities/player.py # dungeonbattle/game.py # dungeonbattle/interfaces.py # dungeonbattle/mapdisplay.py # dungeonbattle/settings.py # dungeonbattle/tests/settings_test.py # dungeonbattle/texturepack.py
This commit is contained in:
		@@ -1,33 +1,36 @@
 | 
			
		||||
from ..interfaces import Entity, FightingEntity
 | 
			
		||||
from ..interfaces import Entity, FightingEntity, Map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Item(Entity):
 | 
			
		||||
    held:bool
 | 
			
		||||
    held: bool
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(self, *args, **kwargs)
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.held = False
 | 
			
		||||
    
 | 
			
		||||
    def drop(self, x:int, y:int):
 | 
			
		||||
 | 
			
		||||
    def drop(self, y: int, x: int) -> None:
 | 
			
		||||
        self.held = False
 | 
			
		||||
        self.move(x, y)
 | 
			
		||||
    
 | 
			
		||||
    def hold(self):
 | 
			
		||||
        self.move(y, x)
 | 
			
		||||
 | 
			
		||||
    def hold(self) -> None:
 | 
			
		||||
        self.held = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Bomb(Item):
 | 
			
		||||
    damage:int = 5
 | 
			
		||||
    exploding:bool
 | 
			
		||||
    damage: int = 5
 | 
			
		||||
    exploding: bool
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super().__init__(self, *args, **kwargs)
 | 
			
		||||
        super().__init__(*args, **kwargs)
 | 
			
		||||
        self.exploding = False
 | 
			
		||||
 | 
			
		||||
    def drop(self, x:int, y:int):
 | 
			
		||||
        super.drop(self, x, y)
 | 
			
		||||
    def drop(self, x: int, y: int) -> None:
 | 
			
		||||
        super().drop(x, y)
 | 
			
		||||
        self.exploding = True
 | 
			
		||||
    
 | 
			
		||||
    def act(self, map):
 | 
			
		||||
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        if self.exploding:
 | 
			
		||||
            for e in map.entities:
 | 
			
		||||
                if abs (e.x - self.x) + abs (e.y - self.y) <= 1 and isinstance(e,FightingEntity):
 | 
			
		||||
            for e in m.entities:
 | 
			
		||||
                if abs(e.x - self.x) + abs(e.y - self.y) <= 1 and \
 | 
			
		||||
                        isinstance(e, FightingEntity):
 | 
			
		||||
                    e.take_damage(self, self.damage)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,11 @@
 | 
			
		||||
from ..interfaces import FightingEntity
 | 
			
		||||
from ..interfaces import FightingEntity, Map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Monster(FightingEntity):
 | 
			
		||||
    def act(self, map):
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Squirrel(Monster):
 | 
			
		||||
    maxhealth = 10
 | 
			
		||||
    strength = 3
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,22 @@
 | 
			
		||||
from ..interfaces import FightingEntity
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Player(FightingEntity):
 | 
			
		||||
    maxhealth = 20
 | 
			
		||||
    strength = 5
 | 
			
		||||
 | 
			
		||||
    def move_up(self) -> bool:
 | 
			
		||||
        return self.check_move(self.y - 1, self.x, True)
 | 
			
		||||
 | 
			
		||||
    def move_down(self) -> bool:
 | 
			
		||||
        return self.check_move(self.y + 1, self.x, True)
 | 
			
		||||
 | 
			
		||||
    def move_left(self) -> bool:
 | 
			
		||||
        return self.check_move(self.y, self.x - 1, True)
 | 
			
		||||
 | 
			
		||||
    def move_right(self) -> bool:
 | 
			
		||||
        return self.check_move(self.y, self.x + 1, True)
 | 
			
		||||
 | 
			
		||||
    currentXP: int
 | 
			
		||||
    maxXP: int
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,71 +1,94 @@
 | 
			
		||||
import sys
 | 
			
		||||
from typing import Any
 | 
			
		||||
 | 
			
		||||
from .entities.player import Player
 | 
			
		||||
from .interfaces import Map
 | 
			
		||||
from .mapdisplay import MapDisplay
 | 
			
		||||
from .settings import Settings
 | 
			
		||||
from .term_manager import TermManager
 | 
			
		||||
from enum import Enum, auto
 | 
			
		||||
from . import menus
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class GameMode(Enum):
 | 
			
		||||
    MAINMENU = auto()
 | 
			
		||||
    PLAY = auto()
 | 
			
		||||
    SETTINGS = auto()
 | 
			
		||||
    INVENTORY = auto()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class KeyValues(Enum):
 | 
			
		||||
    UP = auto()
 | 
			
		||||
    DOWN = auto()
 | 
			
		||||
    LEFT = auto()
 | 
			
		||||
    RIGHT = auto()
 | 
			
		||||
    ENTER = auto()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Game:
 | 
			
		||||
    INSTANCE = None
 | 
			
		||||
 | 
			
		||||
    def init(self) -> None:
 | 
			
		||||
        Game.INSTANCE = self
 | 
			
		||||
    def __init__(self) -> None:
 | 
			
		||||
        self.state = GameMode.MAINMENU
 | 
			
		||||
        self.main_menu = menus.MainMenu()
 | 
			
		||||
        self.settings = Settings()
 | 
			
		||||
        self.settings.load_settings()
 | 
			
		||||
        self.settings.write_settings()
 | 
			
		||||
        self.key_handler = self.player_move
 | 
			
		||||
 | 
			
		||||
    def new_game(self):
 | 
			
		||||
    def new_game(self, init_pad: bool = True) -> None:
 | 
			
		||||
        # TODO generate a new map procedurally
 | 
			
		||||
        self.m = Map.load("example_map.txt")
 | 
			
		||||
        self.d = MapDisplay(self.m)
 | 
			
		||||
        self.player = Player()
 | 
			
		||||
        self.player.y = 1
 | 
			
		||||
        self.player.x = 6
 | 
			
		||||
        self.player.move(1, 6)
 | 
			
		||||
        self.m.add_entity(self.player)
 | 
			
		||||
        self.d = MapDisplay(self.m, self.player, init_pad)
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def load_game(filename):
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def load_game(filename: str) -> None:
 | 
			
		||||
        # TODO loading map from a file
 | 
			
		||||
        raise NotImplementedError()
 | 
			
		||||
 | 
			
		||||
    def run(self, screen):
 | 
			
		||||
    def run(self, screen: Any) -> None:
 | 
			
		||||
        while True:
 | 
			
		||||
            screen.clear()
 | 
			
		||||
            screen.refresh()
 | 
			
		||||
            self.d.display(self.player.getPosY(), self.player.getPosX())
 | 
			
		||||
            self.d.display(self.player.y, self.player.x)
 | 
			
		||||
            key = screen.getkey()
 | 
			
		||||
            self.key_handler(key)
 | 
			
		||||
            self.handle_key_pressed(self.translate_key(key))
 | 
			
		||||
 | 
			
		||||
    def player_move(self, key):
 | 
			
		||||
        # TODO load keys from settings
 | 
			
		||||
        if key == 'z' or key == 'KEY_UP':
 | 
			
		||||
            self.player.move_up()
 | 
			
		||||
        if key == 's' or key == 'KEY_DOWN':
 | 
			
		||||
            self.player.move_down()
 | 
			
		||||
        if key == 'q' or key == 'KEY_LEFT':
 | 
			
		||||
            self.player.move_left()
 | 
			
		||||
        if key == 'd' or key == 'KEY_RIGHT':
 | 
			
		||||
            self.player.move_right()
 | 
			
		||||
    def translate_key(self, key: str) -> KeyValues:
 | 
			
		||||
        if key in (self.settings.KEY_DOWN_SECONDARY,
 | 
			
		||||
                   self.settings.KEY_DOWN_PRIMARY):
 | 
			
		||||
            return KeyValues.DOWN
 | 
			
		||||
        elif key in (self.settings.KEY_LEFT_PRIMARY,
 | 
			
		||||
                     self.settings.KEY_LEFT_SECONDARY):
 | 
			
		||||
            return KeyValues.LEFT
 | 
			
		||||
        elif key in (self.settings.KEY_RIGHT_PRIMARY,
 | 
			
		||||
                     self.settings.KEY_RIGHT_SECONDARY):
 | 
			
		||||
            return KeyValues.RIGHT
 | 
			
		||||
        elif key in (self.settings.KEY_UP_PRIMARY,
 | 
			
		||||
                     self.settings.KEY_UP_SECONDARY):
 | 
			
		||||
            return KeyValues.UP
 | 
			
		||||
        elif key == self.settings.KEY_ENTER:
 | 
			
		||||
            return KeyValues.ENTER
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Player:
 | 
			
		||||
    # FIXME Should be elsewhere, only useful to don't break the previous code
 | 
			
		||||
    y: int = 0
 | 
			
		||||
    x: int = 0
 | 
			
		||||
 | 
			
		||||
    def move_up(self):
 | 
			
		||||
        self.y -= 1
 | 
			
		||||
 | 
			
		||||
    def move_down(self):
 | 
			
		||||
        self.y += 1
 | 
			
		||||
 | 
			
		||||
    def move_left(self):
 | 
			
		||||
        self.x -= 1
 | 
			
		||||
 | 
			
		||||
    def move_right(self):
 | 
			
		||||
        self.x += 1
 | 
			
		||||
 | 
			
		||||
    def getPosX(self):
 | 
			
		||||
        return self.x
 | 
			
		||||
 | 
			
		||||
    def getPosY(self):
 | 
			
		||||
        return self.y
 | 
			
		||||
    def handle_key_pressed(self, key: KeyValues) -> None:
 | 
			
		||||
        if self.state == GameMode.PLAY:
 | 
			
		||||
            if key == KeyValues.UP:
 | 
			
		||||
                self.player.move_up()
 | 
			
		||||
            if key == KeyValues.DOWN:
 | 
			
		||||
                self.player.move_down()
 | 
			
		||||
            if key == KeyValues.LEFT:
 | 
			
		||||
                self.player.move_left()
 | 
			
		||||
            if key == KeyValues.RIGHT:
 | 
			
		||||
                self.player.move_right()
 | 
			
		||||
        if self.state == GameMode.MAINMENU:
 | 
			
		||||
            if key == KeyValues.DOWN:
 | 
			
		||||
                self.main_menu.go_down()
 | 
			
		||||
            if key == KeyValues.UP:
 | 
			
		||||
                self.main_menu.go_up()
 | 
			
		||||
            if key == KeyValues.ENTER:
 | 
			
		||||
                option = self.main_menu.validate()
 | 
			
		||||
                if option == menus.MainMenuValues.START:
 | 
			
		||||
                    self.state = GameMode.PLAY
 | 
			
		||||
                elif option == menus.MainMenuValues.SETTINGS:
 | 
			
		||||
                    self.state = GameMode.SETTINGS
 | 
			
		||||
                elif option == menus.MainMenuValues.EXIT:
 | 
			
		||||
                    sys.exit(0)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,13 +13,20 @@ class Map:
 | 
			
		||||
    height: int
 | 
			
		||||
    tiles: list
 | 
			
		||||
    currentx : int #coordinates of the point that should be on the topleft corner of the screen
 | 
			
		||||
    currenty : int 
 | 
			
		||||
    currenty : int
 | 
			
		||||
 | 
			
		||||
    def __init__(self, width: int, height: int, tiles: list, entities = []):
 | 
			
		||||
    def __init__(self, width: int, height: int, tiles: list):
 | 
			
		||||
        self.width = width
 | 
			
		||||
        self.height = height
 | 
			
		||||
        self.tiles = tiles
 | 
			
		||||
        self.entities = entities
 | 
			
		||||
        self.entities = []
 | 
			
		||||
 | 
			
		||||
    def add_entity(self, entity: "Entity") -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Register a new entity in the map.
 | 
			
		||||
        """
 | 
			
		||||
        self.entities.append(entity)
 | 
			
		||||
        entity.map = self
 | 
			
		||||
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def load(filename: str):
 | 
			
		||||
@@ -42,8 +49,7 @@ class Map:
 | 
			
		||||
        tiles = [[Tile(c)
 | 
			
		||||
                  for x, c in enumerate(line)] for y, line in enumerate(lines)]
 | 
			
		||||
 | 
			
		||||
        return Map(width, height, tiles, [])
 | 
			
		||||
 | 
			
		||||
        return Map(width, height, tiles)
 | 
			
		||||
 | 
			
		||||
    def draw_string(self, pack: TexturePack) -> str:
 | 
			
		||||
        """
 | 
			
		||||
@@ -73,21 +79,39 @@ class Tile(Enum):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Entity:
 | 
			
		||||
    x: int
 | 
			
		||||
    y: int
 | 
			
		||||
    x: int
 | 
			
		||||
    name : str
 | 
			
		||||
    map: Map
 | 
			
		||||
 | 
			
		||||
    def move(self, x: int, y: int) -> None:
 | 
			
		||||
        self.x = x
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.y = 0
 | 
			
		||||
        self.x = 0
 | 
			
		||||
 | 
			
		||||
    def check_move(self, y: int, x: int, move_if_possible: bool = False)\
 | 
			
		||||
            -> bool:
 | 
			
		||||
        tile = self.map.tiles[y][x]
 | 
			
		||||
        if tile.can_walk() and move_if_possible:
 | 
			
		||||
            self.move(y, x)
 | 
			
		||||
        return tile.can_walk()
 | 
			
		||||
 | 
			
		||||
    def move(self, y: int, x: int) -> None:
 | 
			
		||||
        self.y = y
 | 
			
		||||
    
 | 
			
		||||
    def act(self, m:Map):
 | 
			
		||||
        self.x = x
 | 
			
		||||
 | 
			
		||||
    def act(self, m: Map) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Define the action of the entity that is ran each tick.
 | 
			
		||||
        By default, does nothing.
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FightingEntity(Entity):
 | 
			
		||||
    maxhealth: int
 | 
			
		||||
    health: int
 | 
			
		||||
    strength: int
 | 
			
		||||
    dead: bool
 | 
			
		||||
    intelligence: int
 | 
			
		||||
    charisma: int
 | 
			
		||||
    dexterity: int
 | 
			
		||||
@@ -95,15 +119,17 @@ class FightingEntity(Entity):
 | 
			
		||||
    level: int
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.health = self.maxhealth
 | 
			
		||||
        self.dead = False
 | 
			
		||||
 | 
			
		||||
    def hit(self, opponent) -> None:
 | 
			
		||||
    def hit(self, opponent: "FightingEntity") -> None:
 | 
			
		||||
        opponent.take_damage(self, self.strength)
 | 
			
		||||
    
 | 
			
		||||
    def take_damage(self, attacker, amount:int) -> None:
 | 
			
		||||
 | 
			
		||||
    def take_damage(self, attacker: "Entity", amount: int) -> None:
 | 
			
		||||
        self.health -= amount
 | 
			
		||||
        if self.health <= 0:
 | 
			
		||||
            self.die()
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    def die(self) -> None:
 | 
			
		||||
       pass 
 | 
			
		||||
        self.dead = True
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
from dungeonbattle.interfaces import Map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestInterfaces(unittest.TestCase):
 | 
			
		||||
    def test_map(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        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(), ".█\n█.")
 | 
			
		||||
							
								
								
									
										34
									
								
								dungeonbattle/mapdisplay.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								dungeonbattle/mapdisplay.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
#!/usr/bin/env python
 | 
			
		||||
import curses
 | 
			
		||||
 | 
			
		||||
from dungeonbattle.entities.player import Player
 | 
			
		||||
from dungeonbattle.interfaces import Map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MapDisplay:
 | 
			
		||||
    def __init__(self, m: Map, player: Player, init_pad: bool = True):
 | 
			
		||||
        self.map = m
 | 
			
		||||
        self.player = player
 | 
			
		||||
        if init_pad:
 | 
			
		||||
            self.pad = curses.newpad(m.height, m.width + 1)
 | 
			
		||||
 | 
			
		||||
    def update_pad(self) -> None:
 | 
			
		||||
        self.pad.addstr(0, 0, self.map.draw_string())
 | 
			
		||||
        # TODO Not all entities should be a player
 | 
			
		||||
        for e in self.map.entities:
 | 
			
		||||
            self.pad.addstr(e.y, e.x, '🐿')
 | 
			
		||||
 | 
			
		||||
    def display(self, y: int, x: int) -> None:
 | 
			
		||||
        deltay, deltax = (curses.LINES // 2) + 1, (curses.COLS // 2) + 1
 | 
			
		||||
        pminrow, pmincol = y - deltay, x - deltax
 | 
			
		||||
        sminrow, smincol = max(-pminrow, 0), max(-pmincol, 0)
 | 
			
		||||
        deltay, deltax = curses.LINES - deltay, curses.COLS - deltax
 | 
			
		||||
        smaxrow = self.map.height - (y + deltay) + curses.LINES - 1
 | 
			
		||||
        smaxrow = min(smaxrow, curses.LINES - 1)
 | 
			
		||||
        smaxcol = self.map.width - (x + deltax) + curses.COLS - 1
 | 
			
		||||
        smaxcol = min(smaxcol, curses.COLS - 1)
 | 
			
		||||
        pminrow = max(0, min(self.map.height, pminrow))
 | 
			
		||||
        pmincol = max(0, min(self.map.width, pmincol))
 | 
			
		||||
        self.pad.clear()
 | 
			
		||||
        self.update_pad()
 | 
			
		||||
        self.pad.refresh(pminrow, pmincol, sminrow, smincol, smaxrow, smaxcol)
 | 
			
		||||
							
								
								
									
										34
									
								
								dungeonbattle/menus.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								dungeonbattle/menus.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
from enum import Enum, auto
 | 
			
		||||
from typing import Any
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Menu:
 | 
			
		||||
    values: list
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.position = 0
 | 
			
		||||
 | 
			
		||||
    def go_up(self) -> None:
 | 
			
		||||
        self.position = max(0, self.position - 1)
 | 
			
		||||
 | 
			
		||||
    def go_down(self) -> None:
 | 
			
		||||
        self.position = min(len(self.values) - 1, self.position + 1)
 | 
			
		||||
 | 
			
		||||
    def validate(self) -> Any:
 | 
			
		||||
        return self.values[self.position]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MainMenuValues(Enum):
 | 
			
		||||
    START = auto()
 | 
			
		||||
    SETTINGS = auto()
 | 
			
		||||
    EXIT = auto()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MainMenu(Menu):
 | 
			
		||||
    values = [e for e in MainMenuValues]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ArbitraryMenu(Menu):
 | 
			
		||||
    def __init__(self, values: list):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
        self.values = values
 | 
			
		||||
@@ -11,14 +11,24 @@ class Settings:
 | 
			
		||||
    We can define the setting by simply use settings.TEXTURE_PACK = 'new_key'
 | 
			
		||||
    """
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.KEY_UP_PRIMARY = ['z', 'Touche principale pour aller vers le haut']
 | 
			
		||||
        self.KEY_UP_SECONDARY = ['KEY_UP', 'Touche secondaire pour aller vers le haut']
 | 
			
		||||
        self.KEY_DOWN_PRIMARY = ['s', 'Touche principale pour aller vers le bas']
 | 
			
		||||
        self.KEY_DOWN_SECONDARY = ['KEY_DOWN', 'Touche secondaire pour aller vers le bas']
 | 
			
		||||
        self.KEY_LEFT_PRIMARY = ['q', 'Touche principale pour aller vers la gauche']
 | 
			
		||||
        self.KEY_LEFT_SECONDARY = ['KEY_LEFT', 'Touche secondaire pour aller vers la gauche']
 | 
			
		||||
        self.KEY_RIGHT_PRIMARY = ['d', 'Touche principale pour aller vers la droite']
 | 
			
		||||
        self.KEY_RIGHT_SECONDARY = ['KEY_RIGHT', 'Touche secondaire pour aller vers la droite']
 | 
			
		||||
        self.KEY_UP_PRIMARY = \
 | 
			
		||||
            ['z', 'Touche principale pour aller vers le haut']
 | 
			
		||||
        self.KEY_UP_SECONDARY = \
 | 
			
		||||
            ['KEY_UP', 'Touche secondaire pour aller vers le haut']
 | 
			
		||||
        self.KEY_DOWN_PRIMARY = \
 | 
			
		||||
            ['s', 'Touche principale pour aller vers le bas']
 | 
			
		||||
        self.KEY_DOWN_SECONDARY = \
 | 
			
		||||
            ['KEY_DOWN', 'Touche secondaire pour aller vers le bas']
 | 
			
		||||
        self.KEY_LEFT_PRIMARY = \
 | 
			
		||||
            ['q', 'Touche principale pour aller vers la gauche']
 | 
			
		||||
        self.KEY_LEFT_SECONDARY = \
 | 
			
		||||
            ['KEY_LEFT', 'Touche secondaire pour aller vers la gauche']
 | 
			
		||||
        self.KEY_RIGHT_PRIMARY = \
 | 
			
		||||
            ['d', 'Touche principale pour aller vers la droite']
 | 
			
		||||
        self.KEY_RIGHT_SECONDARY = \
 | 
			
		||||
            ['KEY_RIGHT', 'Touche secondaire pour aller vers la droite']
 | 
			
		||||
        self.KEY_ENTER = \
 | 
			
		||||
            ['\n', 'Touche pour valider un menu']
 | 
			
		||||
        self.TEXTURE_PACK = ['ascii', 'Pack de textures utilisé']
 | 
			
		||||
 | 
			
		||||
    def __getattribute__(self, item: str) -> Any:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										0
									
								
								dungeonbattle/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								dungeonbattle/tests/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										97
									
								
								dungeonbattle/tests/entities_test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								dungeonbattle/tests/entities_test.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
from dungeonbattle.entities.items import Bomb, Item
 | 
			
		||||
from dungeonbattle.entities.monsters import Squirrel
 | 
			
		||||
from dungeonbattle.entities.player import Player
 | 
			
		||||
from dungeonbattle.interfaces import Entity, Map
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestEntities(unittest.TestCase):
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Load example map that can be used in tests.
 | 
			
		||||
        """
 | 
			
		||||
        self.map = Map.load("example_map.txt")
 | 
			
		||||
 | 
			
		||||
    def test_basic_entities(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with basic entities.
 | 
			
		||||
        """
 | 
			
		||||
        entity = Entity()
 | 
			
		||||
        entity.move(42, 64)
 | 
			
		||||
        self.assertEqual(entity.y, 42)
 | 
			
		||||
        self.assertEqual(entity.x, 64)
 | 
			
		||||
        self.assertIsNone(entity.act(self.map))
 | 
			
		||||
 | 
			
		||||
    def test_fighting_entities(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with fighting entities.
 | 
			
		||||
        """
 | 
			
		||||
        entity = Squirrel()
 | 
			
		||||
        self.assertIsNone(entity.act(self.map))
 | 
			
		||||
        self.assertEqual(entity.maxhealth, 10)
 | 
			
		||||
        self.assertEqual(entity.maxhealth, entity.health)
 | 
			
		||||
        self.assertEqual(entity.strength, 3)
 | 
			
		||||
        self.assertIsNone(entity.hit(entity))
 | 
			
		||||
        self.assertFalse(entity.dead)
 | 
			
		||||
        self.assertIsNone(entity.hit(entity))
 | 
			
		||||
        self.assertFalse(entity.dead)
 | 
			
		||||
        self.assertIsNone(entity.hit(entity))
 | 
			
		||||
        self.assertFalse(entity.dead)
 | 
			
		||||
        self.assertIsNone(entity.hit(entity))
 | 
			
		||||
        self.assertTrue(entity.dead)
 | 
			
		||||
 | 
			
		||||
    def test_items(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with items.
 | 
			
		||||
        """
 | 
			
		||||
        item = Item()
 | 
			
		||||
        self.assertFalse(item.held)
 | 
			
		||||
        item.hold()
 | 
			
		||||
        self.assertTrue(item.held)
 | 
			
		||||
        item.drop(42, 42)
 | 
			
		||||
        self.assertEqual(item.y, 42)
 | 
			
		||||
        self.assertEqual(item.x, 42)
 | 
			
		||||
 | 
			
		||||
    def test_bombs(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with bombs.
 | 
			
		||||
        """
 | 
			
		||||
        item = Bomb()
 | 
			
		||||
        squirrel = Squirrel()
 | 
			
		||||
        self.map.add_entity(item)
 | 
			
		||||
        self.map.add_entity(squirrel)
 | 
			
		||||
        squirrel.health = 2
 | 
			
		||||
        squirrel.move(41, 42)
 | 
			
		||||
        item.act(self.map)
 | 
			
		||||
        self.assertFalse(squirrel.dead)
 | 
			
		||||
        item.drop(42, 42)
 | 
			
		||||
        self.assertEqual(item.y, 42)
 | 
			
		||||
        self.assertEqual(item.x, 42)
 | 
			
		||||
        item.act(self.map)
 | 
			
		||||
        self.assertTrue(squirrel.dead)
 | 
			
		||||
 | 
			
		||||
    def test_players(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some random stuff with players.
 | 
			
		||||
        """
 | 
			
		||||
        player = Player()
 | 
			
		||||
        self.map.add_entity(player)
 | 
			
		||||
        player.move(1, 6)
 | 
			
		||||
        self.assertEqual(player.strength, 5)
 | 
			
		||||
        self.assertEqual(player.health, player.maxhealth)
 | 
			
		||||
        self.assertEqual(player.maxhealth, 20)
 | 
			
		||||
 | 
			
		||||
        # Test movements and ensure that collisions are working
 | 
			
		||||
        self.assertFalse(player.move_up())
 | 
			
		||||
        self.assertTrue(player.move_left())
 | 
			
		||||
        self.assertFalse(player.move_left())
 | 
			
		||||
        for i in range(8):
 | 
			
		||||
            self.assertTrue(player.move_down())
 | 
			
		||||
        self.assertFalse(player.move_down())
 | 
			
		||||
        self.assertTrue(player.move_right())
 | 
			
		||||
        self.assertTrue(player.move_right())
 | 
			
		||||
        self.assertTrue(player.move_right())
 | 
			
		||||
        self.assertFalse(player.move_right())
 | 
			
		||||
        self.assertTrue(player.move_down())
 | 
			
		||||
        self.assertTrue(player.move_down())
 | 
			
		||||
							
								
								
									
										97
									
								
								dungeonbattle/tests/game_test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								dungeonbattle/tests/game_test.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
from dungeonbattle.game import Game, KeyValues, GameMode
 | 
			
		||||
from dungeonbattle.menus import MainMenuValues
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestGame(unittest.TestCase):
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Setup game.
 | 
			
		||||
        """
 | 
			
		||||
        self.game = Game()
 | 
			
		||||
        self.game.new_game(False)
 | 
			
		||||
 | 
			
		||||
    def test_load_game(self) -> None:
 | 
			
		||||
        self.assertRaises(NotImplementedError, Game.load_game, "game.save")
 | 
			
		||||
 | 
			
		||||
    def test_key_translation(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test key bindings.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_UP_PRIMARY), KeyValues.UP)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_UP_SECONDARY), KeyValues.UP)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_DOWN_PRIMARY), KeyValues.DOWN)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_DOWN_SECONDARY), KeyValues.DOWN)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_LEFT_PRIMARY), KeyValues.LEFT)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_LEFT_SECONDARY), KeyValues.LEFT)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_RIGHT_PRIMARY), KeyValues.RIGHT)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_RIGHT_SECONDARY), KeyValues.RIGHT)
 | 
			
		||||
        self.assertEqual(self.game.translate_key(
 | 
			
		||||
            self.game.settings.KEY_ENTER), KeyValues.ENTER)
 | 
			
		||||
 | 
			
		||||
    def test_key_press(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Press a key and see what is done.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertEqual(self.game.state, GameMode.MAINMENU)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
                         MainMenuValues.START)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.UP)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
                         MainMenuValues.START)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.DOWN)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
                         MainMenuValues.SETTINGS)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.ENTER)
 | 
			
		||||
        self.assertEqual(self.game.state, GameMode.SETTINGS)
 | 
			
		||||
 | 
			
		||||
        self.game.state = GameMode.MAINMENU
 | 
			
		||||
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.DOWN)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
                         MainMenuValues.EXIT)
 | 
			
		||||
        self.assertRaises(SystemExit, self.game.handle_key_pressed,
 | 
			
		||||
                          KeyValues.ENTER)
 | 
			
		||||
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.UP)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
                         MainMenuValues.SETTINGS)
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.UP)
 | 
			
		||||
        self.assertEqual(self.game.main_menu.validate(),
 | 
			
		||||
                         MainMenuValues.START)
 | 
			
		||||
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.ENTER)
 | 
			
		||||
        self.assertEqual(self.game.state, GameMode.PLAY)
 | 
			
		||||
 | 
			
		||||
        y, x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.DOWN)
 | 
			
		||||
        new_y, new_x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.assertEqual(new_y, y + 1)
 | 
			
		||||
        self.assertEqual(new_x, x)
 | 
			
		||||
 | 
			
		||||
        y, x = new_y, new_x
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.RIGHT)
 | 
			
		||||
        new_y, new_x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.assertEqual(new_y, y)
 | 
			
		||||
        self.assertEqual(new_x, x + 1)
 | 
			
		||||
 | 
			
		||||
        y, x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.UP)
 | 
			
		||||
        new_y, new_x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.assertEqual(new_y, y - 1)
 | 
			
		||||
        self.assertEqual(new_x, x)
 | 
			
		||||
 | 
			
		||||
        y, x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.game.handle_key_pressed(KeyValues.LEFT)
 | 
			
		||||
        new_y, new_x = self.game.player.y, self.game.player.x
 | 
			
		||||
        self.assertEqual(new_y, y)
 | 
			
		||||
        self.assertEqual(new_x, x - 1)
 | 
			
		||||
							
								
								
									
										33
									
								
								dungeonbattle/tests/interfaces_test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								dungeonbattle/tests/interfaces_test.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
from dungeonbattle.interfaces import Map, Tile
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestInterfaces(unittest.TestCase):
 | 
			
		||||
    def test_map(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        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(), ".█\n█.")
 | 
			
		||||
 | 
			
		||||
    def test_load_map(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Try to load a map from a file.
 | 
			
		||||
        """
 | 
			
		||||
        m = Map.load("example_map.txt")
 | 
			
		||||
        self.assertEqual(m.width, 52)
 | 
			
		||||
        self.assertEqual(m.height, 17)
 | 
			
		||||
 | 
			
		||||
    def test_tiles(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test some things about tiles.
 | 
			
		||||
        """
 | 
			
		||||
        self.assertFalse(Tile.FLOOR.is_wall())
 | 
			
		||||
        self.assertTrue(Tile.WALL.is_wall())
 | 
			
		||||
        self.assertFalse(Tile.EMPTY.is_wall())
 | 
			
		||||
        self.assertTrue(Tile.FLOOR.can_walk())
 | 
			
		||||
        self.assertFalse(Tile.WALL.can_walk())
 | 
			
		||||
        self.assertTrue(Tile.EMPTY.can_walk())
 | 
			
		||||
							
								
								
									
										24
									
								
								dungeonbattle/tests/menus_test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								dungeonbattle/tests/menus_test.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
from dungeonbattle.menus import ArbitraryMenu, MainMenu, MainMenuValues
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestMenus(unittest.TestCase):
 | 
			
		||||
    def test_scroll_menu(self) -> None:
 | 
			
		||||
        """
 | 
			
		||||
        Test to scroll the menu.
 | 
			
		||||
        """
 | 
			
		||||
        arbitrary_menu = ArbitraryMenu([])
 | 
			
		||||
        self.assertEqual(arbitrary_menu.position, 0)
 | 
			
		||||
 | 
			
		||||
        main_menu = MainMenu()
 | 
			
		||||
        self.assertEqual(main_menu.position, 0)
 | 
			
		||||
        self.assertEqual(main_menu.validate(), MainMenuValues.START)
 | 
			
		||||
        main_menu.go_up()
 | 
			
		||||
        self.assertEqual(main_menu.validate(), MainMenuValues.START)
 | 
			
		||||
        main_menu.go_down()
 | 
			
		||||
        self.assertEqual(main_menu.validate(), MainMenuValues.SETTINGS)
 | 
			
		||||
        main_menu.go_down()
 | 
			
		||||
        self.assertEqual(main_menu.validate(), MainMenuValues.EXIT)
 | 
			
		||||
        main_menu.go_down()
 | 
			
		||||
        self.assertEqual(main_menu.validate(), MainMenuValues.EXIT)
 | 
			
		||||
@@ -18,8 +18,10 @@ class TestSettings(unittest.TestCase):
 | 
			
		||||
        self.assertEqual(settings.KEY_LEFT_SECONDARY, 'KEY_LEFT')
 | 
			
		||||
        self.assertEqual(settings.KEY_RIGHT_SECONDARY, 'KEY_RIGHT')
 | 
			
		||||
        self.assertEqual(settings.TEXTURE_PACK, 'ascii')
 | 
			
		||||
        self.assertEqual(settings.get_comment(settings.TEXTURE_PACK), settings.get_comment('TEXTURE_PACK'))
 | 
			
		||||
        self.assertEqual(settings.get_comment(settings.TEXTURE_PACK), 'Pack de textures utilisé')
 | 
			
		||||
        self.assertEqual(settings.get_comment(settings.TEXTURE_PACK),
 | 
			
		||||
                         settings.get_comment('TEXTURE_PACK'))
 | 
			
		||||
        self.assertEqual(settings.get_comment(settings.TEXTURE_PACK),
 | 
			
		||||
                         'Pack de textures utilisé')
 | 
			
		||||
 | 
			
		||||
        settings.TEXTURE_PACK = 'UNICODE'
 | 
			
		||||
        self.assertEqual(settings.TEXTURE_PACK, 'UNICODE')
 | 
			
		||||
							
								
								
									
										0
									
								
								dungeonbattle/texturepack.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								dungeonbattle/texturepack.py
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user