From b71faf0f0c3452f5e0ee2b59ee9708bcbd504da4 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Fri, 5 Jan 2018 21:33:36 -0600 Subject: [PATCH 1/2] Add files via upload --- card/card_gain.py | 3 +- card/card_trash.py | 2 +- card/cellar.py | 2 +- card/merchant.py | 3 +- card/militia.py | 3 +- player/bots/pure_big_money.py | 4 +-- player/hand.py | 13 +++----- player/player.py | 58 +++++++++++++++++++++++++++-------- 8 files changed, 60 insertions(+), 28 deletions(-) diff --git a/card/card_gain.py b/card/card_gain.py index 63684b2..1020c29 100644 --- a/card/card_gain.py +++ b/card/card_gain.py @@ -26,7 +26,8 @@ class CardGain(Card): chances = 0 def __get_gain_card(self): - return int(input("\nPlease identify the index of which card you would like to obtain: ")) + return self.__Card_owner.get_general_input("\nPlease identify the index of which card you would like to " + "obtain: ", int) def __get_gainable_cards(self, spending_limit): result = list() diff --git a/card/card_trash.py b/card/card_trash.py index 55833a4..5d6d198 100644 --- a/card/card_trash.py +++ b/card/card_trash.py @@ -29,7 +29,7 @@ class CardTrash(Card): self.trash_card_get_cost() def __get_card_to_trash(self): - return int(input("\nPlease identify the index of the desired card to trash: ")) + return self.__Card_owner.get_general_input("\nPlease identify the index of the desired card to trash: ", int) def __get_trashable_cards(self): result = list() diff --git a/card/cellar.py b/card/cellar.py index 5bada8d..a4fd832 100644 --- a/card/cellar.py +++ b/card/cellar.py @@ -23,5 +23,5 @@ class Cellar(Card): self._Card__owner.draw_cards(cards_discarded) def __get_index(self, message): - return int(input(message)) + return self.__Card_owner.get_general_input(message, int) diff --git a/card/merchant.py b/card/merchant.py index 6539792..cb9df3d 100644 --- a/card/merchant.py +++ b/card/merchant.py @@ -13,4 +13,5 @@ class Merchant(Card): self._Card__owner.add_purchase_power(3) def __get_Merchant_input(self, message): - return input("Player " + str(self._Card__owner.get_player_index()) + ", " + message) + return self.__Card_owner.get_general_input("Player " + str(self._Card__owner.get_player_index()) + ", " + + message, str) diff --git a/card/militia.py b/card/militia.py index acdb418..da037bd 100644 --- a/card/militia.py +++ b/card/militia.py @@ -13,7 +13,8 @@ class Militia(Card): def __force_discard(self, chances, player): if player.get_hand().get_remaining() > 3 and chances > 0: hand_index = player.militia_input("\nPlease provide an index to identify a card from hand you would like to" - " discard (0 to " + str(player.get_hand().get_remaining() - 1) + "): ") + " discard (0 to " + str(player.get_hand().get_remaining() - 1) + "): " + , int) self.__check_discard(hand_index, player, chances) elif self._Card__owner.get_hand().get_remaining() > 3 and chances <= 0: print("You're out of chances to select a valid card to discard, randomly selecting for you.") diff --git a/player/bots/pure_big_money.py b/player/bots/pure_big_money.py index 525b484..182cc02 100644 --- a/player/bots/pure_big_money.py +++ b/player/bots/pure_big_money.py @@ -7,7 +7,7 @@ class Pure_Big_Money(Player): print("\nAs a BIG MONEY BOT, I'm skipping this unnecessary action phase. Beep-boop, bow to me humans!") #This method will only be called for this bot when it is time to play treasures, it will play all of them always. - def get_play_input(self, message): + def get_play_input(self, message, target_type): choice = -1 hand = self.get_hand().get_supply() @@ -19,7 +19,7 @@ class Pure_Big_Money(Player): return choice #This method will only be called when it is time to buy things, a very simple logic will decide its action. - def get_buy_input(self, message): + def get_buy_input(self, message, target_type): coin = self._Player__purchase_power choice = -1 diff --git a/player/hand.py b/player/hand.py index cb6e2c7..485ffee 100644 --- a/player/hand.py +++ b/player/hand.py @@ -27,16 +27,13 @@ class Hand(Supply): found_at = self._Supply__card.index(c) if found_at >= 0: - yes_no = "Y" == self.__get_reveal("Player " - + str(self._Supply__card[found_at].get_owner().get_player_index()) - + ", enter 'Y' if you'd like to reveal " - + self._Supply__card[found_at].get_name() + " to block the " - + what_attack + " attack: ") + owner = self._Supply__card[found_at].get_owner() + yes_no = "Y" == owner.get_general_input("Player " + str(owner.get_player_index()) + ", enter 'Y' if you'd " + "like to reveal " + + self._Supply__card[found_at].get_name() + " to block the " + + what_attack + " attack: ", str) return yes_no - def __get_reveal(self, message): - return input(message) - def __get_unique_types(self): unique_type = list() diff --git a/player/player.py b/player/player.py index 5e23599..116e71a 100644 --- a/player/player.py +++ b/player/player.py @@ -3,11 +3,12 @@ from player.discard import Discard from player.hand import Hand from player.counter import Counter from card.card import Card +from random import randint class Player: def __init__(self, table): - self.__std_chances = 3 + self.__std_chances = 2 self.__deck = Deck() self.__discard = Discard() self.__hand = Hand() @@ -100,7 +101,7 @@ class Player: def play_card(self, acceptable_card_type, chances, counter): if chances > 0 and self.__hand.contains_one_of(acceptable_card_type): - hand_index = self.get_play_input("\nPlease identify a card from hand to play by providing its index: ") + hand_index = self.get_play_input("\nPlease identify a card from hand to play by providing its index: ", int) self.__check_play_card(hand_index, counter, acceptable_card_type, chances) elif chances <= 0: print("You have used up all of your chances to enter a valid integer; forfeiting remaining plays.") @@ -129,7 +130,7 @@ class Player: def buy_card(self, chances): self.__table.print() while self.__buys > 0 and not self.__table.are_there_any_empty_piles() and chances > 0: - pile_index = self.get_buy_input("\nPlease identify a pile from the table that you'd like to purchase: ") + pile_index = self.get_buy_input("\nPlease choose a pile from the table that you'd like to purchase: ", int) if pile_index < 0: print("You have elected to forfeit any remaining plays.") @@ -141,11 +142,13 @@ class Player: print("You do not have enough coin. Try again.") chances -= 1 else: + self.__buys -= 1 + self.__purchase_power -= self.__table.get_pile(pile_index).get_card_group().get_cost() print("Player " + str(self.get_table().get_players().index(self)) + " buying card " + - self.__table.get_pile(pile_index).get_card_group().get_name()) + self.__table.get_pile(pile_index).get_card_group().get_name() + " leaving " + + str(self.__purchase_power) + " coin(s) and " + str(self.__buys) + " buy(s) following purchase.") self.__table.get_pile(pile_index).transfer_top_card(self.__discard) self.claim_top_card(self.__discard) - self.__buys -= 1 def take_turn(self): self.__turn_setup() @@ -184,17 +187,46 @@ class Player: self.play_card(acceptable_card_type, chances - 1, counter) # The following two methods are identical under different names so they can be overridden by bot classes later - def get_play_input(self, message): - return self.get_general_input(message) + def get_play_input(self, message, target_type): + return self.get_general_input(message, target_type) - def get_buy_input(self, message): - return self.get_general_input(message) + def get_buy_input(self, message, target_type): + return self.get_general_input(message, target_type) - def militia_input(self, message): - return self.get_general_input(message) + def militia_input(self, message, target_type): + return self.get_general_input(message, target_type) - def get_general_input(self, message): - return int(input(message)) + def get_general_input(self, message, target_type): + return self.__get_input(self.__std_chances, target_type, message) + + def __get_input(self, chances, target_type, message): + value = input(message) + if chances > 0: + if not self.__does_typecast_error(value, target_type): + return target_type(value) + else: + print("'" + str(value) + "' of type " + str(type(value)) + " is an invalid entry. " + str(chances) + + " chances to input a " + str(target_type) + " remain.") + return self.__get_input(chances - 1, target_type, message) + else: + if target_type == int: + rand_value = randint(-1, 1) + print("You've run out of chances to input an int. A random value of '" + str(rand_value) + "' is being" + " supplied.") + return rand_value + elif target_type == str: + print("You've run out of chances to input an string. A zero length string is being supplied.") + return "" + else: + print("You've run out of chances to input a" + str(target_type) + ". A None is being supplied.") + return None + + def __does_typecast_error(self, value, target_type): + try: + target_type(value) + return False + except ValueError: + return True def __print_discard(self): print("\nPlayer " + str(self.__table.get_players().index(self)) + " Discard:") From 74ce68822fc5cc2006e9474de7ea08915e0d2c1d Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Fri, 5 Jan 2018 21:34:30 -0600 Subject: [PATCH 2/2] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8ea9655..e5d86ef 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ Things done: 3) Special First Play cards in 2nd Edition: Workshop, Remodel, Mine, Merchant, Cellar, Moat, and Militia 4) Bot player with big money strategy 5) Game scoring +6) Input safety Things to do: 1) Make end of game conditions match actual end of game conditions