def forward_checking(self, domain): # check the domain with variables(c1,c2,..) # to play next card we take a rule from satisfing domain # if next card is illegal, that means our constraint (next card is legal) is failed, # so remove(prune) it from domain and repeat with another rule satisfyingDomain = [] n = len(self.prevCards) if n < 3: return domain for rule in domain: p = new_eleusis.parse(rule) legalValue = False s = self.prevCards for i in range(0, len(self.prevCards) - 2, 1): cards = (self.prevCards[i][0], self.prevCards[i + 1][0], self.prevCards[i + 2][0]) try: legalValue = p.evaluate(cards) except: pass if not legalValue: break if legalValue: satisfyingDomain.append(rule) return satisfyingDomain
def test_hypothesis(self, player_rule_expression): """ Test hypothesis against rule for all possible cards. If the hypothesis is correct for those all cards, return True. If it does not pass all cards test, add 15 to the playerScore and return False. This decision tree will always produce a rule that describes the current board. input: output: True if correct, False otherwise returns: score with expression """ num_correct = 0 trials = 52*52*52 # for trial in range(0, trials): for card0 in self.get_shuffled_deck(): for card1 in self.get_shuffled_deck(): for card2 in self.get_shuffled_deck(): # use our_rule to pick a card, then play that card. Test against dealer_rule god_result = self.__rule_obj.evaluate((card0, card1, card2)) if (god_result == 'False') or (god_result is False): god_result = False else: god_result = True player_rule_obj = new_eleusis.parse(player_rule_expression) our_result = player_rule_obj.evaluate((card0, card1, card2)) if (our_result == 'False') or (our_result is False): our_result = False else: our_result = True if god_result == our_result: num_correct += 1 # print results percent_correct = (num_correct * 1.0) / trials return percent_correct * 75
def decide_success(self): # get the current rule and history current_rule = self.get_rule() history_length = len(self.thinker.history) self.confidence = 1 # if there is a rule, evaluate it and see if we need to declare if not current_rule is None: try: # pars the rule and get the requireed info parsed_rule = new_eleusis.parse(current_rule[0]) efficiency = current_rule[1][0] equivalence = current_rule[1][1] rule_length = len(current_rule[0]) # get the factors of the min_plays that will be used in order to decide factor = [(i * min_plays) for i in range(1, 11)] #if there have been more than min plays if history_length >= min_plays: # if the current rule has 100 efficiency and 100 equivalence if efficiency == 100 and equivalence == 100: # if the length of the rule is less than factor[i + 2] or # the plays is some value with a factor[i] for i in range(0, 11): rule_length_limit = 0 factor_limit = 0 # if the index is less than 7 if i < 7: factor_limit = factor[i + 2] rule_length_limit = factor[i + 3] elif i == 7: factor_limit = factor[i + 1] rule_length_limit = factor[i + 2] elif i == 8: factor_limit = factor[i + 1] rule_length_limit = factor[i + 1] else: factor_limit = factor[i] rule_length_limit = factor[i] if rule_length <= rule_length_limit or history_length >= factor_limit: self.confidence = self.confidence * 1.0 return current_rule # if the current rule has 100 efficiency or 100 equivalence elif efficiency == 100 or equivalence == 100: # if the history is if history_length >= factor[ 2] and rule_length <= factor[4]: self.confidence = self.confidence * 0.75 return current_rule elif history_length >= factor[3]: self.confidence = self.confidence * 0.50 return current_rule # if the current rule is not as efficient as we like, show rule if max plays have been made elif history_length >= max_plays: self.confidence = self.confidence * 0.25 return current_rule except: self.confidence = self.confidence * 0.0 if history_length >= max_plays: return current_rule return None
def set_rule(self, rule_expression): """ please check readMe file to know the syntax and semantics of rule expression. :type rule_expression: rule expression string """ self.__rule_expression = rule_expression self.__rule_obj = new_eleusis.parse(rule_expression)
def get_best_card(self): index = -1 try: correct_indeces = [] incorrect_indeces = [] player_rule = new_eleusis.parse(self.rule[0]) # for all the cards in the hand, assign correct or # incorrect against the player's current rule for i in range(0, len(self.hand)): last_three = self.get_last_three(self.hand[i], self.board, -1) if self.evaluate_card(last_three, player_rule): correct_indeces.append(i) else: incorrect_indeces.append(i) # if the last play made was a positive test, play a negative if self.last_play_positive: self.last_play_positive = False # if there are incorrect cards in the hand if len(incorrect_indeces) > 0: index = incorrect_indeces[random.randint( 0, len(incorrect_indeces) - 1)] for i in range(0, len(incorrect_indeces)): if self.hand[index] in self.board[-1][1]: index = incorrect_indeces[random.randint( 0, len(incorrect_indeces) - 1)] else: break if self.hand[index] in self.board[-1][1]: index = correct_indeces[random.randint( 0, len(correct_indeces) - 1)] else: index = correct_indeces[random.randint( 0, len(correct_indeces) - 1)] else: self.last_play_positive = True # if there are correct cards in the hand if len(correct_indeces) > 0: index = correct_indeces[random.randint( 0, len(correct_indeces) - 1)] else: index = incorrect_indeces[random.randint( 0, len(incorrect_indeces) - 1)] except: # if the rule evaluation fails index = -1 #play the card with the corresponding index return self.get_card_from_hand(index)
def setRule(expression): """ Set the current dealer rule, using the functions provided in new_eleusis.py Inputs: String expression of dealer's rule Outputs: None """ # Save expression as a global variable, ruleExpression global rule_expression, dealer_rule rule_expression = expression # Use Tree's parse(expression) to create Tree of rule dealer_rule = ne.parse(rule_expression)
def play(self, card): # checks if a card is legal or not if self.rule() == "": return True parsedGodRule = new_eleusis.parse(self.rule()) n = len(self.boardState()) if n < 3: return True else: tuple3 = (self.prevCards[n - 2][0], self.prevCards[n - 1][0], card) try: legalValue = parsedGodRule.evaluate(tuple3) except: print "god rule can't evaluate" exit() return legalValue
def prioritize_rules(self, rules): evaluation = [] for rule in rules: efficiency = 0.0 equivalence = 0.0 try: parsed_rule = new_eleusis.parse(rule) efficiency = self.get_efficiency(parsed_rule) equivalence = self.get_equivalence(parsed_rule) evaluation.append((rule, (efficiency, equivalence))) except: evaluation.append((rule, (efficiency, equivalence))) return sorted(evaluation, key=lambda tuple: (tuple[1][0], tuple[1][1], -(len(tuple[0]))))
def __init__(self, cards, rule = None, randomPlay = False): self.deck = Deck(6) self.history = [] self.deck.shuffle() self.truthTable = [] self.randomPlay = randomPlay self.dealer_rule = None if rule is not None: self.dealer_rule = new_eleusis.parse(rule) self.recordPlay(cards, True) self.provided_rule = rule self.guessed_rules = []
def score(scientist, rule, score, is_ending_player): efficiency = 0.0 equivalence = 0.0 if rule is None: score = score + 30 try: parsed_rule = new_eleusis.parse(rule) efficiency = scientist.get_efficiency(parsed_rule) equivalence = scientist.get_equivalence(parsed_rule) if efficiency != 100.0: score = score + 15 if equivalence == 100.0: score = score - 75 if is_ending_player: score = score - 25 else: score = score + 30 except: score = score + 45 return (score, efficiency, equivalence)
def play_card(self): """ :return: next card to be returned """ guess = True if self.num_correct > self.num_incorrect: guess = False else: guess = True if self.num_consecutive_correct >= self.confidence_value: return None for i in range(0, len(self.our_hand)): our_rule_obj = new_eleusis.parse(self.our_rule_expression) board_state = self.god_instance.get_board_state() our_result = our_rule_obj.evaluate( (board_state[-2][0], board_state[-1][0], self.our_hand[i])) our_result = bool(our_result) if our_result == guess: self.card_played = self.our_hand[i] return self.our_hand[i] self.card_played = self.our_hand[0] return self.our_hand[0]
def play(self, card): if card == None: return print "Play number: {} playedcard: {}".format(self.cardsPlayed, card) if self.cardsPlayed >= 200: self.declareRule() self.cardsPlayed += 1 if self.cardsPlayed % 10 == 0: self.possibleRules = self.forward_checking(self.possibleRules) n = len(self.prevCards) self.parsedGodRule = new_eleusis.parse(self.rule) if n == 0: tuple3 = ("", self.random_card(), card) elif 0 < n <= 1: tuple3 = ("", self.prevCards[n - 1][0], card) else: tuple3 = (self.prevCards[n - 2][0], self.prevCards[n - 1][0], card) try: legalValue = self.parsedGodRule.evaluate(tuple3) except: print "god rule can't evaluate" exit() self.updateBoardState(card, legalValue)
def pickCardToTest(self, rule): try: p = new_eleusis.parse( rule) # if not parse pick different rule to do except: self.evaluateFail(rule) return self.random_card() n = len(self.prevCards) r = self.random_card() if n == 0: print "not enough cards" elif n == 1: cards = ("", self.prevCards[n - 1][0], r) else: cards = (self.prevCards[n - 2][0], self.prevCards[n - 1][0], r) try: b = p.evaluate(cards) self.playingLegalCard = b return r except: self.evaluateFail(rule) return self.random_card()
def setRule(self, expression): self.ruleExpression = expression self.ruleTree = new_eleusis.parse(expression)
def set_rule(self, dealer_rule, player_rule): self.dealer_rule = new_eleusis.parse(dealer_rule)
def scientist(): """ This function returns the rule your player has found. It is responsible for the inductive task, that is, figuring out the rule. When called, this function is responsible for making plays, considering the information gained, dealing with hypotheses*, and choosing when (after 20+ plays) to declare success and return a rule. Inputs: None Outputs: Expression for current hypothesis if it thinks it is right, returns 'None' otherwise. :return: """ global cards_played, decision_tree, our_rule, our_expression, guess_true, our_hand, we_returned_rule, num_adversaries, our_turn num_correct = 0 num_adversaries = 3 adv_stop = [] for adv in range(num_adversaries): adv_stop.append(random.randrange(180) + 20) print "adversary limits: " + str(adv_stop) our_hand = get_shuffled_deck()[0:13] # build initial rule decision_tree.build_tree() our_expression = decision_tree.get_hypo_expression() our_rule = ne.parse(our_expression) while cards_played < 200: # our turn # decide whether or not to return hypothesis # print "cards played: " + str(cards_played) if num_correct > 50: we_returned_rule = True print "Our confident player is a real genius, and has decided to return a rule!" return our_expression # play our card card = select_next_card() print "card[" + str(cards_played) + "]: we play the " + card our_turn = True result = play(card) # Look at board state to determine if current hypothesis is # consistent. Otherwise, update hypothesis if result != guess_true: # update hypothesis with new information num_correct = 0 decision_tree.build_tree() our_expression = decision_tree.get_hypo_expression() our_rule = ne.parse(our_expression) else: num_correct += 1 if cards_played < 20: decision_tree.build_tree() our_expression = decision_tree.get_hypo_expression() our_rule = ne.parse(our_expression) # play adversary cards for adv in range(num_adversaries): # decide to randomly return rule if adv_stop[adv] <= cards_played: we_returned_rule = False print "Adversary " + str(adv) + " has audaciously decided to return a rule!" return our_expression # play random card card = get_shuffled_deck()[0] my_result = our_rule.evaluate((board[-2][0], board[-1][0], card)) our_turn = False print "card[" + str(cards_played) + "]: adv[" + str(adv) + "] plays " + card result = play(card) # update board if result != my_result: # update hypothesis with new information num_correct = 0 decision_tree.build_tree() our_expression = decision_tree.get_hypo_expression() our_rule = ne.parse(our_expression) else: num_correct += 1 if cards_played < 20: decision_tree.build_tree() our_expression = decision_tree.get_hypo_expression() our_rule = ne.parse(our_expression)