Пример #1
0
 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 = []
Пример #2
0
    def canPlayerSaveCard(self, turn: GameTurn, player: Player,
                          coins_table: CoinsTable):
        if self.__canPlayerBuyCard(
                player, turn.getTakenCard()) or not self.__canPlayerTakeCoins(
                    [CoinTypes.ANY_COLOR], player):
            return False

        return coins_table.getCoinsCount(CoinTypes.ANY_COLOR) > 0
Пример #3
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)
Пример #4
0
    def test_game_turns_enumerator(self):
        coins_table = CoinsTable()
        level1_stack = CardsStack(CardLevel.ONE, self.cards_db)
        level2_stack = CardsStack(CardLevel.TWO, self.cards_db)
        level3_stack = CardsStack(CardLevel.THREE, self.cards_db)
        cards_table = CardsTable(level1_stack, level2_stack, level3_stack)
        turns_enumerator = GameTurnsEnumerator(coins_table, cards_table)

        turns = turns_enumerator.enumerateAllPossibleTurns()
        self.assertEqual(10 + 12, len(turns))
        self.assertEqual(GameTurn((CoinTypes.WHITE, CoinTypes.BLUE, CoinTypes.GREEN), None), turns[0])
        self.assertEqual(GameTurn((CoinTypes.WHITE, CoinTypes.BLUE, CoinTypes.RED), None), turns[1])
        self.assertEqual(GameTurn((CoinTypes.BLUE, CoinTypes.GREEN, CoinTypes.RED), None), turns[6])
        self.assertEqual(GameTurn((CoinTypes.GREEN, CoinTypes.RED, CoinTypes.BLACK), None), turns[9])
        self.assertEqual(GameTurn((), self.cards_db[0]), turns[10])
        self.assertEqual(GameTurn((), self.cards_db[8]), turns[14])
        self.assertEqual(GameTurn((), self.cards_db[16]), turns[18])

        coins_table.takeCoins(CoinTypes.WHITE, CoinsTable.max_coins_count)
        coins_table.takeCoins(CoinTypes.BLUE, CoinsTable.max_coins_count)
        coins_table.takeCoins(CoinTypes.GREEN, CoinsTable.max_coins_count)
        turns = turns_enumerator.enumerateAllPossibleTurns()
        self.assertEqual(1 + 12, len(turns))
        self.assertEqual(GameTurn((CoinTypes.RED, CoinTypes.BLACK), None), turns[0])
        self.assertEqual(GameTurn((), self.cards_db[0]), turns[1])

        coins_table.takeCoins(CoinTypes.RED, CoinsTable.max_coins_count)
        cards_table.takeCardByIndex(CardLevel.ONE, 0)
        cards_table.takeCardByIndex(CardLevel.ONE, 0)
        cards_table.takeCardByIndex(CardLevel.ONE, 0)
        cards_table.takeCardByIndex(CardLevel.ONE, 0)
        cards_table.takeCardByIndex(CardLevel.ONE, 0)
        turns = turns_enumerator.enumerateAllPossibleTurns()
        self.assertEqual(1 + 11, len(turns))
        self.assertEqual(GameTurn((CoinTypes.BLACK, ), None), turns[0])
        self.assertEqual(GameTurn((), self.cards_db[1]), turns[1])
Пример #5
0
    def testGameTurn(self):
        coins_table = CoinsTable()
        turn = GameTurn((), self.cards_db[0])
        player = Player()

        coins_table.takeCoins(CoinTypes.BLUE, 3)
        player.receiveCoins(CoinTypes.BLUE, 3)
        turn.payForPurchasedCard(player, coins_table)
        self.assertEqual(0, player.getCoinsCount(CoinTypes.BLUE))
        self.assertEqual(3, turn.getPaidCoinsCount(CoinTypes.BLUE))

        turn.returnPaymentForPurchasedCard(player, coins_table)
        self.assertEqual(3, player.getCoinsCount(CoinTypes.BLUE))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.BLUE))

        turn = GameTurn((), self.cards_db[8])
        coins_table.takeCoins(CoinTypes.GREEN, 3)
        player.receiveCoins(CoinTypes.GREEN, 3)
        player.receivePurchasedCard(self.cards_db[1])
        player.receivePurchasedCard(self.cards_db[3])
        player.receivePurchasedCard(self.cards_db[4])
        turn.payForPurchasedCard(player, coins_table)
        self.assertEqual(3, player.getCoinsCount(CoinTypes.BLUE))
        self.assertEqual(2, player.getCoinsCount(CoinTypes.GREEN))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.BLUE))
        self.assertEqual(1, turn.getPaidCoinsCount(CoinTypes.GREEN))

        turn.returnPaymentForPurchasedCard(player, coins_table)
        self.assertEqual(3, player.getCoinsCount(CoinTypes.BLUE))
        self.assertEqual(3, player.getCoinsCount(CoinTypes.GREEN))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.BLUE))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.GREEN))

        turn = GameTurn((), self.cards_db[8])
        player.receivePurchasedCard(self.cards_db[9])
        turn.payForPurchasedCard(player, coins_table)
        self.assertEqual(3, player.getCoinsCount(CoinTypes.BLUE))
        self.assertEqual(2, player.getCoinsCount(CoinTypes.GREEN))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.BLUE))
        self.assertEqual(1, turn.getPaidCoinsCount(CoinTypes.GREEN))

        turn.returnPaymentForPurchasedCard(player, coins_table)
        self.assertEqual(3, player.getCoinsCount(CoinTypes.BLUE))
        self.assertEqual(3, player.getCoinsCount(CoinTypes.GREEN))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.BLUE))
        self.assertEqual(0, turn.getPaidCoinsCount(CoinTypes.GREEN))
Пример #6
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()
Пример #7
0
 def returnPaymentForPurchasedCard(self, player: Player,
                                   coins_table: CoinsTable):
     for coin, coin_count in self.paid_coins_count.items():
         player.receiveCoins(coin, coin_count)
         self.paid_coins_count[coin] = 0
         coins_table.takeCoins(coin, coin_count)
Пример #8
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))