Ejemplo n.º 1
0
    def create(self):
        """ sets up game"""

        # choose number of players 1-6 start with even numbers only
        # num_players = utils.choose_number_of_players()
        # num_squads = utils.choose_number_of_squads()
        # player_squad = {}
        # for x in range(0, num_squads + 1):
        #     player = utils.choose_player(num_players + 1)
        #     squad = utils.choose_players_squads()
        #     if Player(player) in player_squad:
        #         player_squad[Player(player)].append(Main(squad))
        #     else:
        #         player_squad[Player(player)] = [Main(squad)]
        # print(player_squad)

        #board_type = utils.choose_game_board()

        # skipping the setup menus
        squads = [s_utils.setup_squad(1, Main.dooku, SqState.dark),
                  s_utils.setup_squad(2, Main.mace, SqState.light)]
        board_type = BoardType.ruins
        self.engine = Engine({'squads': squads, 'board_type': board_type})
        self.engine.num_players = 2
        self.engine.initial_placement()
        print(self.engine)
Ejemplo n.º 2
0
 def setUp(self):
     self.board = Board({})
     self.squads = [s_utils.setup_squad(1, Main.mace, SqState.light),
                    s_utils.setup_squad(2, Main.dooku, SqState.dark)]
     # s_utils.setup_squad(3, Main.mace, Square.light),
     # s_utils.setup_squad(4, Main.dooku, Square.dark)]
     self.engine = Engine({'board': self.board, 'squads': self.squads,
                           'active_char': self.squads[0].chars['main']})
     self.engine.move_char(self.squads[0].chars['main'], Pos(3, 3))
Ejemplo n.º 3
0
    def create(self):
        """ sets up game"""
        logging.info('Creating engine')

        # choose number of players 1-6 start with even numbers only
        # pick sides

        # pick squads
        # player_squad = {}
        # for x in range(0, num_squads + 1):
        #     player = utils.choose_player(num_players + 1)
        #     squad = utils.choose_players_squads()
        #     if Player(player) in player_squad:
        #         player_squad[Player(player)].append(Main(squad))
        #     else:
        #         player_squad[Player(player)] = [Main(squad)]
        # print(player_squad)

        # pick number of players
        # num_players = utils.choose_number_of_players()
        num_players = 2

        # pick number of squads
        # self.engine = utils.choose_number_of_squads()
        num_squads = 2

        # skipping the setup menus
        squads = [s_utils.setup_squad(1, Main.dooku, SqState.dark),
                  s_utils.setup_squad(2, Main.mace, SqState.light)]

        # pick boards
        # board_type = utils.choose_game_board()
        board_type = BoardType.ruins

        self.engine = Engine({'num_players': num_players,
                              'squads': squads,
                              'num_squads': len(squads),
                              'board_type': board_type})
Ejemplo n.º 4
0
        self.setMinimumSize(375, 300)
        self.populate_tabs()
        self.show()

    def populate_tabs(self):
        """Populate the tabs with squad/character information."""
        # TODO:NOT sure about saving the number of squads as a variable
        # TODO: instead of just getting len() from the squads array
        for squad in self.engine.squads:
            tab_title = "{0} {1}".format(squad.player_num, squad.chars["main"].name)
            self.addTab(SquadWidget(squad), squad.chars["main"].name)


if __name__ == "__main__":
    from pyduel_engine.content.engine_states import Action, BoardType
    from pyduel_engine.utilities import squad_utilities as s_utils
    from pyduel_engine.model.engine import Engine
    from pyduel_engine.content.engine_states import SqState as SqState

    from pyduel_engine.epic_plugin.epic_states import Main

    squads = [s_utils.setup_squad(1, Main.dooku, SqState.dark), s_utils.setup_squad(2, Main.mace, SqState.light)]
    board_type = BoardType.ruins
    engine = Engine({"squads": squads, "board_type": board_type})
    engine.num_players = 2
    engine.num_squads = len(engine.squads)
    engine.initial_placement()
    app = QtGui.QApplication(sys.argv)
    ex = SquadTabWidget(engine)
    sys.exit(app.exec_())
