예제 #1
0
	def __repr__(self):
		# type: () -> str
		"""
		:return: A concise string representation of the state in one line
		"""

		rep = "The game is in phase: {}\n".format(self.__phase)
		rep += "Player 1's points: {}, pending: {}\n".format(self.__p1_points, self.__p1_pending_points)
		rep += "Player 2's points: {}, pending: {}\n".format(self.__p2_points, self.__p2_pending_points)
		rep += "The trump suit is: {}\n".format(self.get_trump_suit())
		rep += "Player 1's hand:"

		for card in self.__deck.get_player_hand(1):
			rank, suit = util.get_card_name(card)
			rep += " {}{}".format(rank, suit)

		rep += "\n"
		rep += "Player 2's hand:"

		for card in self.__deck.get_player_hand(2):
			rank, suit = util.get_card_name(card)
			rep += " {}{}".format(rank, suit)

		rep += "\n"
		rep += "There are {} cards in the stock\n".format(self.__deck.get_stock_size())
		
		trick = self.__deck.get_trick()
		if trick[0] is not None:
			rep += "Player 1 has played card: {} of {}\n".format(util.get_rank(trick[0]), util.get_suit(trick[0]))
		if trick[1] is not None:
			rep += "Player 2 has played card: {} of {}\n".format(util.get_rank(trick[1]), util.get_suit(trick[1]))

		return rep
예제 #2
0
    def test_trump_jack_non_leading(self):
        state = State.generate(6)
        me = state.whose_turn()
        s1 = state.clone(signature=me)
        trump_suit = state.get_trump_suit()

        jacks = [
            move for move in s1.moves()
            if (move[0] == 4 or move[0] == 9 or move[0] == 14 or move[0] == 19)
        ]
        trump_jacks = [
            move for move in jacks if util.get_suit(move[0]) == trump_suit
        ]

        self.assertEqual(len(s1.moves()), 5 + len(trump_jacks))

        state = state.next(random.choice(state.moves()))
        s1 = state.clone(me)

        jacks = [
            move for move in state.moves()
            if (move[0] == 4 or move[0] == 9 or move[0] == 14 or move[0] == 19)
        ]
        trump_jacks = [
            move for move in jacks if util.get_suit(move[0]) == trump_suit
        ]

        self.assertGreater(len(trump_jacks), 0)
        self.assertEqual(len(state.moves()), 5)
예제 #3
0
def general_information(kb, state, index):  # Loads fuzzy symbols, gives them fuzzy values and adds them to fuzzy knowledge base
    RV = FuzzySymbol("rv", set_fuzzyRankValue(state, util.get_rank(index)))  # rank value
    TV = FuzzySymbol("tv", 0.01 if state.get_trump_suit() == util.get_suit(index) else 1.00)  # trump value
    SV = FuzzySymbol("sv", set_fuzzySuitValue(state, util.get_suit(index)))  # suit value
    
    kb.add_clause(RV)
    kb.add_clause(TV)
    kb.add_clause(SV)
예제 #4
0
def play(
        player1,
        player2,
        state,  # type: State
        max_time=5000,  # type: int
        verbose=True  # type: bool
):
    """
    Play a game between two given players, from the given starting state.
    """
    pr('player1: {}'.format(player1), verbose)
    pr('player2: {}'.format(player2), verbose)

    # The game loop
    while not state.finished():

        player = player1 if state.whose_turn() == 1 else player2

        move = get_move(state, player, max_time, verbose)

        check(move, player)  # check for common mistakes TODO

        if move[0] is None:
            pr(
                '*   Player {} performs a trump jack exchange'.format(
                    state.whose_turn()), verbose)
        else:
            pr(
                '*   Player {} plays: {}{}'.format(state.whose_turn(),
                                                   util.get_rank(move[0]),
                                                   util.get_suit(move[0])),
                verbose)
            if move[1] is not None:
                pr(
                    '*   Player {} melds a marriage between {}{} and {}{}'.
                    format(state.whose_turn(), util.get_rank(move[0]),
                           util.get_suit(move[0]), util.get_rank(move[1]),
                           util.get_suit(move[1])), verbose)

        state = state.next(move)
        pr(state, verbose)

        if not state.revoked() is None:
            pr(
                '!   Player {} revoked (made illegal move), game finished.'.
                format(state.revoked()), verbose)

    if state.finished():
        pr(
            'Game finished. Player {} has won, receiving {} points.'.format(
                state.winner()[0],
                state.winner()[1]), verbose)
    else:
        pr('Maximum turns exceed. No winner.', verbose)

    return state.winner() if state.finished() else None
