Ejemplo n.º 1
0
 def test_player_hand_card_contains_multiple_cards_selected(self):
     with pytest.raises(PlayerParameterException):
         player = Player(name, one)
         card1 = Card(one, one, tuple_ones)
         card1.is_selected = True
         card2 = Card(2, one, tuple_ones)
         card2.is_selected = True
         player.hand = [card1, card2]
Ejemplo n.º 2
0
 def launch_main_menu(self):
     #print(str(self.connexion_menu.parameters))
     name = self.connexion_menu.parameters.get('player_name')
     color = self.connexion_menu.parameters.get('player_color')
     if not name or not color:
         return
     self.player = Player(name, color, self.screen)
     self.connexion_menu.run = False
     self.back_ground_menu = self.main_menu
     self.main_menu.launch()
Ejemplo n.º 3
0
class GameOffline(Game):
    def __init__(self, parent, player):

        Game.__init__(self, parent, player)

        self.turn = bool(Coin())

    # FUNCTIONS

    def init_opponent(self):
        self.opponent = Player("IA", clearblue, self.screen)
        self.opponent.rect = self.rect_right
        self.opponent.number = 1
        self.opponent.reset_hand()

    def play_opponnent_turn(self):
        self.message.text_key = text_opponent_turn
        self.draw()
        play_random_card(self.board, self.opponent, self.screen)
        self.actualize_turn_count()
        self.actualize_scores()
        self.turn = True
Ejemplo n.º 4
0
 def test_player_color_b_not_number(self):
     with pytest.raises(PlayerParameterException):
         Player(name, (1, 1, "Tests"))
Ejemplo n.º 5
0
 def test_player_color_size_too_high(self):
     with pytest.raises(PlayerParameterException):
         Player(name, (1, 1, 1, 1))
Ejemplo n.º 6
0
 def test_player_color_not_tuple(self):
     with pytest.raises(PlayerParameterException):
         Player(name, "Tests")
Ejemplo n.º 7
0
 def test_player_color_is_none(self):
     with pytest.raises(PlayerParameterException):
         Player(name, None)
Ejemplo n.º 8
0
 def test_player_name_is_not_str(self):
     with pytest.raises(PlayerParameterException):
         Player(2, tuple_ones)