Ejemplo n.º 5
0
        self.VerticalLayout.addWidget(self.hand_size)
        self.VerticalLayout.addWidget(CharWidget(squad.chars['main']))
        self.VerticalLayout.addWidget(CharWidget(squad.chars['minor1']))

        if squad.chars['minor2']:
            self.VerticalLayout.addWidget(CharWidget(squad.chars['minor2']))

        # set layout
        self.setLayout(self.VerticalLayout)

        self.show()

if __name__ == "__main__":
    from pyduel_engine.content.engine_states import Action, BoardType
    from pyduel_engine.utilities import squad_utilities as s_utils
    from pyduel_engine.model.engine import Engine

    from pyduel_engine.epic_plugin.epic_states import Main

    app = QApplication(sys.argv)

    squads = [s_utils.setup_squad(1, Main.dooku, SqState.dark),
              s_utils.setup_squad(2, Main.mace, SqState.light)]
    board_type = BoardType.ruins
    engine = Engine({'squads': squads, 'board_type': board_type})
    engine.num_players = 2
    engine.initial_placement()
    print(engine.squads[0].chars['main'])
    ex = SquadWidget(engine.squads[0])
    sys.exit(app.exec_())
Ejemplo n.º 6
0
 def __init__(self):
     self.engine = Engine({})
