Пример #1
0
def choice_17(g, p):
    if g.info_tokens < 8:
        for c in p.deck:
            if c.value_info != 5:
                discard(g, p, c)
                return True
    return False
Пример #2
0
def random_choice(g, p):
    # choice 0 : discard
    # choice 1 : play a card
    # choice 2 : give info
    possible_choices = [0, 1, 2]

    # can not discard if there are already 8 info tokens
    if g.info_tokens == 8:
        possible_choices.remove(0)
    # can not give info if there are not any info token left
    elif g.info_tokens == 0:
        possible_choices.remove(2)

    action_choice = choice(possible_choices)

    if action_choice == 0:
        # choose randomly the card to discard
        discarded_card = randrange(len(p.deck))
        discard(g, p, p.deck[discarded_card])

    elif action_choice == 1:
        # choose randomly the card to play
        played_card = randrange(len(p.deck))
        play_card(g, p, p.deck[played_card])

    else:
        # choose randomly the player to give information
        p_index = g.players.index(p)
        other_players_index = list(range(len(g.players)))
        other_players_index.remove(p_index)
        player_info = g.players[choice(other_players_index)]

        # choose randomly the card to give information on
        card_info = randrange(len(player_info.deck))

        # choose randomly the type of information : 0 for color, 1 for value
        info_type = choice(['color', 'value'])

        if info_type == 'color':
            info = choice(['blue', 'red', 'green', 'yellow', 'white'])
        else:
            info = randrange(1, 6)

        give_info(g, player_info, card_info, info_type, info)
Пример #3
0
def choice_1(g, p):
    for c in p.deck:
        if (c.color_info != "") and (c.value_info != 10):
            if c.value_info <= g.fireworks[c.color_info]:
                discard(g, p, c)
                return True
            else:
                play_card(g, p, c)
                return True
        elif c.color_info != "":
            if (g.fireworks[c.color_info] == 5) or (color_lost(g, c.color)):
                discard(g, p, c)
                return True
            else:
                play_card(g, p, c)
                return True
        elif c.value_info != 10:
            if (c.value_info < 5) and (c.value_info <= min(
                    g.fireworks.values())):
                discard(g, p, c)
                return True
            elif c.value_info < 5:
                play_card(g, p, c)
                return True
    return False
