def read_Card_Choose_Leaf_instruction(board, deck, player, players, Leaf_val): """ Function that takes the instructions given by a tree Leaf value and commits into doing its requested action. Some Leaf values require other imports such as AI_Functs, while others require computation of board/player status to proceed. O(n) runtime where n is the lenght of players or the size of player's hand (whichever is bigger) or Can recuse back to Main_Decision_Tree """ # print("AI instruction:", player.name, Leaf_val) if Leaf_val == "Play only card": allowed_cards = card_logic.card_allowed(board, player) # O(n) player.play_card(board, allowed_cards[0]) elif Leaf_val == "play wild, most common color": # search for wild card messy method hand_index = 0 for card in player.hand: # O(n) if card.color == "w": player.play_card(board, hand_index) break hand_index += 1 elif Leaf_val == "play most common color": color_max = AI_functs.fetch_most_common_color_playable(board, player) # O(n) allowed_cards = card_logic.card_allowed(board, player) # O(n) for i in allowed_cards: # O(n) if player.hand[i].color == color_max: player.play_card(board, i) break elif Leaf_val == "play most common type": type_max = AI_functs.fetch_most_common_type_playable(board, player) # O(n) allowed_cards = card_logic.card_allowed(board, player) # O(n) for i in allowed_cards: # O(n) if player.hand[i].type == type_max: player.play_card(board, i) break # figure out what do within the game from AI played card AI_card_logic.AI_card_played_type(board, deck, player, players) # O(n)
def extern_player_turn(board, deck, player, players, turn): drop_again = True while drop_again: turn_done = False selected = None # redraw display at start of human turn display_funct.redraw_screen([(player, None)], board, players) # grab the list of allowed_cards cards allowed_card_list = card_logic.card_allowed(board, player) # if no cards can be played end turn if len(allowed_card_list) == 0: print("no playable cards skipping and drawing\n\n") player.grab_card(deck) turn = compute_turn(players, turn, board.turn_iterator) return (player, turn) while not turn_done: (update, selected, turn_done) = intern_player_turn( board, deck, player, allowed_card_list, selected) check_winners(player) update = check_update(board, allowed_card_list, selected, player, players, update) # returns false unless a drop_again type card is played drop_again = card_logic.card_played_type(board, deck, player, players) return (player, turn)
def fetch_most_common_color_playable(board, player): """ Returns the most common color in a players hand that is also playable. O(n) runtime where n is the size of the players hand """ color_dict = dict() allowed_cards = card_logic.card_allowed(board, player) # O(n) for i in allowed_cards: # O(n) allowed_card = player.hand[i] if allowed_card.color == "w": # skip wild cards continue try: color_dict[allowed_card.color] = 0 except KeyError: color_dict[allowed_card.color] = 0 for card in player.hand: # O(n) if card.color in color_dict.keys(): color_dict[card.color] += 1 if color_dict == {}: # if no colors were prefered pick a random color return get_rand_color() return max(color_dict, key=color_dict.get) # O(4) only 4 colors
def read_Card_Choose_Tree_question(board, player, players, question): """ Function that takes a branches question and returns a tuple of two Logic values. Indicating wether to go left or right within the tree. (True, False) ==> go left (False, True) ==> go right Any other combination is considered incorrect O(n) runtime where n is the number of cards in a players hand """ # print("AI question:", player.name, question) if question == "Do I multiple playable cards?": if len(player.hand) > 1: return (True, False) else: return (False, True) elif question == "Do I have a nonwild playable card?": allowed_cards = card_logic.card_allowed(board, player) # O(n) for i in allowed_cards: # O(n) if not player.hand[i].color == "w": return (True, False) return (False, True) elif question == "what is my most common (color or type) that is also playable?": max_color = AI_functs.fetch_most_common_color_playable(board, player) # O(n) max_type = AI_functs.fetch_most_common_type_playable(board, player) # O(n) max_color_count = 0 max_type_count = 0 for card in player.hand: # O(n) if card.color == max_color: max_color_count += 1 if card.type == max_type: max_type_count += 1 if max_color_count >= max_type_count: return (True, False) else: return (False, True)
def fetch_oldest_card(board, player): """ Returns the oldest playable card card's index in players hand. O(n) runtime where n is the size of the players hand """ card_index = 0 maxi = 0 maxi_index = 0 playable_indexes = card_logic.card_allowed(board, player) # O(n) for card in player.hand: # O(n) if card.old_val >= maxi and not card.color == "w" and card_index in playable_indexes: maxi = card.old_val maxi_index = card_index card_index += 1 return (maxi, maxi_index)
def fetch_hate_cards(board, player): """ Returns a list of all the cards that are hateable that are playable. Returns both the card itself and its index in the players hand O(n) runtime where n is the size of the players hand """ hate_cards = [] card_index = 0 maxi = 0 maxi_index = 0 playable_indexes = card_logic.card_allowed(board, player) # O(n) for card in player.hand: # O(n) if card.type in ["d", "s", "p"] and card_index in playable_indexes: hate_cards.append((card, card_index)) card_index += 1 return hate_cards
def fetch_most_common_type_playable(board, player): """ Returns the most common card type from a players hand that is also playable. O(n) runtime where n is the size of the players hand """ type_dict = dict() allowed_cards = card_logic.card_allowed(board, player) for i in allowed_cards: # O(n) allowed_card = player.hand[i] try: type_dict[allowed_card.type] = 0 except KeyError: type_dict[allowed_card.type] = 0 for card in player.hand: # O(n) if card.type in type_dict.keys(): type_dict[card.type] += 1 return max(type_dict, key=type_dict.get) # worst O(15) all card types
def read_Dec_tree_question(board, player, players, question): """ Function that takes a branches question and returns a tuple of two Logic values. Indicating wether to go left or right within the tree. (True, False) ==> go left (False, True) ==> go right Any other combination is considered incorrect O(n) runtime where n is the length of players or the size of player's hand (whichever is larger) """ # print("AI question:", player.name, question) if question == "Can I win this turn?": wild_count = 0 for card in player.hand: # O(n) if card.color == "w": wild_count += 1 if wild_count >= len(player.hand) - 1: return (True, False) else: return (False, True) elif question == "Is there an apparent winner?": (winnners_bool, winners_list) = AI_functs.fetch_possible_winner( board, player, players) # O(n) if winnners_bool: return (True, False) else: return (False, True) elif question == "Can stop them winning it?": (winnners_bool, winners_list) = AI_functs.fetch_possible_winner( board, player, players) # O(n) playable_cards = card_logic.card_allowed(board, player) # O(n) for hand_index in playable_cards: # O(n) possible_card = player.hand[hand_index] if possible_card.type in ["p", "s", "d"]: # O(3) return (True, False) return (False, True) elif question == "Does oldest card play priority beat my hate play priority?": (old_val, card_index) = AI_functs.fetch_oldest_card(board, player) # O(n) (hate_val, hate_player) = AI_functs.fetch_hate_priority(player, players) # O(n) if hate_val <= old_val: # TODO return (True, False) else: return (False, True) elif question == "Do I have playable cards?": playable_cards = card_logic.card_allowed(board, player) # O(n) if len(playable_cards) > 0: return (True, False) else: return (False, True) elif question == "Do I multiple playable cards?": playable_cards = card_logic.card_allowed(board, player) # O(n) if len(playable_cards) > 1: return (True, False) else: return (False, True) elif question == "Do I have playable hate cards?": hate_cards = AI_functs.fetch_hate_cards(board, player) # O(n) if len(hate_cards) > 0: return (True, False) else: return (False, True)