Ejemplo n.º 7
0
class Game(object):

    def __init__(self):
        self.engine = Engine({})

    def create(self):
        """ sets up game"""
        logging.info('Creating engine')

        # choose number of players 1-6 start with even numbers only
        # pick sides

        # pick squads
        # player_squad = {}
        # for x in range(0, num_squads + 1):
        #     player = utils.choose_player(num_players + 1)
        #     squad = utils.choose_players_squads()
        #     if Player(player) in player_squad:
        #         player_squad[Player(player)].append(Main(squad))
        #     else:
        #         player_squad[Player(player)] = [Main(squad)]
        # print(player_squad)

        # pick number of players
        # num_players = utils.choose_number_of_players()
        num_players = 2

        # pick number of squads
        # self.engine = utils.choose_number_of_squads()
        num_squads = 2

        # skipping the setup menus
        squads = [s_utils.setup_squad(1, Main.dooku, SqState.dark),
                  s_utils.setup_squad(2, Main.mace, SqState.light)]

        # pick boards
        # board_type = utils.choose_game_board()
        board_type = BoardType.ruins

        self.engine = Engine({'num_players': num_players,
                              'squads': squads,
                              'num_squads': len(squads),
                              'board_type': board_type})

        # #################### Notes ###########################

    def initialize_game(self):
        """ Places Characters on the board, draws initial hands
        :return:
        """
        logging.info('Initializing Game')

        # place characters initially on the board
        self.engine.initial_placement()
        logging.info('Placed Main Characters on Board')

        # place secondary characters
        for squad in self.engine.squads:
            pos = self.engine.find_minor_placement(squad)
            # print(pos)
            shuffle(pos)
            # hard coding the first two positions for the minor chars
            self.engine.move_char(squad.chars['minor1'], pos[0])
            self.engine.move_char(squad.chars['minor2'], pos[1])

        logging.info('Placed Minor Characters on Board')

        # shuffle all decks
        self.engine.shuffle_all_decks()
        logging.info('Shuffled all decks')

    # draw default hand
        self.engine.deal_cards_to_squads()
        logging.info('Dealt Cards for initial hand to each squad')

    def start(self):
        """ Starts the game.

        :return:
        """
        logging.info('Starting Game')
        # start game loop
        print(self.engine)

        for x in range(0, 1):
            self.round()

        # while not self.engine.is_game_over():
        #     # loop into squad rounds
        #     self.round()

    def stop(self):
        logging.info('Stopping Game')
        pass

    def save(self):
        logging.info('Saving Game')
        pass

    def quit(self):
        logging.info('Quitting Game')
        pass

    def round(self):
        """ Game round
        cycle through each squad turn
        """
        logging.info('Start Round: {0}'.format(
            self.engine.round_num))
        # give every squad a turn
        for x in range(0, self.engine.num_squads):
            # loop into turns per squad
            self.turn()
            self.engine.turn += 1

        logging.info('End Round: {0} '.format(self.engine.round_num))

        # reset turn count
        self.engine.turn = 0
        # increment engine round
        self.engine.round_num += 1

    def turn(self):
        """ Game turn
        The active squad (set by turn number)
            1. Move
            2. act
        """
        logging.info('Start Turn: {0}'.format(self.engine.turn))

        logging.info("Player: {0} Char: {1} Side: {2} ".format(
            self.engine.active_squad().player_num,
            self.engine.active_squad().chars['main'].name,
            self.engine.active_squad().side.name))

        # Move Phase
        # self.move_phase()

        # Action Phase
        self.action_phase()

        # Increment engine turn
        logging.info('End Turn: {0}'.format(self.engine.turn))

    def move_phase(self):
        """ Move phase for squads
            - Based on dice roll determine if only one character
               or all characters move
            - present moveable characters along with possible moves
            - choose character(s) to move
        """
        logging.info("Start R:{0} T:{1} Move phase".format(
            self.engine.round_num, self.engine.turn))
        # do you want to move
        if not utils.choose_to_move():
            logging.info("Squad {0} chose not to move".format(
                self.engine.turn + 1))
            return

        # Dice Roll
        self.engine.dice.roll()

        # TODO: Starting and stopping mechanism for moving to the action phase

        # get active characters in squad
        active_chars = self.engine.active_squad().get_active_chars()
        # logging.debug("active characters {0}".format(active_chars))

        # get squad moves
        squad_moves = self._get_and_print_squad_moves(active_chars)

        if self.engine.dice.is_all():
            while len(active_chars) > 0:
                char_key = self._choose_character(active_chars)
                new_pos = self._choose_move(squad_moves[char_key])
                self.engine.move_char(
                    self.engine.active_squad().chars[char_key], new_pos)

        # logging.info("active characters {0}".format(squad_moves))

        logging.info("End R:{0} T:{1} Move phase".format(
            self.engine.round_num, self.engine.turn))

    def action_phase(self):
        """ Squad performs actions for squad
            Use card, draw card, discard to heal
        """
        logging.info("Start R:{0} T:{1} Action phase".format(
            self.engine.round_num, self.engine.turn))
        while self.engine.active_squad().can_act():
            logging.info("Start action")

            active_chars = self.engine.active_squad().get_active_chars()
            # active_characters = ['main', 'minor1', 'minor2']
            main_cards, minor_cards = \
                self.engine.active_squad().list_character_cards()
            # chars = {'main': Name: Count Dooku	HP: 18	Pos: (4,6),
            #  'minor1': Name: Super Battle Droid 1	HP: 5	Pos: (4,5),
            #  'minor2': Name: Super Battle Droid 2	HP: 5	Pos: (5,6)}
            print(self.engine.active_squad().hand)
            # hand = [1|4, 1|4, 2|3, 2|3]
            print(main_cards)
            print(minor_cards)
            print(self.engine.get_squad_targets())
            # TODO: check card arrays if conditions allow for use
            # attack, defend, special keys process based on that
            # attack: int, defend: int, special: effects

            possible_actions = self.engine.get_possible_actions()
            action = utils.choose_actions(possible_actions)
            # possible_targets = self.engine.get_possible_targets()
            # targets = self._text_choose_targets(possible_actions)
            # action = Action.draw
            # self.engine.active_action = action
            # if action == Action.card:
                #
                # if card.ack:
                #     get ack from target player
                # self.engine.execute_action()
            #     pass
            # else:
                # self.engine.current_action()
                # self.engine.execute_action()
                # pass

            # def squad_act(self):
            #     if self.active_squad().can_act():
            #         self.active_squad().get_possible_actions()
            #         self.active_squad().actions -= 1
            #
            # def end_turn(self):
            #     pass
            #
            # def end_action(self):
            #     self.target_char = None
            #     self.target_chars = None
            #     self.target_squad = None
            #     self.active_squad().actions -= 1


            logging.info("End Action")
            self.engine.active_squad(). actions -= 1

    def _choose_character(self, active_chars):
        """
        choose char and return char key
        """
        choice = utils.choose_character(active_chars)
        return active_chars.pop(choice)

    def _choose_move(self, positions):
        """
        """
        choice = utils.choose_move(positions)
        return positions[choice]

    def _get_and_print_squad_moves(self, active_chars):
        """ text based helper method
        the squad moves need to be refreshed with every character move
        to allow for newly vacated/occupied squares
        """
        # get squad moves
        squad_moves = self.engine.find_squad_moves(active_chars)

        # print moves
        for k, v in squad_moves.items():
            print(k, ':', v)

        return squad_moves

    def _choose_action(self, chars):
        """
        """
        char = chars.pop(utils.choose_character(chars))
        actions = self.engine.get_possible_moves()
        action = actions[utils.choose_move(actions)]
        return actions