Ejemplo n.º 9
0
class GameTutorial(Game):
    def __init__(self, parent, player):

        Game.__init__(self, parent, player)

        self.step = 1
        self.rounds = 5

        parameter_path = directory_path + "/Parameters/tutorials.yaml"
        with open(parameter_path, 'r') as stream:
            try:
                self.configuration = yaml.safe_load(stream)
            except yaml.YAMLError as exc:
                print(exc)

    # OVERRIDED FUNCTIONS

    def init_in_game_menu(self):

        in_game_tutorial_menu_rect = RectCenter(in_game_tutorial_menu_px,
                                                in_game_tutorial_menu_py,
                                                in_game_tutorial_menu_width,
                                                in_game_tutorial_menu_height)

        in_game_tutorial_menu_capitulate_button = Button(
            text_capitulate_game,
            in_game_tutorial_menu_capitulate_button_px,
            in_game_tutorial_menu_capitulate_button_py,
            action=self.launch_confirm_capitulate_menu)

        in_game_tutorial_replay_tutorial_button = Button(
            text_replay_tutorial,
            in_game_tutorial_menu_replay_tutorial_button_px,
            in_game_tutorial_menu_replay_tutorial_button_py,
            action=self.replay_tutorial)

        in_game_tutorial_menu_options_button = Button(
            text_options,
            in_game_tutorial_menu_options_button_px,
            in_game_tutorial_menu_options_button_py,
            action=self.parent.launch_options_menu)

        in_game_tutorial_menu_return_to_game_button = Button(
            text_return_to_game,
            in_game_tutorial_menu_return_to_game_button_px,
            in_game_tutorial_menu_return_to_game_button_py)

        self.in_game_menu = Menu(
            self,
            buttons=[
                in_game_tutorial_menu_capitulate_button,
                in_game_tutorial_replay_tutorial_button,
                in_game_tutorial_menu_options_button
            ],
            quit_button=in_game_tutorial_menu_return_to_game_button,
            rect=in_game_tutorial_menu_rect)

    def init_player(self, player):
        self.player = player
        self.player.number = 0
        self.player.rect = self.rect_left

    def init_opponent(self):
        self.opponent = Player("IA", clearblue, self.screen)
        self.opponent.rect = self.rect_right
        self.opponent.number = 1

    def build_card(self, card_configuration, player):
        number = 5 if 'number' not in card_configuration else card_configuration[
            'number']
        custom_card = Card(number,
                           player.number,
                           player.color,
                           self.screen,
                           number_of_arrows=2)

        custom_card.life_point = card_configuration['life_point']

        custom_card.arrows = {
            direction: None
            for direction in Directions.all_directions
        }
        for direction in card_configuration['arrows']:
            custom_card.arrows[eval(direction)] = Arrow(
                eval(direction), 0, 0, self.screen)
        return custom_card

    def new_round(self):

        round_configuration = self.configuration['round_%s' % str(self.step)]

        board_configuration = round_configuration['board']
        self.board = Board(self, board_configuration['size_x'],
                           board_configuration['size_y'])
        if board_configuration['crushed']:
            for case in board_configuration['crushed']:
                if not case:
                    continue
                self.board.crush(case['x'], case['y'])

        player_1_configuration = round_configuration['player_1']
        if player_1_configuration['board']:
            for card in player_1_configuration['board']:
                custom_card = self.build_card(card, self.player)
                self.board.get_case(card['x'], card['y']).put(custom_card)
        if player_1_configuration['hand']:
            for card in player_1_configuration['hand']:
                if not card:
                    continue
                custom_card = self.build_card(card, self.player)
                self.player.add_card(custom_card)
            self.player.reset_hand_positions()

        player_2_configuration = round_configuration['player_2']

        if player_2_configuration['board']:
            for card in player_2_configuration['board']:
                custom_card = self.build_card(card, self.opponent)
                self.board.get_case(card['x'], card['y']).put(custom_card)

        if player_2_configuration['hand']:
            for card in player_2_configuration['hand']:
                custom_card = self.build_card(card, self.opponent)
                self.opponent.add_card(custom_card)
                self.opponent.reset_hand_positions()

        self.turn = True
        self.actualize_scores()
        self.turn_count = 0
        self.played = 0
        self.round_over = False
        self.displayed_tutorial_message = False

    def end_round(self):

        self.end_round_menu.run = False
        self.round_over = True
        self.step += 1

    def game_loop_function(self):

        if not self.displayed_tutorial_message:

            messages = []
            message_number = 1
            got_all_message = False
            while (not got_all_message):
                try:
                    text_key = text_tutorial_message % (str(
                        self.step), str(message_number))
                    message = Message(0, 0, text_key)
                    message.test_text_key()
                    messages.append(message)
                    message_number += 1
                except Exception:
                    got_all_message = True
            tutorial_message_menu = MultipleMessagesMenu(self,
                                                         messages=messages)
            tutorial_message_menu.launch()

            self.displayed_tutorial_message = True

    # DRAWING FUNCTION

    def draw(self, update=True):

        self.screen.fill(get_color(white))

        text_step = get_text(text_step_count, text_completion=str(self.step))
        self.screen.blit(get_text_image(text_step),
                         (self.rect_up.x + 10, self.rect_up.y + 10))

        self.player.draw()

        if self.opponent is not None:
            self.opponent.draw(card_hidden=False)

        pygame.draw.rect(self.screen, get_color(black), self.rect_up, border)
        pygame.draw.rect(self.screen, get_color(black), self.rect_left, border)
        pygame.draw.rect(self.screen, get_color(black), self.rect_bottom,
                         border)
        pygame.draw.rect(self.screen, get_color(black), self.rect_right,
                         border)

        self.message.draw(self.screen)

        self.board.draw(update=False)

        if update:
            pygame.display.update()

    # ADDITIONNAL FUNCTIONS

    def replay_tutorial(self):
        self.in_game_menu.run = False
        self.displayed_tutorial_message = False