예제 #5
0
def best_non_trump_card(state):
    """
    :param state: A state object
    :return: A move tuple representing the highest rank non-trump move available
    """

    # All legal moves
    moves = state.moves()
    chosen_move = moves[0]

    lowest_suit_moves = []

    #Get all moves which are not trump suit or matching the suit of the enemy's card
    for move in moves:

        if move[0] is not None and util.get_suit(
                move[0]) != state.get_trump_suit():
            lowest_suit_moves.append(move)

    if len(lowest_suit_moves) == 0:
        lowest_suit_moves = moves

    # Get move with highest rank available, of the subset that we've narrowed down so far
    for move in lowest_suit_moves:
        if move[0] is not None and move[0] % 5 <= chosen_move[0] % 5:
            chosen_move = move

    return chosen_move
예제 #6
0
    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()

        # Heuristic 1 - if possible, play a mariage.
        for move in moves:
            if move[0] != None and move[1] != None:
                # print('forcing a mariage {}'.format(move))
                if util.get_suit(move[1]) == state.get_trump_suit():
                    return move
                else:
                    return move

        # Heuristic 2 - if only 1 spouse in hand (and it's partner has not been played in the previous trick),
        # don't play it and keep it. Unless it's the only card in hand.

        # check if not the only card in hand
        prev_trick = state.get_prev_trick()
        if len(moves) > 1:
            for move in enumerate(moves):
                # remove single spouses (Kings and Queens) from moves if their partners were played in the previous trick.
                if move[1][0] in (2, 7, 12, 17):  # test if King
                    if prev_trick[0] not in (3, 8, 13, 18):
                        pass  # if card 1 from previous trick is not a queen, pass
                    if prev_trick[1] not in (3, 8, 13, 18):
                        pass  # if card 2 from previous trick is not a queen, pass
                    else:
                        # spouse detected in previous trick, remove from moves.
                        moves.pop(move[0])
                        # print('previous trick --> {}'.format(prev_trick))
                        # print(
                        #     'removed move {}, single spouse detected.'.format(move[1]))

                elif move[1][0] in (3, 8, 13, 18):  # test if queen
                    if prev_trick[0] not in (2, 7, 12, 17):
                        pass  # if card 1 from previous trick is not a king, pass
                    if prev_trick[1] not in (2, 7, 12, 17):
                        pass  # if card 2 from previous trick is not a king, pass
                    else:
                        # spouse detected in previous trick, remove from moves.
                        moves.pop(move[0])
                        # print('previous trick --> {}'.format(prev_trick))
                        # print(
                        #     'removed move {}, single spouse detected.'.format(move[1]))

        # Return a random choice
        return random.choice(moves)