Ejemplo n.º 8
0
 def getEngine(self):
     squads = self.squad_selector.getSquads()
     board = self.boardComboBox.getBoard()
     engine = Engine({'squads': squads, 'board_type': board})
     engine.num_players = len(engine.squads)
     return engine
Ejemplo n.º 9
0
class Game(object):

    def __init__(self):
        self.engine = None

    def create(self):
        """ sets up game"""

        # choose number of players 1-6 start with even numbers only
        # num_players = utils.choose_number_of_players()
        # num_squads = utils.choose_number_of_squads()
        # player_squad = {}
        # for x in range(0, num_squads + 1):
        #     player = utils.choose_player(num_players + 1)
        #     squad = utils.choose_players_squads()
        #     if Player(player) in player_squad:
        #         player_squad[Player(player)].append(Main(squad))
        #     else:
        #         player_squad[Player(player)] = [Main(squad)]
        # print(player_squad)

        #board_type = utils.choose_game_board()

        # skipping the setup menus
        squads = [s_utils.setup_squad(1, Main.dooku, SqState.dark),
                  s_utils.setup_squad(2, Main.mace, SqState.light)]
        board_type = BoardType.ruins
        self.engine = Engine({'squads': squads, 'board_type': board_type})
        self.engine.num_players = 2
        self.engine.initial_placement()
        print(self.engine)

    def start(self):

        print(self.engine)
        self.engine.deal_cards_to_squads()

        while not self.engine.is_game_over():
            self.round()

    def stop(self):
        pass

    def save(self):
        pass

    def quit(self):
        pass

    def round(self):
        # give every squad a turn
        for x in range(0, self.engine.num_squads):
            self.turn()
        self.engine.round_num += 1

    def turn(self):
        # Roll Phase
        self.engine.dice.roll()
        print('Roll: {0}'.format(self.engine.dice))

        # Move Phase
        moves = {'main': None, 'minor1': None, 'minor2': None}
        if self.engine.active_squad().can_move():
            possible_moves = self.engine.get_possible_moves()
            # get moves for squad from text or event
            # moves = self._text_choose_move(possible_moves)
            self.engine.move(moves)

        # Action Phase
        while self.engine.active_squad().can_act():

            possible_action = self.engine.get_possible_actions()
            # action = self._text_choose_action(possible_actions)
            possible_targets = self.engine.get_possible_targets()
            # targets = self._text_choose_targets(possible_actions)
            action = Action.draw
            self.engine.active_action = action
            if action == Action.card:
                possible_targets = self.engine.get_possible_targets()
                # if card.ack:
                #     get ack from target player
                # self.engine.execute_action()
                pass
            else:
                self.engine.current_action()
                self.engine.execute_action()
        self.engine.turn += 1

    def _text_choose_move(self, chars):
        char = chars.pop(utils.choose_character(chars))
        moves = self.engine.get_possible_moves()
        move = moves[utils.choose_move(moves)]
        return moves

    def _text_choose_action(self, chars):
        char = chars.pop(utils.choose_character(chars))
        actions = self.engine.get_possible_moves()
        action = actions[utils.choose_move(actions)]
        return actions