Ejemplo n.º 10
0
 def test_player_color_b_decimal(self):
     with pytest.raises(PlayerParameterException):
         Player(name, (1, 1, 3.5))
Ejemplo n.º 11
0
 def test_player_hand_card_is_not_is_own(self):
     with pytest.raises(PlayerParameterException):
         Player(name, one).hand = [Card(one, 2, tuple_ones)]
Ejemplo n.º 12
0
 def test_player_hand_is_not_card(self):
     with pytest.raises(PlayerParameterException):
         Player(name, one).hand = ["Tests"]
Ejemplo n.º 13
0
 def test_player_hand_is_none(self):
     with pytest.raises(PlayerParameterException):
         Player(name, one).hand = None
Ejemplo n.º 14
0
 def test_player_py_decimal(self):
     with pytest.raises(PlayerParameterException):
         player = Player(name, tuple_ones)
         player.round = 3.5
Ejemplo n.º 15
0
def Game():
    # Define some colours
    # Colours are defined using RGB values
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)
    PURPLE = (174, 20, 188)
    BROWN = (84, 31, 10)
    font = pygame.font.Font(None, 36)
    BROWN = (70, 31, 10)

    # Define screen size
    screenW = 1400
    screenH = 785

    # Check if staff placed or not
    active = True

    # Timer of when you need to spawn enemies
    spawnTime = 0
    waveSpeed = 0

    # Check if first wave has passed
    passedFirstWave = False

    # Checked if already pressed e
    pressedE = False

    # A cooldown event and boolean to see it's state
    cooldownEvent = pygame.USEREVENT
    cooled = True

    # To count the demons you've slain
    killCount = 0

    # This loop will continue until the user exits the game
    carryOn = True
    clock = pygame.time.Clock()

    # Open a new window
    # The window is defined as (width, height), measured in pixels
    size = (screenW, screenH)
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption("Demon Staff")
    pygame.mouse.set_visible(False)

    # Replace mouse with aiming redicule
    # Image from: https://www.frankerfacez.com/emoticon/37517-hitmarker
    hitMarker = pygame.image.load('hitMarker.png')
    hitMarker = pygame.transform.scale(hitMarker, (50, 50))
    hitMarkerRect = hitMarker.get_rect()

    # - Create some tutorial text on the floor of the game
    demonFont = pygame.font.Font('DemonsAndDarlings.ttf', 64)
    demonFont2 = pygame.font.Font('DemonsAndDarlings.ttf', 48)
    # - W
    wText = demonFont.render('W', True, RED)
    wTextRect = wText.get_rect()
    wTextRect.center = (screenW / 2, screenH / 3)
    # - S
    sText = demonFont.render('S', True, RED)
    sTextRect = sText.get_rect()
    sTextRect.center = (screenW / 2, screenH * 3 / 4)
    # - A
    aText = demonFont.render('A', True, RED)
    aTextRect = aText.get_rect()
    aTextRect.center = (screenW / 4, screenH / 2)
    # - D
    dText = demonFont.render('D', True, RED)
    dTextRect = dText.get_rect()
    dTextRect.center = (screenW * 3 / 4, screenH / 2)
    #- The press e buttom
    eText = demonFont.render('', True, RED)
    eTextRect = eText.get_rect()
    # - SpaceBar tutorial text
    devilText = demonFont2.render('Get close...', True, PURPLE)
    devilTextRect = devilText.get_rect()
    devilTextRect.center = (200, 450)

    devil2Text = demonFont2.render('and hold that staff...', True, PURPLE)
    devil2TextRect = devil2Text.get_rect()
    devil2TextRect.center = (500, 550)

    devil3Text = demonFont2.render('do it with Spacebar!', True, PURPLE)
    devil3TextRect = devil3Text.get_rect()
    devil3TextRect.center = (screenW // 2.7, 625)

    # The text to tell how many killed
    killText = demonFont.render('Slain: ', True, RED)
    killTextRect = killText.get_rect()
    killTextRect.center = (80, 110)
    # The text counter for the killed
    killCountText = demonFont.render(str(killCount), True, RED)
    killCountTextRect = killCountText.get_rect()
    killCountTextRect.center = (180, 110)

    # Create lists
    spriteList = pygame.sprite.Group()
    spawnerList = pygame.sprite.Group()
    enemyList = pygame.sprite.Group()
    objectList = pygame.sprite.Group()
    projectileList = pygame.sprite.Group()
    itemList = pygame.sprite.Group()

    # Create the objects and sets properties
    player = Player(GREEN, 50, 50, 4)
    player.rect.center = (screenW // 2, screenH // 2)

    staff = Staff(PURPLE, 0, 0)
    staff.rect.center = (screenW / 8, screenH - 160)

    staffAOE = StaffAOE(PURPLE, 300, 300, 300 // 2)
    staffAOE.rect.center = staff.rect.center

    spawner = EnemySpawner(RED, 50, 50)
    spawner.rect.center = (-50, -50)

    spawner2 = EnemySpawner(RED, 50, 50)
    spawner2.rect.center = (1450, -50)

    spawner3 = EnemySpawner(RED, 50, 50)
    spawner3.rect.center = (-50, 835)

    spawner4 = EnemySpawner(RED, 50, 50)
    spawner4.rect.center = (1450, 835)

    spawnerList.add(spawner, spawner2, spawner3, spawner4)

    spriteList.add(player, staff, staffAOE, spawner, spawner2, spawner3,
                   spawner4)
    objectList.add(staff, staffAOE)
    itemList.add(staff)

    #---------Main Program Loop----------
    while carryOn:

        # - Start the spawn timer
        spawnTime += 1

        # - Make the aiming redicule to follow mouse
        hitMarkerRect.center = pygame.mouse.get_pos()

        # --- Main event loop ---
        for event in pygame.event.get():  # Player did something
            if event.type == pygame.QUIT:  # Player clicked close button
                carryOn = False
            elif event.type == cooldownEvent:  # Off cooldown
                cooled = True
                pygame.time.set_timer(cooldownEvent, 0)

        # - WASD controls
        keys = pygame.key.get_pressed()
        if keys[pygame.K_a]:
            player.moveLeft(5)
            aText = demonFont.render('', True, BLACK)
        if keys[pygame.K_d]:
            player.moveRight(5)
            dText = demonFont.render('', True, BLACK)
        if keys[pygame.K_w]:
            player.moveUp(5)
            wText = demonFont.render('', True, BLACK)
        if keys[pygame.K_s]:
            player.moveDown(5)
            sText = demonFont.render('', True, BLACK)

        # --- Game logic goes here
        spriteList.update()

        # List to know what to check for collision between enemies and player
        hurtList = pygame.sprite.spritecollide(player, enemyList, False,
                                               pygame.sprite.collide_mask)
        pickUpList = pygame.sprite.spritecollide(player, itemList, False,
                                                 pygame.sprite.collide_mask)

        # - Moves staff when presing and holding spacebar
        for item in pickUpList:

            # Checked if pressed spacebar
            if keys[pygame.K_SPACE]:

                # You pick up staff and move it
                item.moveWithPlayer(player)
                staffAOE.kill()

                # Removes the tutorial text
                devilText = demonFont2.render('', False, RED)
                devil2Text = demonFont2.render('', False, RED)
                devil3Text = demonFont2.render('', False, RED)

                active = False  # Makes so can't use magic

            else:
                # When done moving, place it
                staffAOE.updateAOE(staff)
                staffAOE.add(objectList)
                staffAOE.add(spriteList)

                active = True  # When placed down again, can use magic again

        # - Creates random amount of enemies in random corners
        if spawnTime == 1000 - waveSpeed:

            # Sets amount of enemy to spawn
            amount = 0

            # First wave always one enemy
            if passedFirstWave == False:
                amount = 1
                print("how many:", amount)
            else:
                amount = random.randint(1, 6)
                print("how many:", amount - 1)

            # Loop to spawn and place enemies
            for badguy in range(amount):

                badguy = Enemy(RED, 0, 0, 4, 3)

                corner = random.randint(1, 4)
                if corner == 1:
                    badguy.rect.center = spawner.rect.center
                if corner == 2:
                    badguy.rect.center = spawner2.rect.center
                if corner == 3:
                    badguy.rect.center = spawner3.rect.center
                if corner == 4:
                    badguy.rect.center = spawner4.rect.center

                enemyList.add(badguy)
                spriteList.add(badguy)

            # When done spawning, make the time shorter
            spawnTime = 0
            waveSpeed += 5
            passedFirstWave = True

        # When timer is finally zero, you win
        elif waveSpeed == 1000:
            print("Your free!")
            carryOn = False

        # - Enemies charge to player
        for enemy in enemyList:
            enemy.moveToPlayer(player)

        # - Does dmg when player toches enemy
        for bad in hurtList:
            player.health -= 1

            if bad.rect.x > player.rect.x:
                player.rect.x -= 100
            if bad.rect.x < player.rect.x:
                player.rect.x += 100
            if bad.rect.y > player.rect.y:
                player.rect.y -= 100
            if bad.rect.y < player.rect.y:
                player.rect.y += 100

        # - Ends game when player runs out of health
        if player.health <= 0:
            carryOn = False

        # - Blessing zone to allow player to use magic,
        # Code based off: https://stackoverflow.com/questions/34054248/pygame-circle-and-its-associated-rect-for-collision-detection

        #  Find pos of player and AOE
        x1, y1 = player.rect.center
        x2, y2 = staffAOE.rect.center

        # Find the distance between player and AOE
        AOEDistance = math.hypot(x1 - x2, y1 - y2)
        if AOEDistance < staffAOE.radius and active == True:

            # Removes the tutorial text
            eText = demonFont.render('Press E', True, RED)
            eTextRect.center = (player.rect.x, player.rect.y - 70)

            # Removes the tutorial text
            if pressedE == True:
                eText = demonFont.render('', False, RED)

            # Checks pressed e
            if keys[pygame.K_e]:
                #  - Cooldown portion,
                # based off: https://stackoverflow.com/questions/23368999/move-an-object-every-few-seconds-in-pygame?noredirect=1&lq=1
                if cooled:

                    # Gets position of mouse
                    pos = pygame.mouse.get_pos()
                    xMouse = pos[0]
                    yMouse = pos[1]

                    # Creates a "Fireball"
                    fireBall = FireBall(player.rect.x, player.rect.y, xMouse,
                                        yMouse)

                    # Add fireball to lists
                    spriteList.add(fireBall)
                    projectileList.add(fireBall)

                    # Removes the tutorial text
                    eText = demonFont.render('', False, RED)

                    cooled = False
                    pressedE = True

                    # Start cooldown timer
                    pygame.time.set_timer(cooldownEvent, 3000)

        else:
            # If leaves zone, text disapears
            eText = demonFont.render('', False, RED)

        # Check for every fireball projectile
        for fireball in projectileList:
            # Creates a collision list for enemies
            enemyKillList = pygame.sprite.spritecollide(
                fireball, enemyList, False, pygame.sprite.collide_mask)
            # When hits enemy, removes fireball enemies
            for badboi in enemyKillList:
                badboi.health -= 1
                print(badboi.health)

                projectileList.remove(fireBall)
                spriteList.remove(fireBall)

                if badboi.health <= 0:
                    badboi.kill()
                    killCount += 1

            # When goes off screen, remove fireball
            if fireball.rect.x < 0 or fireball.rect.x > screenW or fireball.rect.y < 0 or fireball.rect.y > screenH:
                fireball.kill()

        # --- Draw code goes here

        # - Clear the screen to white
        screen.fill(BROWN)

        # Queue different shapes and lines to be drawn
        # - Draw all sprites
        spriteList.draw(screen)

        # - Devil's writing
        screen.blit(wText, wTextRect)
        screen.blit(sText, sTextRect)
        screen.blit(aText, aTextRect)
        screen.blit(dText, dTextRect)
        screen.blit(eText, eTextRect)
        screen.blit(killText, killTextRect)
        screen.blit(killCountText, killCountTextRect)
        screen.blit(devilText, devilTextRect)
        screen.blit(devil2Text, devil2TextRect)
        screen.blit(devil3Text, devil3TextRect)
        screen.blit(hitMarker, hitMarkerRect)

        # - Update kill count
        killCountText = demonFont.render(str(killCount), True, RED)

        # - Health Bar
        pygame.draw.rect(screen, BLACK, [5, 5, 200 + 10, 60], 10)
        pygame.draw.rect(screen, GREEN, [10, 10, player.health * 50, 50])

        # Update the screen with queued shapes
        pygame.display.flip()

        # --- Limit to 60 frames per second
        clock.tick(60)

    # Once the main program loop is exited, stop the game engine
    pygame.quit()
Ejemplo n.º 16
0
 def init_opponent(self):
     self.opponent = Player("IA", clearblue, self.screen)
     self.opponent.rect = self.rect_right
     self.opponent.number = 1
Ejemplo n.º 17
0
 def test_player_color_b_negative(self):
     with pytest.raises(PlayerParameterException):
         Player(name, (1, 1, -1))
Ejemplo n.º 18
0
 def test_player_color_b_to_big(self):
     with pytest.raises(PlayerParameterException):
         Player(name, (1, 1, 300))
Ejemplo n.º 19
0
 def test_player_number_negative(self):
     with pytest.raises(PlayerParameterException):
         player = Player(name, tuple_ones)
         player.number = -1
Ejemplo n.º 20
0
 def test_player_number_is_not_number(self):
     with pytest.raises(PlayerParameterException):
         player = Player(name, tuple_ones)
         player.number = "Tests"
Ejemplo n.º 21
0
 def init_opponent(self):
     self.opponent = Player("myself", blue, self.screen)
     self.opponent.number = 1
     self.opponent.rect = self.rect_right
     self.opponent.reset_hand()
Ejemplo n.º 22
0
 def test_player_hand_card_contains_multiple_cards_with_same_number(self):
     with pytest.raises(PlayerParameterException):
         Player(name, one).hand = [Card(one, one, tuple_ones),Card(one, one, tuple_ones)]
Ejemplo n.º 23
0
class Game(object):

    # PROPERTIES

    # CONSTRUCTORS

    def __init__(self, parent, player):

        # Est ce qu'il n'y a pas une meilleur façon d'avoir acces a la couche du dessus ?
        self.parent = parent

        self.screen = self.parent.screen

        self.board = Board(self, size_of_board, size_of_board, rocks=Coin())

        self.rect_up = pygame.Rect(0, 0, board_max_right, board_max_top)

        self.rect_left = pygame.Rect(0, board_max_top, board_max_left,
                                     board_max_bottom)

        self.rect_bottom = pygame.Rect(board_max_left, board_max_bottom,
                                       board_max_right, board_max_top)

        self.rect_right = pygame.Rect(board_max_right, 0, board_max_left,
                                      board_max_bottom)

        self.message = Message(0, 0, None)
        self.message.rect.width = self.rect_up.width
        self.message.rect.center = self.rect_up.center

        self.last_winner = None

        self.selected_card = None
        self.selected_case = None

        self.game_over = False
        self.round_over = False

        self.selected_case = None
        self.selected_card = None

        self.played = 0
        self.turn_count = 0

        self.rounds = rounds_to_win
        self.number_of_players = 2
        self.turn = bool(Coin())

        self.init_player(player)
        self.init_opponent()
        self.init_in_game_menu()
        self.init_end_round_menu()
        self.init_end_game_menu()
        self.init_confirm_capitulate_menu()

    # FUNCTIONS

    def play_game(self):

        while not self.game_over:

            self.new_round()

            self.message.text_key = text_choose_card

            self.draw()

            while not self.round_over:

                self.game_loop_function()

                if self.turn:
                    self.play_player_turn(self.player)
                else:
                    self.play_opponnent_turn()

                self.draw()

                if self.all_hands_are_empty():
                    self.launch_end_round_menu()

            if self.player.round == self.rounds or self.opponent.round == self.rounds:
                self.launch_end_game_menu()

    def play_player_turn(self, player):

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                # confirmation message to capitulate.
                self.parent.Quit()

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_ESCAPE:
                    self.in_game_menu.launch()

            elif event.type == pygame.MOUSEMOTION:
                pass

            elif event.type == pygame.MOUSEBUTTONDOWN:

                if event.button == 1:

                    click_x = event.pos[0]
                    click_y = event.pos[1]

                    if not self.selected_card and not self.selected_case:
                        self.selected_card = player.select_card(
                            click_x, click_y)
                    elif self.selected_card and not self.selected_case:
                        self.selected_case = self.board.select_case(
                            click_x, click_y)
                        if not self.selected_case:
                            self.selected_card = player.select_card(
                                click_x, click_y)
                    elif self.selected_card and self.selected_case:
                        if self.board.has_click_on_selected_case(
                                click_x, click_y):
                            self.play_selected_card(player)
                        else:
                            self.selected_case = self.board.select_case(
                                click_x, click_y)

                    if not self.selected_card and not self.selected_case:
                        self.message.text_key = text_choose_card
                    elif self.selected_card and not self.selected_case:
                        self.message.text_key = text_choose_case
                    elif self.selected_card and self.selected_case:
                        self.message.text_key = text_validate_case

    def actualize_turn_count(self):
        self.played += 1
        if self.played == self.number_of_players:
            self.turn_count += 1
            self.played = 0

    def actualize_scores(self):

        self.player.score = self.board.get_player_score(self.player.number)
        self.opponent.score = self.board.get_player_score(self.opponent.number)

    def all_hands_are_empty(self):
        return len(self.player.hand) == 0 and len(self.opponent.hand) == 0

    # MENUS

    def init_end_round_menu(self):

        end_round_menu_rect = RectCenter(end_round_menu_px, end_round_menu_py,
                                         end_round_menu_width,
                                         end_round_menu_height)

        end_round_menu_continue_button = Button(
            text_continue,
            end_round_menu_continue_button_px,
            end_round_menu_continue_button_py,
            action=self.end_round)

        self.end_round_menu = Menu(self,
                                   quit_button=end_round_menu_continue_button,
                                   messages=[],
                                   rect=end_round_menu_rect)

    def launch_end_round_menu(self):

        draw = self.player.score == self.opponent.score

        if draw:
            end_round_menu_message = Message(end_round_menu_message_px,
                                             end_round_menu_message_py,
                                             text_draw)
        else:
            winner = self.player if self.player.score > self.opponent.score else self.opponent
            winner.round += 1
            self.last_winner = winner
            end_round_menu_message = Message(end_round_menu_message_px,
                                             end_round_menu_message_py,
                                             text_player_won_round,
                                             argument=winner.name)

        self.end_round_menu.messages = [end_round_menu_message]

        self.end_round_menu.launch()

    def init_end_game_menu(self):

        end_game_menu_rect = RectCenter(end_game_menu_px, end_game_menu_py,
                                        end_game_menu_width,
                                        end_game_menu_height)

        end_game_menu_continue_button = Button(
            text_continue,
            end_game_menu_continue_button_px,
            end_game_menu_continue_button_py,
            action=self.end_game)

        self.end_game_menu = Menu(self,
                                  quit_button=end_game_menu_continue_button,
                                  messages=[],
                                  rect=end_game_menu_rect)

    def launch_end_game_menu(self):

        winner = self.player if self.player.score == self.rounds else self.opponent

        end_game_menu_message = Message(end_game_menu_message_px,
                                        end_game_menu_message_py,
                                        text_player_won,
                                        argument=winner.name)

        self.end_game_menu.messages = [end_game_menu_message]

        self.end_game_menu.launch()

    def init_confirm_capitulate_menu(self):

        confirm_capitulate_menu_rect = RectCenter(
            quit_game_menu_px, quit_game_menu_py,
            confirm_capitulate_menu_width, confirm_capitulate_menu_height)

        confirm_capitulate_menu_message = Message(
            confirm_capitulate_menu_message_px,
            confirm_capitulate_menu_message_py, text_capitulate_game_question)

        confirm_capitulate_menu_yes_button = Button(
            text_yes,
            confirm_capitulate_menu_yes_button_px,
            confirm_capitulate_menu_yes_button_py,
            action=self.capitulate)
        confirm_capitulate_menu_no_button = Button(
            text_no, confirm_capitulate_menu_no_button_px,
            confirm_capitulate_menu_no_button_py)

        self.confirm_capitulate_menu = Menu(
            self,
            quit_button=confirm_capitulate_menu_no_button,
            buttons=[confirm_capitulate_menu_yes_button],
            messages=[confirm_capitulate_menu_message],
            rect=confirm_capitulate_menu_rect)

    def launch_confirm_capitulate_menu(self):
        self.confirm_capitulate_menu.launch()

    # OVERRIDED FUNCTIONS

    def init_in_game_menu(self):

        in_game_menu_rect = RectCenter(in_game_menu_px, in_game_menu_py,
                                       in_game_menu_width, in_game_menu_height)

        in_game_menu_capitulate_button = Button(
            text_capitulate_game,
            in_game_menu_capitulate_button_px,
            in_game_menu_capitulate_button_py,
            action=self.launch_confirm_capitulate_menu)

        in_game_menu_options_button = Button(
            text_options,
            in_game_menu_options_button_px,
            in_game_menu_options_button_py,
            action=self.parent.launch_options_menu)

        in_game_menu_return_to_game_button = Button(
            text_return_to_game, in_game_menu_return_to_game_button_px,
            in_game_menu_return_to_game_button_py)

        self.in_game_menu = Menu(
            self,
            buttons=[
                in_game_menu_capitulate_button, in_game_menu_options_button
            ],
            quit_button=in_game_menu_return_to_game_button,
            rect=in_game_menu_rect)

    def init_player(self, player):
        self.player = player
        self.player.number = 0
        self.player.rect = self.rect_left
        self.player.reset_hand()

    def init_opponent(self):
        self.opponent = Player("myself", blue, self.screen)
        self.opponent.number = 1
        self.opponent.rect = self.rect_right
        self.opponent.reset_hand()

    def capitulate(self):

        self.opponent.round = self.rounds

        self.round_over = True
        self.game_over = True
        self.confirm_capitulate_menu.run = False
        self.in_game_menu.run = False
        self.draw()

    def play_selected_card(self, player):

        player.unselect_all_cards()
        self.board.unselect_all_cases()

        card = player.get_card(self.selected_card.number)
        self.draw()
        self.board.play(card, self.selected_case, None)

        self.actualize_scores()
        self.turn = not self.turn
        self.selected_case = None
        self.selected_card = None

        self.actualize_turn_count()

    def play_opponnent_turn(self):

        self.message.text_key = text_opponent_turn
        self.play_player_turn(self.opponent)

    def game_loop_function(self):
        pass

    def new_round(self):

        self.player.reset_hand()
        self.opponent.reset_hand()

        self.board = Board(self, size_of_board, size_of_board, rocks=True)

        if self.last_winner:
            if self.last_winner.number != self.player.number:
                self.turn = True
            else:
                self.turn = False

        self.actualize_scores()
        self.round_over = False
        self.turn_count = 0
        self.played = 0

    def end_round(self):
        self.end_round_menu.run = False
        self.round_over = True

    def end_game(self):

        self.game_over = True
        self.player.round = 0
        self.opponent.round = 0
        self.player.hand = []
        self.opponent.hand = []

    # DRAWING FUNCTION

    def draw(self, update=True):

        self.screen.fill(get_color(white))

        text_turn = get_text(text_turn_count,
                             text_completion=str(self.turn_count))
        self.screen.blit(get_text_image(text_turn),
                         (self.rect_up.x + 10, self.rect_up.y + 10))

        self.player.draw()

        if self.opponent is not None:
            self.opponent.draw(card_hidden=False)

        pygame.draw.rect(self.screen, get_color(black), self.rect_up, border)
        pygame.draw.rect(self.screen, get_color(black), self.rect_left, border)
        pygame.draw.rect(self.screen, get_color(black), self.rect_bottom,
                         border)
        pygame.draw.rect(self.screen, get_color(black), self.rect_right,
                         border)

        self.message.draw(self.screen)

        self.board.draw(update=False)

        if update:
            pygame.display.update()