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 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
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)
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])
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))
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()
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)
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))