Пример #4
0
def simple_rules(g, p):
    # play a card if the information on it is known and can be played
    # discard it if the card is useless
    for c in p.deck:
        if (c.color_info != "") and (c.value_info != 10):
            if c.value == g.fireworks[c.color_info] + 1:
                play_card(g, p, c)
                return
    for c in p.deck:
        if (c.color_info != "") and (c.value_info != 10):
            if c.value_info <= g.fireworks[c.color_info]:
                discard(g, p, c)
                return
            elif c.value_info == g.fireworks[c.color_info] + 1:
                play_card(g, p, c)
                return
        elif c.color_info != "":
            if (g.fireworks[c.color_info] == 5) or (color_lost(g, c.color)):
                discard(g, p, c)
                return
            else:
                play_card(g, p, c)
                return
        elif c.value_info != 10:
            if (c.value_info < 5) and (c.value_info <= min(
                    g.fireworks.values())):
                discard(g, p, c)
                return
            elif (c.value_info < 5) and (c.value_info <=
                                         max(g.fireworks.values()) + 1):
                play_card(g, p, c)
                return

    # give the information if a player among the 2 nexts has 2 playable cards
    if g.info_tokens >= 1:
        for next_turn in [1, 2]:
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                recurrent_value = several_playable_cards(g, next_player_deck)
                if recurrent_value != 0:
                    good_info = True
                    for c in next_player_deck:
                        if (c.value == recurrent_value) and (
                                c.color_info == "") and (c.value_info == 10):
                            if (not (unseen_information(
                                    g, next_player, c, 'value'))
                                ) or (not (unseen_information(
                                    g, next_player, c, 'color'))) or (
                                        c.value < g.fireworks[c.color] + 1):
                                good_info = False
                    if good_info:
                        give_info(g, next_player, 'value', recurrent_value)
                        return

    # complete the information about a "5" of the 2 next players if it is playable
    if g.info_tokens >= 1:
        for next_turn in range(1, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            for c in next_player_deck:
                if (c.value_info == 5) and (c.color_info
                                            == "") and (g.fireworks[c.color]
                                                        == 4):
                    same_color_cards = 0
                    for cards in next_player_deck:
                        if cards.color == c.color:
                            same_color_cards += 1
                    if same_color_cards <= 1:
                        give_info(g, next_player, 'color', c.color)
                        return

    # give an information if the 2 next players have nice cards with not any info on it
    # and if there is at least an info token left
    if g.info_tokens >= 1:
        for next_turn in [1, 2]:
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (c.value == g.fireworks[c.color] + 1) and (
                            c.color_info == "") and (c.value_info == 10):
                        info = info_to_give(next_player_deck, c)
                        if info == "color":
                            if unseen_information(g, next_player, c, 'color'):
                                give_info(g, next_player, 'color', c.color)
                                return
                        elif info == "value":
                            if unseen_information(g, next_player, c, 'value'):
                                give_info(g, next_player, 'value', c.value)
                                return

    # give an information to a player if the previous player has an information so the second one
    # will be able to play a card just after (second and third next players)
    if g.info_tokens >= 1:
        for next_turn in [2, 3]:
            player_before_next = g.players[(g.players.index(p) + next_turn - 1)
                                           % len(g.players)]
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (c.value == g.fireworks[c.color] +
                            2) and (c.color_info == "") and (
                                c.value_info == 10) and info_given_to_player(
                                    player_before_next, c.color,
                                    g.fireworks[c.color] +
                                    1) and not (info_on_the_left(
                                        player_before_next.deck, c)):
                        info = info_to_give(next_player_deck, c)
                        if info == "color":
                            if unseen_information(g, next_player, c, 'color'):
                                give_info(g, next_player, 'color', c.color)
                                return
                        elif info == "value":
                            if unseen_information(g, next_player, c, 'value'):
                                give_info(g, next_player, 'value', c.value)
                                return

    # give an information about a "5" or a useless card in the 2 next players' deck
    if g.info_tokens >= 1:
        for next_turn in [1, 2]:
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (c.value == 5) and (c.color_info
                                           == "") and (c.value_info == 10):
                        give_info(g, next_player, 'value', 5)
                        return
                    elif (min(g.fireworks.values()) >=
                          c.value) and (c.value_info == 10):
                        give_info(g, next_player, 'value', c.value)
                        return
                    elif (g.fireworks[c.color] == 5) and (c.color_info == ""):
                        give_info(g, next_player, 'color', c.color)
                        return

    # give an information if the next players have nice cards with not any info on it
    # and if there is at least an info token left (from the third next player)
    if g.info_tokens >= 1:
        for next_turn in range(3, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (c.value == g.fireworks[c.color] + 1) and (
                            c.color_info == "") and (c.value_info == 10):
                        info = info_to_give(next_player_deck, c)
                        if info == "color":
                            if unseen_information(g, next_player, c, 'color'):
                                give_info(g, next_player, 'color', c.color)
                                return
                        elif info == "value":
                            if unseen_information(g, next_player, c, 'value'):
                                give_info(g, next_player, 'value', c.value)
                                return

    # give an information about a "5" or a useless card in the next players' deck (from the third next player)
    if g.info_tokens >= 1:
        for next_turn in range(3, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (c.value == 5) and (c.color_info
                                           == "") and (c.value_info == 10):
                        give_info(g, next_player, 'value', 5)
                        return
                    elif (min(g.fireworks.values()) >=
                          c.value) and (c.value_info == 10):
                        give_info(g, next_player, 'value', c.value)
                        return
                    elif (g.fireworks[c.color] == 5) and (c.color_info == ""):
                        give_info(g, next_player, 'color', c.color)
                        return

    # complete the information about a "5" of the next players
    if g.info_tokens >= 1:
        for next_turn in [1, 2]:
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            for c in next_player_deck:
                if (c.value_info == 5) and (c.color_info == "") and (
                        g.fireworks[c.color]
                        == 4) and not (same_value_or_color_cards(
                            next_player_deck, c)):
                    give_info(g, next_player, 'color', c.color)
                    return

    # complete the information about an unplayable informed card
    if g.info_tokens >= 1:
        for next_turn in [1, 2]:
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            for c in next_player_deck:
                if (c.value_info == 10) and (c.color_info != ""):
                    if c.value != g.fireworks[c.color] + 1:
                        info = info_to_give(next_player_deck, c)
                        if info == "value":
                            give_info(g, next_player, 'value', c.color)
                            return
                if (c.value_info != 10) and (c.color_info == ""):
                    if c.value != g.fireworks[c.color] + 1:
                        info = info_to_give(next_player_deck, c)
                        if info == "color":
                            give_info(g, next_player, 'color', c.color)
                            return

    # throw a card (not a "5") if it is not useful in a near future
    if g.info_tokens < 8:
        for c in p.deck:
            if (c.value_info != 10) and (c.value != 5):
                if c.value_info > max(g.fireworks.values()) + 1:
                    discard(g, p, c)
                    return

    # throw a random card (not a useful "5") if no information about the deck
    if g.info_tokens < 6:
        for c in p.deck:
            if c.value_info != 5:
                discard(g, p, c)
                return

    # complete the information about a "5" with no cards with the same color in the deck to not discard randomly
    if g.info_tokens >= 1:
        for next_turn in range(1, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            for c in next_player_deck:
                if (c.value_info == 5) and (c.color_info == ""):
                    if not (same_value_or_color_cards(next_player_deck, c)):
                        give_info(g, next_player, 'color', c.color)
                        return

    # complete the color information about cards that are the same and with the value only as information
    if g.info_tokens >= 1:
        for next_turn in range(1, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            for c in next_player_deck:
                if (duplicated_card(g, next_player_deck, c)
                    ) and (c.value <= g.fireworks[c.color]) and (
                        c.value_info != 10) and (c.color_info == "") and not (
                            same_value_or_color_cards(next_player_deck, c)):
                    give_info(g, next_player, 'color', c.color)
                    return

    # give an information about a playable card which appears twice in the deck of one of the next players
    if g.info_tokens >= 1:
        for next_turn in range(1, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (duplicated_card(
                            g, next_player_deck,
                            c)) and (c.value == g.fireworks[c.color] + 1) and (
                                c.value_info == 10) and (c.color_info == ""):
                        give_info(g, next_player, 'value', c.value)
                        return

    # give an information about a playable card but with cards with same color and same value in the deck
    # can not be given to the player just after
    if g.info_tokens >= 1:
        for next_turn in range(2, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            if not (too_much_information(next_player_deck)):
                for c in next_player_deck:
                    if (c.value_info == 10) and (c.color_info == "") and (
                            c.value == g.fireworks[c.color] + 1):
                        give_info(g, next_player, 'value', c.value)
                        return

    # give a random information if there are a lot of info tokens instead of playing a random card
    # priority for the "4" when the game is near of its start
    if g.info_tokens >= 6:
        for next_turn in range(3, len(g.players)):
            next_player = g.players[(g.players.index(p) + next_turn) %
                                    len(g.players)]
            next_player_deck = next_player.deck
            for c in next_player_deck:
                if (c.value_info != 10) and (c.color_info == "") and (
                        c.value == 4) and (max(g.fireworks.values()) < 3):
                    give_info(g, next_player, 'value', 4)
                    return
            for c in next_player_deck:
                info = info_to_give(next_player_deck, c)
                if (c.value_info != 10) and (c.color_info
                                             == "") and (info == 'color'):
                    give_info(g, next_player, 'color', c.color)
                    return
                if (c.value_info
                        == 10) and (c.color_info != "") and (info == 'value'):
                    give_info(g, next_player, 'value', c.value)
                    return

    # try to put a random card if the game is almost done and there are still error tokens
    if (len(g.draw_pile) < 4) and g.error_tokens >= 2:
        for c in p.deck:
            if (c.color_info == "") and (c.value_info == 10):
                play_card(g, p, c)
                return

    # throw a random card (not a known useful "5") if no information about the deck
    if g.info_tokens < 8:
        for c in p.deck:
            if c.value_info != 5:
                discard(g, p, c)
                return

    # play a random card (rarely happens)
    for c in p.deck:
        if (c.color_info == "") and (c.value_info == 10):
            play_card(g, p, c)
            return
    for c in p.deck:
        if (c.color_info == "") and (c.value_info != 5):
            play_card(g, p, c)
            return
    for c in p.deck:
        if (c.color_info == "") or (c.value_info != 10):
            play_card(g, p, c)
            return
Пример #5
0
def neural_network_predictions(g, p, players_number, game_state, model):
    colors_list = ['blue', 'red', 'green', 'yellow', 'white']
    values_list = [1, 2, 3, 4, 5]

    ## encode the game state
    game_state.loc[0, 'info_tokens'] = g.info_tokens
    game_state.loc[0, 'error_tokens'] = g.error_tokens
    for color in ['blue', 'red', 'green', 'yellow', 'white']:
        game_state.loc[0, color + '_firework'] = g.fireworks[color]

    # deck information
    for c in p.deck:
        if c.color_info != "":
            game_state.loc[0, 'info : card ' + str(p.deck.index(c)) + ' is ' +
                           str(c.color_info)] = 1
        if c.value_info != 10:
            game_state.loc[0, 'info : card ' + str(p.deck.index(c)) + ' is ' +
                           str(c.value_info)] = 1

    # next players' deck
    for next_turn in range(1, players_number):
        next_player = g.players[(g.players.index(p) + next_turn) %
                                len(g.players)]
        next_player_deck = next_player.deck
        card_index = 0
        for c in next_player_deck:
            game_state.loc[0, 'player ' + str(next_turn) +
                           ' turn(s) after : card ' + str(card_index) +
                           ' is ' + str(c.color)] = 1
            game_state.loc[0, 'player ' + str(next_turn) +
                           ' turn(s) after : card ' + str(card_index) +
                           ' is ' + str(c.value)] = 1
            card_index += 1

    # next players' deck information
    for next_player in range(1, players_number):
        next_player_deck = g.players[((g.players.index(p)) + next_player) %
                                     players_number].deck
        for c in next_player_deck:
            if c.color_info != "":
                game_state.loc[0, 'player ' + str(next_player) +
                               ' turn(s) after : info : card ' +
                               str(next_player_deck.index(c)) + ' is ' +
                               str(c.color_info)] = 1
            if c.value_info != 10:
                game_state.loc[0, 'player ' + str(next_player) +
                               ' turn(s) after : info : card ' +
                               str(next_player_deck.index(c)) + ' is ' +
                               str(c.value_info)] = 1

    ## make a score prediction for each possible action and choose the best one

    if len(p.deck) == 4:
        possible_actions = list(game_state.columns[[392, 394, 396, 398]])
    else:
        possible_actions = list(game_state.columns[[392, 394, 396]])

    if g.info_tokens != 8:
        if len(p.deck) == 4:
            possible_actions += list(game_state.columns[[393, 395, 397, 399]])
        else:
            possible_actions += list(game_state.columns[[393, 395, 397]])

    if g.info_tokens > 0:
        for next_player in range(1, players_number):
            next_player_deck = g.players[((g.players.index(p)) + next_player) %
                                         players_number].deck

            for color in colors_list:
                for c in next_player_deck:
                    if c.color == color:
                        possible_actions.append('say to player ' +
                                                str(next_player) + ' the ' +
                                                color)
                        break

            for value in values_list:
                for c in next_player_deck:
                    if c.value == value:
                        possible_actions.append('say to player ' +
                                                str(next_player) + ' the ' +
                                                str(value))
                        break

    action_to_do = ""
    highest_action_score = -100
    for action in possible_actions:
        game_state.loc[0, 392:440] = 0
        game_state.loc[0, action] = 1
        action_score = model.predict(game_state).item()
        if action_score > highest_action_score:
            action_to_do = action
            highest_action_score = action_score

    ## execute the chosen action
    if 'play card' in action_to_do:
        play_card(g, p, p.deck[int(action_to_do[10])])
        return

    if 'discard card' in action_to_do:
        discard(g, p, p.deck[int(action_to_do[13])])
        return

    if 'say' in action_to_do:
        if ('blue' in action_to_do) or ('red' in action_to_do) or (
                'green' in action_to_do) or ('yellow' in action_to_do) or (
                    'white' in action_to_do):
            give_info(
                g, g.players[(g.players.index(p) + int(action_to_do[14])) %
                             players_number], 'color',
                action_to_do[20:len(action_to_do)])
            return
        else:
            give_info(
                g, g.players[(g.players.index(p) + int(action_to_do[14])) %
                             players_number], 'value', int(action_to_do[20]))
            return