def play(self, prev_card): """ Bot plays the best card from its hand, or passes by returning False. If bot plays a card, it also returns a list of actions. """ if not self.hand: raise Exception("Empty Hand") cards = [format_input(card, prev_card) for card in self.hand] output = [] schema = [2, 13, 4, 13, 4, 3, 2] if not self.valid_samples: return False tree = DecisionTree(self.valid_samples, schema) for card in cards: output.append(tree(card)) card = False for i in range(len(cards)): if output[i]: card = self.hand.pop(i) break if not card: return False actions = [] for i in range(len(self.actions)): max_class = max( [sample[0] for sample in self.action_samples[i]]) schema[0] = max_class action_tree = DecisionTree(self.action_samples[i], schema) actions.append(action_tree(card)) return card, actions
def add_sample(self, card, prev_card, is_valid, actions=[]): """ Adds a new sample for the bot to train on. actions is not needed if the move is invalid, and must always be a list, even if there is only one action. """ sample = format_input(card, prev_card) self.valid_samples.append([is_valid, *sample]) if is_valid: for i in range(len(actions)): self.action_samples[i].append([actions[i], *sample])
def make_action_sample(card, prev_card): actions = [0, 0, 0, 0, 0] if prev_card[0] == card[0]: actions[0] = 1 if card[0] == 5 or card[0] == 3 or card[1] == 2 or card[1] == 3: actions[1] = 1 if card[0] > 8: actions[2] = card[0] - 8 if card[0] == 8: actions[3] = 1 if card[0] == 0: actions[4] = 1 return [actions, *format_input(card, prev_card)]
def make_play_sample(card, prev_card): if prev_card[0] == card[0]: is_correct = True elif prev_card[1] == card[1]: if prev_card[0] == 3 and card[0] < 3: is_correct = 0 elif prev_card[0] == 5 and card[0] != 5: is_correct = False else: is_correct = True else: is_correct = False return [is_correct, *format_input(card, prev_card)]