예제 #7
0
    def get_move(self, state):

        moves = state.moves()

        random.shuffle(moves)

        trumpexmoves = []
        marriagemoves = []
        othermoves = []
        trumpmoves = []

        for move in moves:
            if move[0] is None:
                trumpexmoves.append(move)
            elif move[1] is not None:
                marriagemoves.append(move)
            elif util.get_suit(move[0]) == state.get_trump_suit():
                trumpmoves.append(move)
            else:
                othermoves.append(move)

        for move in trumpexmoves:
            if not self.kb_consistent_trumpex(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("Trump Strategy Applied")
                return move

        for move in marriagemoves:
            if not self.kb_consistent_marriage(state, move):
                # 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.
                # Plays the first move that makes the kb inconsistent. We do not take

                # print("Marriage Strategy Applied")
                return move
        if state.get_phase() == 1:
            if state.get_opponents_played_card() is None:
                if len(trumpmoves) != 0:
                    return highest_value(trumpmoves)
                else:
                    return highest_value(moves)
            else:
                for move in moves:
                    if check_card(state, move):
                        # print("HIGHEST SAME SUIT MOVE")
                        return move
                # print("LOWEST VALUE MOVE")
                return lowest_value(moves)
        else:
            if len(trumpmoves) != 0:
                return highest_value(trumpmoves)
            else:
                return highest_value(moves)
예제 #8
0
def lowest_winning_move(moves, opponents_card):
    """Returns the lowest ranking card that wins current trick against the card the opponent has played.
    If not possible, returns the lowest ranking card in hand.

    Args:
        moves (list): List of moves to choose from
        opponents_card (int): Index of card that opponent has played

    Returns:
        tuple: Schnapsen move
    """

    higher_same_suit = []  # possible moves that are higher rank and same suit as opponent's card
    for move in moves:
        if util.get_suit(move[0]) == util.get_suit(opponents_card) and move[0] % 5 < opponents_card % 5:
            higher_same_suit.append(move)

    if len(higher_same_suit) > 0:
        return lowest_rank_move(higher_same_suit)
    else:
        return lowest_rank_move(moves)
예제 #9
0
        def playerHeuristic():
            Bonus = 0
            if state.winner()[1] == 3:
                Bonus += 3
            elif state.winner()[1] == 2:
                Bonus += 1
            elif state.winner()[1] == 1:
                Bonus += 0

            if phase == 2:  # If game enters to the phase 2 at some point more trump cards means more points
                for card in phaseEnterence.moves():
                    if card[0] != None and util.get_suit(
                            card[0]) == state.get_trump_suit():
                        Bonus += 3

            for card in state.moves(
            ):  # And this is for ending the game with almost zero trumps in either case
                if card[0] != None and util.get_suit(
                        card[0]) != state.get_trump_suit():
                    Bonus += 3

            return 1 + Bonus if state.winner()[0] == self.player else 0
예제 #10
0
def play(
        player1,
        player2,
        state,  # type: State
        max_time=5000,  # type: int
        verbose=True  # type: bool
):
    """
    Play a game between two given players, from the given starting state.
    """
    pr('player1: {}'.format(player1), verbose)
    pr('player2: {}'.format(player2), verbose)
    # The game loop
    while not state.finished():

        player = player1 if state.whose_turn() == 1 else player2

        # We introduce a state signature which essentially obscures the deck's perfect knowledge from the player
        given_state = state.clone(
            signature=state.whose_turn()) if state.get_phase() == 1 else state

        move = get_move(given_state, player, max_time, verbose)

        if is_valid(move, player):  # check for common mistakes

            if move[0] is None:
                pr(
                    '*   Player {} performs a trump jack exchange'.format(
                        state.whose_turn()), verbose)

            else:
                pr(
                    '*   Player {} plays: {}{}'.format(state.whose_turn(),
                                                       util.get_rank(move[0]),
                                                       util.get_suit(move[0])),
                    verbose)

                if move[1] is not None:
                    pr(
                        '*   Player {} melds a marriage between {}{} and {}{}'.
                        format(state.whose_turn(), util.get_rank(move[0]),
                               util.get_suit(move[0]), util.get_rank(move[1]),
                               util.get_suit(move[1])), verbose)

            state = state.next(move)
            pr(state, verbose)

            if not state.revoked() is None:
                pr(
                    '!   Player {} revoked (made illegal move), game finished.'
                    .format(state.revoked()), verbose)

        else:
            state.set_to_revoked()

    pr(
        'Game finished. Player {} has won, receiving {} points.'.format(
            state.winner()[0],
            state.winner()[1]), verbose)

    return state.winner()
예제 #11
0
def is_trump(state, move):
    return util.get_suit(move) == state.get_trump_suit() if move is not None else "None move"
예제 #12
0
def is_trump(state, move):
    if util.get_suit(move) == state.get_trump_suit():
        return True
    else:
        return False
예제 #13
0
def check_card(state, move):
    if util.get_suit(move[0]) == util.get_suit(state.get_opponents_played_card()):
        if move[0] % 5 < state.get_opponents_played_card() % 5:
            return True
    return False
예제 #14
0
    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 = []

        # Heuristic 1 - If we have the trump jack in our hand, pick the trump jack exchange
        # (this makes our lowest trump card not a jack and therfore higher rank)
        for move in moves:
            if move[0] == None and move[1] != None:
                if move[1] in (4, 9, 14, 19):
                    # print('forcing trump jack exchange')
                    return move

        # Heuristic 2 - if possible, play a mariage.
        for move in moves:
            if move[0] != None and move[1] != None:
                # print('forcing a mariage {}'.format(move))
                if util.get_suit(move[1]) == state.get_trump_suit():
                    return move
                else:
                    return move

        # Heuristic 3 - If the opponent plays ace (highest) trump card
        # We play the lowest ranking card in hand (so opponent receives minimum points)

        opponents_card = state.get_opponents_played_card()
        if opponents_card is not None:
            # test if opponents card is a trump suit ace
            if opponents_card % 5 == 0 and Deck.get_suit(
                    opponents_card) == state.get_trump_suit():
                # print('opponent played a trump suit ace - {}'.format(opponents_card))
                # print('test - the trump suit is: {}'.format(state.get_trump_suit()))
                for index, move in enumerate(moves):
                    if move[0] is not None and move[0] % 5 > chosen_move[0] % 5:
                        # print('move {} is worth less then {}'.format(
                        #     move, chosen_move))
                        # print('playing move {}'.format(move))
                        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

        # 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
예제 #15
0
    def get_move(self, state):

        moves = state.moves()

        random.shuffle(moves)
        marriage_moves = []
        trumpex_moves = []
        other_moves = []
        trump_moves = []

        for move in moves:
            if move[0] is None:
                trumpex_moves.append(move)
            elif move[1] is not None:
                marriage_moves.append(move)
            elif is_trump(state, move[0]):
                trump_moves.append(move)
            else:
                other_moves.append(move)

        for move in trumpex_moves:
            if not self.kb_consistent(state, move, 0):
                # print("Trump Strategy Applied")
                return move

        for move in marriage_moves:
            if not self.kb_consistent(state, move, 1):
                # print("Marriage Strategy Applied")
                return move

        if state.get_phase() == 1:
            # print("phase 1")
            if state.get_opponents_played_card() is None:
                # print("phase 1, leading, play lowest non trump")
                return lowest_value(other_moves)
            else:
                # print("not leading")
                if is_trump(state, state.get_opponents_played_card()) is False and \
                        (state.get_opponents_played_card() % 5 == 0 or state.get_opponents_played_card() % 5 == 1):
                    if len(trump_moves) != 0:
                        # print("phase1, following, lowest trump card")
                        return lowest_value(trump_moves)
                    else:
                        # print("phase 1, following, lowest non trump")
                        return lowest_value(other_moves)
                elif is_trump(state, state.get_opponents_played_card()):
                    # print("phase 1, following, lowest non trump")
                    return lowest_value(other_moves)
                else:
                    same_suit = []
                    for move in other_moves:
                        if util.get_suit(move[0]) == util.get_suit(
                                state.get_opponents_played_card()):
                            same_suit.append(move)
                    # print("phase 1, following, same suit highest")
                    if len(same_suit) != 0:
                        highest_same_suit = highest_value(same_suit)
                        # print(highest_same_suit, state.get_opponents_played_card())
                        if highest_same_suit[
                                0] % 5 < state.get_opponents_played_card() % 5:
                            return highest_same_suit
                        else:
                            return lowest_value(other_moves)
                    else:
                        return lowest_value(other_moves)
        else:
            # print("phase 2")
            if state.get_opponents_played_card() is None:
                # print("leading")
                if len(trump_moves) != 0:
                    # print("phase 2, leading,  highest trump")
                    return highest_value(trump_moves)
                else:
                    # print("phase 2, leading, highest non-trump")
                    return highest_value(other_moves)
            else:
                # print("following")
                if len(trump_moves) != 0:
                    # print("phase 2, following, highest trump card")
                    return highest_value(trump_moves)
                else:
                    # print("phase 2, following, play random card")
                    return random.choice(moves)