def get_move(self, state): # type: (State) -> tuple[int, int] """ Function that gets called every turn. This is where to implement the strategies. Be sure to make a legal move. Illegal moves, like giving an index of a card you don't own or proposing an illegal mariage, will lose you the game. :param State state: An object representing the gamestate. This includes a link to the states of all the cards, the trick and the points. :return: A tuple of integers or a tuple of an integer and None, indicating a move; the first indicates the card played in the trick, the second a potential spouse. """ # All legal moves moves = state.moves() chosen_move = moves[0] # If it is the computers turn if state.get_opponents_played_card() is not None: case = [] # Store all cards of the same suit in an array for index, move in enumerate(moves): if move[0] is not None: if Deck.get_suit(move[0]) == Deck.get_suit(state.get_opponents_played_card()): case.append(move)
def findLowestPointsCard(self, state): smallestRank = None possibleRanks = ["A", "10", "K", "Q", "J"] position = None moves = state.moves() if len(moves) > 0: for index, move in enumerate(moves): # Iterate through all the possible moves, and find the lowest value card in your hand # Check whether 'J' is in your hand, if so play the card if Deck.get_rank(moves[index][0]) == possibleRanks[4]: smallestRank = possibleRanks[4] position = index break # Otherwise check for a Queen, and keep on checking maybe the Jack will be found later elif Deck.get_rank(moves[index][0]) == possibleRanks[3]: smallestRank = possibleRanks[3] position = index # and so forth elif Deck.get_rank( moves[index][0] ) == possibleRanks[2] and smallestRank != possibleRanks[3]: smallestRank = possibleRanks[2] position = index elif Deck.get_rank(moves[index][0]) == possibleRanks[1] and smallestRank != possibleRanks[2] \ and smallestRank != possibleRanks[3]: smallestRank = possibleRanks[3] position = index elif Deck.get_rank(moves[index][0]) == possibleRanks[0] and smallestRank != possibleRanks[1] \ and smallestRank != possibleRanks[2] and smallestRank != possibleRanks[3]: smallestRank = possibleRanks[4] position = index return position
def get_move(self, state): whose_turn = state.whose_turn() leader = state.leader() trump_suit = state.get_trump_suit() if whose_turn == leader: global kb moves = state.moves() # We look for a possible trump exchange for move in moves: if move[0] is None: return move # We look for a possible marriage for move in moves: if move[1] is not None: return move # We compare the bot's points with the threshold value and decide on playing hard. if state.get_points(whose_turn) >= 50: for move in moves: if Deck.get_suit(move[0]) == trump_suit: return move random.shuffle(moves) for move in moves: if not self.kb_consistent(state, move): # print "Strategy Applied" return move if random.randint(1, 2) == 1: # We play the highest possible card if none of the cards in hand is entailed by the KB chosen_move = moves[0] for index, move in enumerate(moves): if move[0] is not None and move[0] % 5 <= chosen_move[ 0] % 5: chosen_move = move return chosen_move else: # We play the lowest possible card if none of the cards in hand is entailed by the KB lowest_card, _ = moves[0] for move in moves: candidate_card, _ = move if candidate_card != None: if Deck.get_suit(candidate_card) != trump_suit: if candidate_card % 5 > lowest_card % 5: lowest_card = candidate_card if Deck.get_suit(lowest_card) == trump_suit: for move in moves: candidate_card, _ = move if candidate_card != None: if candidate_card % 5 > lowest_card % 5: lowest_card = candidate_card return (lowest_card, None) else: return self.returnMove(state)
def __evaluate_trick(self, trick): """ Evaluates who the winner of the specified trick is and returns it :param trick: A tuple signifying the trick which is evaluated :return: The winner's id as an integer """ if len(trick) != 2: raise RuntimeError("Incorrect trick format. List of length 2 needed.") if trick[0] is None or trick[1] is None: raise RuntimeError("An incomplete trick was attempted to be evaluated.") # If the two cards of the trick have the same suit if Deck.get_suit(trick[0]) == Deck.get_suit(trick[1]): # We only compare indices since the convention we defined in Deck # puts higher rank cards at lower indices, when considering the same color. return 1 if trick[0] < trick[1] else 2 if Deck.get_suit(trick[0]) == self.__deck.get_trump_suit(): return 1 if Deck.get_suit(trick[1]) == self.__deck.get_trump_suit(): return 2 # If the control flow has reached this point, the trick consists of two # different non-trump cards. Since the new leader is determined by the # output of this function, at this point the state object still considers # it to be the non-leading player's turn. Thus, we determine that the winner # is the other player, i.e. the leading player. Thanks: Daan Raven return util.other(self.whose_turn())
def get_move(self, state): # type: (State) -> tuple[int, int] """ Function that gets called every turn. This is where to implement the strategies. Be sure to make a legal move. Illegal moves, like giving an index of a card you don't own or proposing an illegal mariage, will lose you the game. TODO: add some more explanation :param State state: An object representing the gamestate. This includes a link to the states of all the cards, the trick and the points. :return: A tuple of integers or a tuple of an integer and None, indicating a move; the first indicates the card played in the trick, the second a potential spouse. """ # All legal moves moves = state.moves() chosen_move = moves[0] moves_trump_suit = [] moves_trump_suit = [] # If the opponent has played a card if state.get_opponents_played_card() is not None: moves_same_suit = [] # Get all moves of the same suit as the opponent's played card for index, move in enumerate(moves): if move[0] is not None and Deck.get_suit( move[0]) == Deck.get_suit( state.get_opponents_played_card()): moves_same_suit.append(move) #Get a card with higher rank than opponent and same suit as opponent if len(moves_same_suit) > 0: for index, move in enumerate(moves_same_suit): if move[0] is not None and move[0] % 5 < ( state.get_opponents_played_card() % 5): chosen_move = move return chosen_move # Get all trump suit moves available for index, move in enumerate(moves): if move[0] is not None and Deck.get_suit( move[0]) == state.get_trump_suit(): moves_trump_suit.append(move) if len(moves_trump_suit) > 0: chosen_move = moves_trump_suit[0] return chosen_move # Get move with lowest rank available, of any suit for index, move in enumerate(moves): if move[0] is not None and move[0] % 5 >= chosen_move[0] % 5: chosen_move = move return chosen_move
def get_move(self, state): # type: (State) -> tuple[int, int] """ Function that gets called every turn. This is where to implement the strategies. Be sure to make a legal move. Illegal moves, like giving an index of a card you don't own or proposing an illegal mariage, will lose you the game. TODO: add some more explanation :param State state: An object representing the gamestate. This includes a link to the states of all the cards, the trick and the points. :return: A tuple of integers or a tuple of an integer and None, indicating a move; the first indicates the card played in the trick, the second a potential spouse. """ # All legal moves moves = state.moves() chosen_move = moves[0] move_trump_suit = [] for index, move in enumerate(moves): if move[0] is not None and Deck.get_suit(move[0]) == state.get_trump_suit(): move_trump_suit.append(move) if len(move_trump_suit) > 0 : chosen_move = move_trump_suit[0] return chosen_move if state.get_opponents_played_card() is not None : move_same_suit = [] move_lowest = [] for index, move in enumerate(moves): if Deck.get_suit(move[0]) == Deck.get_suit(state.get_opponents_played_card()): if move[0] is not None and move[0] % 5 < state.get_opponents_played_card() % 5 : move_same_suit.append(move) elif move[0] is not None and move[0] % 5 > chosen_move[0] % 5: move_lowest.append(move) if len(move_same_suit) > 0 : chosen_move = move_same_suit[0] return chosen_move elif len(move_lowest) > 0 : chosen_move = move_lowest[0] return chosen_move for index, move in enumerate(moves): if move[0] is not None and move[0] % 5 <= chosen_move[0] % 5: chosen_move = move # Return a random choice return chosen_move
def how_many_card_can_beat_it(state, myList, card) -> int: # see how many trump cards exist that are better cardsThatCanBeatMyCard = 0 for ints in myList: ints = int(ints) # print(ints,card[0]) if (ints % 5 < card[0] % 5) or \ (Deck.get_suit(card[0]) != state.get_trump_suit() and Deck.get_suit(ints) == state.get_trump_suit()): cardsThatCanBeatMyCard += 1 return cardsThatCanBeatMyCard
def findLowestCardOfSameSuit(self, state): lowestRank = None position = None # All possible moves moves = state.moves() # Opponents card suit opponentsCardSuit = Deck.get_suit(state.get_opponents_played_card()) moves_suit = [] # Get all the moves available with the same suit as opponent's played card suit for index, move in enumerate(moves): if moves[index][0] is not None and Deck.get_suit( moves[index][0]) == opponentsCardSuit: moves_suit.append(move) # Check your hand for same suit cards as opponent # If opponent's card rank is '10' check for lowest value card which is 'J' if len(moves_suit) > 0: for index, move in enumerate(moves_suit): if Deck.get_rank(moves_suit[index][0]) == "J" \ and Deck.get_suit(moves_suit[index][0]) == opponentsCardSuit: lowestRank = "J" break # otherwise check for the next lowest value which is 'Q' elif Deck.get_rank(moves_suit[index][0]) == "Q" \ and Deck.get_suit(moves_suit[index][0]) == opponentsCardSuit: lowestRank = "Q" # and so forth elif Deck.get_rank(moves_suit[index][0]) == "K" \ and Deck.get_suit(moves_suit[index][0]) == opponentsCardSuit \ and lowestRank != "Q": lowestRank = "K" # also this function will not play high value cards like '10' and 'A' # becaues in our strategy we are saving the high value card for future # possible cases when we could win the hand # If there is such a card with a smaller value than the opponent's # played card and of the same suit, return the index for index, move in enumerate(moves): if Deck.get_rank(moves[index][0]) == lowestRank \ and Deck.get_suit(moves[index][0]) == opponentsCardSuit: position = index break return position
def returnMove(self, state): moves = state.moves() trump_suit = state.get_trump_suit() played_card = state.get_opponents_played_card() # If we are past the threshold, reply to a trump with highest trump, else trump with lowest trump if Deck.get_suit( played_card) == trump_suit: # Check if played card is trump for move in moves: candidate_card, _ = move if candidate_card != None: if Deck.get_suit( candidate_card ) == trump_suit: # Still not checking for the lowest possible trump card if candidate_card % 5 < played_card % 5: return (candidate_card, None) lowest_card, _ = moves[0] for move in moves: candidate_card, _ = move if candidate_card != None: if Deck.get_suit( candidate_card ) != trump_suit: # Logic will still give exception if nothing is present other than trump cards, which is absurd, because that is not possible (think about it) if candidate_card % 5 > lowest_card % 5: lowest_card = candidate_card return (lowest_card, None) for move in moves: # Else try to find a stronger card of same suit candidate_card, _ = move if candidate_card != None: if Deck.get_suit(candidate_card) == Deck.get_suit(played_card): if candidate_card % 5 < played_card % 5: return (candidate_card, None) for move in moves: # Else try to find a a card from trump suit candidate_card, _ = move if candidate_card != None: if Deck.get_suit(candidate_card) == trump_suit: return (candidate_card, None) lowest_card, _ = moves[0] for move in moves: # By this position, losing the trick is certain, so we try and find the lowest card candidate_card, _ = move if candidate_card != None: if Deck.get_suit(candidate_card) != trump_suit: if candidate_card % 5 > lowest_card % 5: lowest_card = candidate_card if Deck.get_suit(lowest_card) == trump_suit: for move in moves: candidate_card, _ = move if candidate_card != None: if candidate_card % 5 > lowest_card % 5: lowest_card = candidate_card return (lowest_card, None)
def get_suit(card_index): """ Returns the suit of a card :param card_index: :return: """ return Deck.get_suit(card_index)
def get_rank(card_index): """ Returns the rank of a card :param card_index: :return: """ return Deck.get_rank(card_index)
def get_move(self, state): # type: (State) -> tuple[int, int] """ Function that gets called every turn. This is where to implement the strategies. Be sure to make a legal move. Illegal moves, like giving an index of a card you don't own or proposing an illegal mariage, will lose you the game. TODO: add some more explanation :param State state: An object representing the gamestate. This includes a link to the states of all the cards, the trick and the points. :return: A tuple of integers or a tuple of an integer and None, indicating a move; the first indicates the card played in the trick, the second a potential spouse. """ # All legal moves moves = state.moves() for move in moves: if move[0] != None and move[1] != None: return move elif state.get_opponents_played_card(): if state.get_opponents_played_card( ) % 5 == 1 or state.get_opponents_played_card() % 5 == 0: if Deck.get_suit(move[0]) == state.get_trump_suit(): return move #Trump exchange elif move[0] == None and move[1] != None: return move return moves[0]
def generate(id=None, phase=1): """ :param id: The seed used for random generation. Defaults at random, but can be set for deterministic state generation :param phase: The phase at which your generated state starts at :return: A starting state generated using the parameters given """ rng = random.Random(id) deck = Deck.generate(id) player1s_turn = rng.choice([True, False]) state = State(deck, player1s_turn) if phase == 2: while state.__phase == 1: if state.finished(): return State.generate(id if id is None else id+1, phase) # Father forgive me state = state.next(rng.choice(state.moves())) total_score = state.__p1_points + state.__p2_points state.__set_points(1, int(total_score/2)) state.__p1_pending_points = 0 state.__set_points(2, int(total_score/2)) state.__p2_pending_points = 0 return state
def get_trump_moves(state, moves): trump_moves = [] for move in moves: if move[0] is not None and Deck.get_suit( move[0]) == state.get_trump_suit(): trump_moves.append(move) return trump_moves
def load_from_json(dict): state = State(Deck.load_from_json(dict['deck']), dict['player1s_turn'], dict['p1_points'], dict['p2_points'], dict['p1_pending_points'], dict['p2_pending_points']) state.__phase = dict['phase'] state.__leads_turn = dict['leads_turn'] state.__revoked = dict['revoked'] return state
def getTrumpMoves(self, state, moves): new_moves = copy.deepcopy(moves) trump_suit = state.get_trump_suit() for move in new_moves: card, _ = move if Deck.get_suit(card) != trump_suit: new_moves.remove(move) return new_moves
def eval_points(opponents_card, move): if opponents_card is None or move is None: raise RuntimeError( "An incomplete trick was attempted to be evaluated.") # If the two cards of the trick have the same suit if Deck.get_suit(opponents_card[0]) == Deck.get_suit(move[0]): # We only compare indices since the convention we defined in Deck # puts higher rank cards at lower indices, when considering the same color. return 1 if opponents_card < move else 2 if Deck.get_suit(opponents_card[0]) == self.__deck.get_trump_suit(): return 1 if Deck.get_suit(move[0]) == self.__deck.get_trump_suit(): return 2
def kb_consistent(self, state, move): # type: (State, move) -> bool index = move[0] if (Deck.get_suit(index) == state.get_trump_suit()): return True if (Deck.get_rank(index) == "A"): return False kb = self.prepareKB(state) load.strategy_knowledge(kb) variable_string = "pc" + str(index) strategy_variable = Boolean(variable_string) kb.add_clause(~strategy_variable) return kb.satisfiable()
def test_generate(self): d = Deck.generate(0) stock = d.get_card_states().count("S") self.assertEqual(stock, 10, "The value should be 10") player1 = d.get_card_states().count("P1H") self.assertEqual(player1, 5, "The value should be 5") player2 = d.get_card_states().count("P2H") self.assertEqual(player2, 5, "The value should be 5")
def get_move(self, state): # type: (State) -> tuple[int, int] """ Function that gets called every turn. This is where to implement the strategies. Be sure to make a legal move. Illegal moves, like giving an index of a card you don't own or proposing an illegal mariage, will lose you the game. TODO: add some more explanation :param State state: An object representing the gamestate. This includes a link to the states of all the cards, the trick and the points. :return: A tuple of integers or a tuple of an integer and None, indicating a move; the first indicates the card played in the trick, the second a potential spouse. """ # All legal moves moves = state.moves() # starting with a random move chosen_move = random.choice(moves) # List of all legal moves, not being of a trump suit not_trump_suit = [] # Which player this bot is player = state.whose_turn() leader = state.leader # If a mariage or jack exchange is possible, play it for index, move in enumerate(moves): if move[1] != None: return move # Get all not trump suit moves for index, move in enumerate(moves): if move[0] is not None and Deck.get_suit( move[0]) != state.get_trump_suit(): not_trump_suit.append(move) # starting with a random move if len(not_trump_suit) > 0: chosen_move = random.choice(not_trump_suit) # play the highest not trump cards first if len(not_trump_suit ) > 0 and player == leader and not_trump_suit != []: for index, move in enumerate(not_trump_suit): if move[0] is not None and move[0] % 5 <= chosen_move % 5: chosen_move = move return chosen_move # if player != leader: # played_card = state.get_opponents_played_card() # suit_of_card = Deck.get_suit(played_card) # for index, move in enumerate(moves): # if move[0] is not None and Deck.get_suit(move[0]) return chosen_move
def get_move(self, state): # type: (State) -> tuple[int, int] """ Function that gets called every turn. This is where to implement the strategies. Be sure to make a legal move. Illegal moves, like giving an index of a card you don't own or proposing an illegal mariage, will lose you the game. TODO: add some more explanation :param State state: An object representing the gamestate. This includes a link to the states of all the cards, the trick and the points. :return: A tuple of integers or a tuple of an integer and None, indicating a move; the first indicates the card played in the trick, the second a potential spouse. """ # All legal moves moves = state.moves() chosen_move = moves[0] if state.get_phase() == 2: chosen_move = moves[len(moves) - 1] # If the opponent has played a card if state.get_opponents_played_card() is not None: moves_same_suit = [] # Get all moves of the same suit as the opponent's played card for index, move in enumerate(moves): if move[0] is not None and Deck.get_suit( move[0]) == Deck.get_suit( state.get_opponents_played_card()): moves_same_suit.append(move) # Play the cheapest card in phase two if you cant beat the trick, else play the highest card if len(moves_same_suit) > 0: if state.get_phase() == 2 and ( state.get_opponents_played_card() % 5 < moves_same_suit[0][0]): return moves_same_suit[len(moves_same_suit) - 1] chosen_move = moves_same_suit[0] return chosen_move return chosen_move
def get_move(self, state): moves = state.moves() random.shuffle(moves) for move in moves: if not self.kb_consistent(state, move): # Plays the first move that makes the kb inconsistent. We do not take # into account that there might be other valid moves according to the strategy. # Uncomment the next line if you want to see that something happens. # print "Strategy Applied" print(str(Deck.get_rank(move[0]) + Deck.get_suit(move[0])), " has been played") #str(Deck.get_rank(move[0]) + Deck.get_suit(move[0])) return move # If no move that is entailed by the kb is found, play random move return random.choice(moves)
def kb_consistent_matching_win(self, state, move): # type: (State,move) -> bool kb = KB() load_justabout.general_information(kb) load_justabout.strategy_knowledge(kb) opp_card = state.get_opponents_played_card() opp_card_suit = Deck.get_suit(opp_card) opp_card_rank = opp_card % 5 p_card = move[0] p_card_suit = Deck.get_suit(p_card) p_card_rank = opp_card % 5 variable_string = "wt" + str(p_card_rank) + str(opp_card_rank) + str(p_card_suit) + str(opp_card_suit) strategy_variable = Boolean(variable_string) kb.add_clause(~strategy_variable) return kb.satisfiable()
def kb_consistent_trump_win(self,state,move): # type: (State,move) -> bool kb = KB() load_justabout.general_information(kb) load_justabout.strategy_knowledge(kb) opp_card = state.get_opponents_played_card() opp_card_suit = Deck.get_suit(opp_card) opp_card_rank = opp_card & 5 p_card = move[0] p_card_suit = Deck.get_suit(p_card) p_card_rank = p_card % 5 trump_suit = state.get_trump_suit() constraint_a = Integer('me') > Integer('op') constraint_b = Integer('op') > Integer('me') if opp_card_suit == trump_suit: if p_card_suit == trump_suit: if opp_card_rank < p_card_rank: strategy_variable = constraint_b else: strategy_variable = constraint_a else: strategy_variable = constraint_b else: variable_string = "wtt" + str(p_card_suit) + str(trump_suit) strategy_variable = Boolean(variable_string) kb.add_clause(~strategy_variable) return kb.satisfiable()
def load_from_json(dict): """ Creates a new state object from a JSON representation Output from convert_to_json function must be given to json.loads() before being handed to this function, as it is a string initially. Written for the user interface """ state = State(Deck.load_from_json(dict['deck']), dict['player1s_turn'], dict['p1_points'], dict['p2_points'], dict['p1_pending_points'], dict['p2_pending_points']) state.__phase = dict['phase'] state.__leads_turn = dict['leads_turn'] state.__revoked = dict['revoked'] return state
def get_move(self, state): moves_trump_suit = [] if random.random() < self.__non_trump_move: # IMPLEMENT: Make the best non-trump move you can. Use the best_non_trump_card method written below. # bully bot moves = state.moves() chosen_move = moves[0] # take the 1st available #Get all trump suit moves available for index, move in enumerate(moves): if move[0] is not None and Deck.get_suit(move[0]) == state.get_trump_suit(): moves_trump_suit.append(move) # find all cards same suit if len(moves_trump_suit) > 0: chosen_move = moves_trump_suit[0] # choose the 1st trump-suit card return chosen_move # No trump suit moves available: # # If the opponent has played a card # if state.get_opponents_played_card() is not None: # # moves_same_suit = [] # # # Get all moves of the same suit as the opponent's played card # for index, move in enumerate(moves): # if move[0] is not None and Deck.get_suit(move[0]) == Deck.get_suit(state.get_opponents_played_card()): # moves_same_suit.append(move) # # if len(moves_same_suit) > 0: # chosen_move = moves_same_suit[0] # return chosen_move # # # Get move with highest rank available, of any suit # for index, move in enumerate(moves): # if move[0] is not None and move[0] % 5 <= chosen_move[0] % 5: # chosen_move = move # # return chosen_move #IMPLEMENT: Make a random move (but exclude the best non-trump move from above) moves_none_trump = list(set(state.moves()) - set(moves_trump_suit)) # Return a random choice return random.choice(moves_none_trump)
def check_marriage(self, state, moves): possible_marriages = [] for index in moves: if index[0] is not None and index[1] is not None: possible_marriages.append(index) # Check for royal marriages if possible_marriages: possible_royal_marriages = [] for index in possible_marriages: if Deck.get_suit(index[0]) == state.get_trump_suit(): possible_royal_marriages.append(index) return possible_royal_marriages return possible_marriages
def get_number_trumps_or_ace(state, Deck): moves = state.moves() util_point = 0 for move in moves: if move[0] is not None and Deck.get_suit( move[0]) == state.get_trump_suit(): util_point += 1 if move[0] is not None and move[0] % 5 == 0: util_point += 1 return util_point / len(moves)
def test_trump_exchange(self): d = Deck.generate(0) print d.get_trump_suit() print d.get_card_states() if d.can_exchange(1): print "1 exchanged" d.exchange_trump() print d.get_card_states() elif d.can_exchange(2): print "2 exchanged" d.exchange_trump() print d.get_card_states() else: print "no one exchanged"
def test_clone(self): deck = Deck.generate(0) state = State(deck,True) clone = state.clone() self.assertEqual(state.finished(), clone.finished()) self.assertEqual(state.revoked(), clone.revoked()) self.assertEqual(state.winner(), clone.winner()) current_deck = state.get_deck() clone_deck = clone.get_deck() self.assertEqual(current_deck.get_card_states(), clone_deck.get_card_states()) pass