Пример #1
0
    def payForPurchasedCard(self, player: Player, coins_table: CoinsTable):
        for coin in CoinTypes:
            if coin != CoinTypes.UNKNOWN and coin != CoinTypes.ANY_COLOR:
                assert (player.getMaxBuyPrice(coin) >=
                        self.taken_card.getCost(coin)
                        ), "not enough coins ({0}) to buy card {1}".format(
                            coin.name, self.taken_card)
                coins_to_pay = self.taken_card.getCost(
                    coin) - player.getPurchasedCardsCount(coin)
                if coins_to_pay < 0:
                    coins_to_pay = 0

                coins_remainder = player.getCoinsCount(coin) - coins_to_pay

                if coins_remainder < 0:
                    self.paid_coins_count[coin] = player.getCoinsCount(coin)
                    player.returnCoins(coin, player.getCoinsCount(coin))
                    coins_table.returnCoins(coin, player.getCoinsCount(coin))
                    self.paid_coins_count[coin] = -coins_remainder
                    player.returnCoins(CoinTypes.ANY_COLOR, -coins_remainder)
                    coins_table.returnCoins(CoinTypes.ANY_COLOR,
                                            -coins_remainder)
                else:
                    self.paid_coins_count[coin] = coins_to_pay
                    player.returnCoins(coin, coins_to_pay)
                    coins_table.returnCoins(coin, coins_to_pay)
Пример #2
0
    def test_coins_table(self):
        coins_table = CoinsTable()

        self.assertEqual(CoinsTable.max_coins_count, coins_table.getCoinsCount(CoinTypes.BLACK))

        coins_table.takeCoins(CoinTypes.RED)
        coins_table.takeCoins(CoinTypes.RED)
        self.assertEqual(CoinsTable.max_coins_count - 2, coins_table.getCoinsCount(CoinTypes.RED))
        coins_table.returnCoins(CoinTypes.RED)
        coins_table.returnCoins(CoinTypes.RED)
        with self.assertRaises(AssertionError):
            coins_table.returnCoins(CoinTypes.RED)

        i = CoinsTable.max_coins_count
        while(i > 0):
            coins_table.takeCoins(CoinTypes.GREEN)
            i -= 1
        
        with self.assertRaises(AssertionError):
            coins_table.takeCoins(CoinTypes.GREEN)
        
        self.assertEqual(0, coins_table.getCoinsCount(CoinTypes.GREEN))
Пример #3
0
class BestTurnFinder:
    def __init__(self):
        self.player = Player()
        cards_storage = CardsStorage()
        stack_level1 = CardsStack(CardLevel.ONE, cards_storage.cards_storage)
        stack_level2 = CardsStack(CardLevel.TWO, cards_storage.cards_storage)
        stack_level3 = CardsStack(CardLevel.THREE, cards_storage.cards_storage)
        self.cards_table = CardsTable(stack_level1, stack_level2, stack_level3)
        self.coins_table = CoinsTable()
        self.turn_validator = GameTurnValidator()
        self.turns_enumerator = GameTurnsEnumerator(self.coins_table,
                                                    self.cards_table)
        self.current_turns_sequence = []
        self.best_turns_sequences = []
        self.best_turns_sequence_points = 0
        self.current_first_turns_sequence = []
        self.all_first_turns_sequences = []

    def __updateBestTurnsSequence(self):
        current_turns_sequence_points = 0

        for turn in self.current_turns_sequence:
            taken_card = turn.getTakenCard()
            if taken_card:
                current_turns_sequence_points += taken_card.points

        if current_turns_sequence_points > self.best_turns_sequence_points:
            self.best_turns_sequence_points = current_turns_sequence_points
            self.best_turns_sequences = []
            self.best_turns_sequences.append(
                self.current_turns_sequence.copy())
            # print("best {0} turns. points {1}".format(len(self.best_turns_sequences), self.best_turns_sequence_points))
        elif current_turns_sequence_points == self.best_turns_sequence_points:
            self.best_turns_sequences.append(
                self.current_turns_sequence.copy())

    def __enumerateAllValidTurns(self):
        turns = self.turns_enumerator.enumerateAllPossibleTurns()
        valid_turns = []
        for turn in turns:
            if self.turn_validator.isTurnValid(turn, self.player):
                valid_turns.append(turn)

        return valid_turns

    def enumerateAllValidTurnSequences(self, turns_sequence_length):
        if turns_sequence_length == 0:
            self.all_first_turns_sequences.append(
                self.current_first_turns_sequence.copy())
            return

        valid_turns = self.__enumerateAllValidTurns()
        for turn in valid_turns:
            self.__playerTakeTurn(turn)
            self.current_first_turns_sequence.append(turn)
            self.enumerateAllValidTurnSequences(turns_sequence_length - 1)
            self.__playerUndoTurn(turn)
            self.current_first_turns_sequence.pop()

    def findTurnsHighestValueSequenceWithPrecalculatedBegginng(
            self, sequenceLength, valid_turns):
        for turn in valid_turns:
            self.__playerTakeTurn(turn)
            self.current_turns_sequence.append(turn)

        self.findHighestValueTurnsSequence(sequenceLength)

        for turn in valid_turns:
            self.__playerUndoTurn(turn)
            self.current_turns_sequence.pop()

    def findHighestValueTurnsSequence(self, sequenceLength):
        if sequenceLength == 0:
            self.__updateBestTurnsSequence()
            return

        valid_turns = self.__enumerateAllValidTurns()

        # if(sequenceLength >= 8):
        #     print("enumerated {0} valid turns. sequence {1}".format(len(valid_turns), sequenceLength))

        for turn in valid_turns:
            self.__playerTakeTurn(turn)
            self.current_turns_sequence.append(turn)
            self.findHighestValueTurnsSequence(sequenceLength - 1)
            self.__playerUndoTurn(turn)
            self.current_turns_sequence.pop()

    def __playerTakeTurn(self, turn: GameTurn):
        for coin in turn.getTakenCoins():
            self.coins_table.takeCoins(coin)
            self.player.receiveCoins(coin)

        if turn.getTakenCard():
            takken_card = turn.getTakenCard()
            self.cards_table.takeCard(takken_card)
            turn.payForPurchasedCard(self.player, self.coins_table)
            self.player.receivePurchasedCard(takken_card)

    def __playerUndoTurn(self, turn):
        for coin in turn.getTakenCoins():
            self.coins_table.returnCoins(coin)
            self.player.returnCoins(coin)

        if turn.getTakenCard():
            self.player.returnPurchasedCard(turn.getTakenCard())
            turn.returnPaymentForPurchasedCard(self.player, self.coins_table)
            self.cards_table.undoTakeCard()