Ejemplo n.º 10
0
class TestEngine(unittest.TestCase):

    def setUp(self):
        self.board = Board({})
        self.squads = [s_utils.setup_squad(1, Main.mace, SqState.light),
                       s_utils.setup_squad(2, Main.dooku, SqState.dark)]
        # s_utils.setup_squad(3, Main.mace, Square.light),
        # s_utils.setup_squad(4, Main.dooku, Square.dark)]
        self.engine = Engine({'board': self.board, 'squads': self.squads,
                              'active_char': self.squads[0].chars['main']})
        self.engine.move_char(self.squads[0].chars['main'], Pos(3, 3))

    # ######################### active squad ################################

    def test_active_squad(self):
        self.assertIsNotNone(self.engine.active_squad())

    # ############################ is_game_over ##############################

    def test_is_game_over_false(self):
        self.assertFalse(self.engine.is_game_over())

    def test_is_game_over_true(self):
        self.squads[0].chars['main'].hp = 0
        # self.squads[2].chars['main'].hp = 0
        self.assertTrue(self.engine.is_game_over())

    # ######################### move_character ################################

    def test_move_character_true_place_character(self):
        self.assertEqual(self.engine.board.board[8][5]['state'], SqState.empty)
        self.engine.move_char(self.engine.active_char, Pos(8, 5))
        self.assertEqual(self.engine.board.board[8][5]['state'], SqState.light)

    def test_move_character_true_move_character(self):
        self.engine.move_char(self.engine.active_char, Pos(8, 5))
        self.assertEqual(self.engine.board.board[8][5]['state'], SqState.light)
        self.assertEqual(self.engine.board.board[2][2]['state'], SqState.empty)
        self.engine.move_char(self.engine.active_char, Pos(2, 2))
        self.assertEqual(self.engine.board.board[2][2]['state'], SqState.light)

    def test_move_character_false_out_of_bounds(self):
        self.assertFalse(self.engine.move_char(self.engine.active_char,
                                               Pos(8, 5)))

    # ############################# Move Squad ###########################

    def test_move_squad(self):
        squad_pos = {'main': Pos(0, 0), 'minor1': Pos(0, 1),
                     'minor2': Pos(0, 2)}
        squad_num = 1
        self.engine.move_char(self.squads[1].chars['main'], Pos(4, 3))
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(4, 2))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        self.engine.move_squad(squad_pos, squad_num)
        self.assertEqual(self.squads[0].chars['minor1'].hp, 4)
        self.assertEqual(self.squads[1].chars['main'].hp, 16)
        self.assertEqual(self.squads[1].chars['minor2'].hp, 3)

    # ######################## deal_card_to_squads ############################

    def test_deal_card_to_squads(self):
        deck_length0 = len(self.squads[0].deck)
        hand_length0 = len(self.squads[0].hand)
        deck_length1 = len(self.squads[1].deck)
        hand_length1 = len(self.squads[1].hand)
        self.engine.deal_cards_to_squads()
        self.assertEqual(len(self.squads[0].hand), hand_length0 + 4)
        self.assertEqual(len(self.squads[0].deck), deck_length0 - 4)
        self.assertEqual(len(self.squads[1].hand), hand_length1 + 4)
        self.assertEqual(len(self.squads[1].deck), deck_length1 - 4)

    # ####################### get_all_adjacent_characters #####################

    def test_get_all_adjacent_characters_empty_list(self):
        self.squads[0].chars['main'].pos = Pos(0, 0)
        self.assertEqual(len(self.engine.get_adj_chars()), 0)

    def test_get_all_adjacent_characters_one_ally_three_enemy(self):
        self.engine.remove_char(self.squads[0].chars['minor1'])
        self.engine.move_char(self.squads[0].chars['minor2'], Pos(3, 2))
        self.engine.move_char(self.squads[1].chars['main'], Pos(4, 3))
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(4, 2))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        self.assertEqual(len(self.engine.get_adj_chars()), 4)

    def test_get_all_adjacent_characters_one_enemy(self):
        self.engine.remove_char(self.squads[0].chars['minor1'])
        self.engine.remove_char(self.squads[0].chars['minor2'])
        self.engine.move_char(self.squads[1].chars['main'], Pos(4, 3))
        self.engine.remove_char(self.squads[1].chars['minor1'])
        self.engine.remove_char(self.squads[1].chars['minor2'])
        self.assertEqual(len(self.engine.get_adj_chars()), 1)

    # ######################## get_all_adjacent_allies ####################

    def test_get_all_adjacent_allies_empty_list(self):
        self.squads[0].chars['main'].pos = Pos(0, 0)
        allies, enemies = self.engine.get_adj_allies_enemies()
        self.assertListEqual(allies, [])

    def test_get_all_adjacent_allies_two(self):
        self.engine.move_char(self.squads[0].chars['minor1'], Pos(3, 4))
        self.engine.move_char(self.squads[0].chars['minor2'], Pos(3, 2))
        allies, enemies = self.engine.get_adj_allies_enemies()
        self.assertEqual(len(allies), 2)

    def test_get_all_adjacent_allies_one(self):
        self.engine.move_char(self.squads[0].chars['minor2'], Pos(3, 2))
        allies, enemies = self.engine.get_adj_allies_enemies()
        self.assertEqual(len(allies), 1)

    # ######################## get_all_adjacent_enemies ####################

    def test_get_all_adjacent_enemies_empty_list(self):
        self.engine.remove_char(self.squads[1].chars['main'])
        allies, enemies = self.engine.get_adj_allies_enemies()
        self.assertListEqual(enemies, [])

    def test_get_all_adjacent_enemies_three(self):
        self.engine.move_char(self.squads[1].chars['main'], Pos(4, 3))
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(4, 2))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        allies, enemies = self.engine.get_adj_allies_enemies()
        self.assertEqual(len(enemies), 3)

    def test_get_all_adjacent_enemies_two(self):
        self.engine.remove_char(self.squads[1].chars['main'])
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(4, 2))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        allies, enemies = self.engine.get_adj_allies_enemies()
        self.assertEqual(len(enemies), 2)

    #########################################################################
    #                       Discovery Methods
    #########################################################################

    # ######################## get_possible_targets ####################

    def test_get_possible_targets_empty_list(self):
        self.engine.move_char(self.squads[0].chars['minor2'], Pos(3, 2))
        self.engine.move_char(self.squads[1].chars['main'], Pos(6, 6))
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(0, 3))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        self.assertEqual(len(self.engine.get_char_targets(
            self.squads[0].chars['main'])), 1)

    def test_get_possible_targets_three(self):
        self.engine.move_char(self.squads[0].chars['main'], Pos(2, 2))
        self.engine.move_char(self.squads[0].chars['minor2'], Pos(3, 3))
        self.engine.move_char(self.squads[1].chars['main'], Pos(6, 6))
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(0, 3))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        self.assertEqual(len(self.engine.get_char_targets(
            self.squads[0].chars['minor2'])), 3)

    def test_get_possible_targets_two(self):
        self.engine.remove_char(self.squads[1].chars['main'])
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(4, 2))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        self.assertEqual(len(self.engine.get_char_targets(
            self.squads[0].chars['main'])), 2)

    # ########################### Get Possible Moves ########################

    def test_find_moves_roll_1_true(self):
        self.assertEqual(len(self.engine.get_possible_moves(moves=1)), 5)

    def test_find_moves_roll_2_true(self):
        self.engine.dice.result = Roll.two_all
        self.assertEqual(len(self.engine.get_possible_moves()), 13)

    def test_find_moves_roll_3_true(self):
        self.engine.dice.result = Roll.three
        self.assertEqual(len(self.engine.get_possible_moves()), 25)

    def test_find_moves_roll_4_true(self):
        self.engine.dice.result = Roll.four
        self.assertEqual(len(self.engine.get_possible_moves()), 38)

    def test_find_moves_roll_5_true(self):
        self.engine.dice.result = Roll.five
        self.assertEqual(len(self.engine.get_possible_moves()), 49)

    ##########################################################################
    #                           Abilities
    ##########################################################################

    # ############################ Damage_Adjacent ###########################

    def test_dmg_adjacent_enemies(self):
        self.engine.move_char(self.squads[0].chars['minor1'], Pos(5, 6))
        self.engine.move_char(self.squads[0].chars['minor2'], Pos(3, 2))
        self.engine.move_char(self.squads[1].chars['main'], Pos(4, 3))
        self.engine.move_char(self.squads[1].chars['minor1'], Pos(4, 2))
        self.engine.move_char(self.squads[1].chars['minor2'], Pos(4, 4))
        self.engine.damage_adj_chars(2)
        self.assertEqual(self.squads[0].chars['minor1'].hp, 4)
        self.assertEqual(self.squads[1].chars['main'].hp, 16)
        self.assertEqual(self.squads[1].chars['minor2'].hp, 3)

    ###########################################################################
    #                        Card mechanics
    ###########################################################################

    def test_attack_undefended(self):
        self.assertIsNone(self.engine.def_card)

    def test_attack_defended(self):
        self.engine.def_card = 'fake card'
        self.assertIsNotNone(self.engine.def_card)