diff --git a/README.md b/README.md index e5d86ef..43e422b 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,10 @@ Things done: 6) Input safety Things to do: -1) Make end of game conditions match actual end of game conditions -2) Testing classes -3) Turn Timer -4) Django server and hosting -5) HTML5 frontend -6) Multiplayer -7) Remaining 2nd Edition Base Cards: Bureaucrat, Chapel, Feast, Laboratory, Moneylender, Throne Room, Council Room, Festival, Library, Harbringer, Vassal, Gardens, Poacher, Bandit, Witch, Artisan, & Sentry -8) Choosing play sets +1) Testing classes +2) Turn Timer +3) Django server and hosting +4) HTML5 frontend +5) Multiplayer +6) Remaining 2nd Edition Base Cards: Bureaucrat, Chapel, Feast, Laboratory, Moneylender, Throne Room, Council Room, Festival, Library, Harbringer, Vassal, Gardens, Poacher, Bandit, Witch, Artisan, & Sentry +7) Choosing play sets diff --git a/_windows/git.xml b/_windows/git.xml deleted file mode 100644 index a8092bd..0000000 --- a/_windows/git.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/_windows/laf.xml b/_windows/laf.xml index c1f98d9..dbf49b4 100644 --- a/_windows/laf.xml +++ b/_windows/laf.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/card/basic/card_action.py b/card/basic/card_action.py new file mode 100644 index 0000000..88d78cf --- /dev/null +++ b/card/basic/card_action.py @@ -0,0 +1,5 @@ +from card.basic.card_kingdom import Kingdom + + +class Action(Kingdom): + pass diff --git a/card/basic/card_attack.py b/card/basic/card_attack.py new file mode 100644 index 0000000..d3acc68 --- /dev/null +++ b/card/basic/card_attack.py @@ -0,0 +1,11 @@ +from card.basic.card_kingdom import Kingdom + + +class Attack(Kingdom): + def effect(self): + for player in self.get_owner().get_table().get_players(): + if self.get_owner() != player and not player.get_hand().reaction_blocks_attack(self.get_name()): + self.attack(player) + + def attack(self, player): + pass diff --git a/card/basic/card_curse.py b/card/basic/card_curse.py new file mode 100644 index 0000000..185531c --- /dev/null +++ b/card/basic/card_curse.py @@ -0,0 +1,10 @@ +from card.basic.card_victory import Victory + + +class Curse(Victory): + @classmethod + def pile_setup(cls, player_count): + if player_count % cls.normal_full_table < cls.normal_full_table/2: + return Victory.pile_player_rate + else: + return (player_count - 1) * cls.pile_player_rate diff --git a/card/basic/card_kingdom.py b/card/basic/card_kingdom.py new file mode 100644 index 0000000..77b6075 --- /dev/null +++ b/card/basic/card_kingdom.py @@ -0,0 +1,10 @@ +from card.card import Card +from math import floor + + +class Kingdom(Card): + pile_player_rate = 10 + + @classmethod + def pile_setup(cls, player_count): + return (floor(player_count/cls.normal_full_table) + 1) * cls.pile_player_rate diff --git a/card/basic/card_reaction.py b/card/basic/card_reaction.py new file mode 100644 index 0000000..2ebf00a --- /dev/null +++ b/card/basic/card_reaction.py @@ -0,0 +1,5 @@ +from card.basic.card_kingdom import Kingdom + + +class Reaction(Kingdom): + pass diff --git a/card/basic/card_treasure.py b/card/basic/card_treasure.py new file mode 100644 index 0000000..f16fdce --- /dev/null +++ b/card/basic/card_treasure.py @@ -0,0 +1,8 @@ +from card.card import Card +from math import floor + + +class Treasure(Card): + @classmethod + def pile_setup(cls, player_count): + return (floor(player_count/cls.normal_full_table) + 1) * cls.pile_player_rate diff --git a/card/basic/card_victory.py b/card/basic/card_victory.py new file mode 100644 index 0000000..e023e99 --- /dev/null +++ b/card/basic/card_victory.py @@ -0,0 +1,21 @@ +from card.card import Card +from math import floor + + +class Victory(Card): + two_player_count = 8 + four_player_count = 12 + five_player_count = 15 + six_player_count = 18 + + @classmethod + def pile_setup(cls, player_count): + if 0 < player_count % Card.normal_full_table < Card.normal_full_table/2: + supplement = cls.two_player_count + elif Card.normal_full_table/2 <= player_count % Card.normal_full_table < Card.normal_full_table - 1: + supplement = cls.four_player_count + elif player_count % Card.normal_full_table == Card.normal_full_table - 1: + supplement = cls.five_player_count + else: + supplement = cls.six_player_count + return (floor(player_count/Card.normal_full_table) * cls.six_player_count) + supplement diff --git a/card/card.py b/card/card.py index b1f0107..6dcffa7 100644 --- a/card/card.py +++ b/card/card.py @@ -1,22 +1,11 @@ -from enum import Enum, auto - - class Card: - class CardType(Enum): - Treasure = auto() - Action = auto() - Reaction = auto() - Attack = auto() - Victory = auto() - Curse = auto() + normal_full_table = 6 + pile_player_rate = 10 - prevent_attack = False - - def __init__(self, name, cost, cardtype, value, coin, action, buy, draw, owner): + def __init__(self, name, cost, value, coin, action, buy, draw, owner): self.__name = name self.__cost = cost self.__coin = coin - self.__type = cardtype self.__action = action self.__buy = buy self.__draw = draw @@ -34,16 +23,22 @@ class Card: # This is here so that 'special' card can override this function so that unique card effects can happen. pass - def setup(self): + def react(self, what_attack): + return False + + @classmethod + def pile_setup(cls, player_count): + # This is here so that each card can override this function so that the right number of . + pass + + @staticmethod + def setup(): # This is here so that 'special' card can override this function so that unique card setup effects can happen. pass def get_name(self): return self.__name - def get_type(self): - return self.__type - def get_points(self): return self.__value @@ -60,7 +55,15 @@ class Card: return self.__owner def identify(self): - return self.__name + ", " + str(self.__type) + ", " + str(self.__cost) + return self.__name + ", " + self.__str__() + ", costing " + str(self.__cost) + + def print_card_list(self, card, message): + print("\nPlayer " + str(self._Card__owner.get_player_index()) + " " + message) + + counter = 0 + for c in card: + print(str(counter) + ": " + c.identify()) + counter += 1 def __get_index_not_self(self): result = -1 @@ -69,13 +72,5 @@ class Card: result = self._Card__owner.get_hand().get_player_index() return result - def __print_card_list(self, card, message): - print("\nPlayer " + str(self._Card__owner.get_player_index()) + " " + message) - - counter = 0 - for c in card: - print(str(counter) + ": " + c.identify()) - counter += 1 - def __str__(self): - return "A " + self.__name + " card." + return "a " + self.__name + " card" diff --git a/card/mine.py b/card/mine.py deleted file mode 100644 index 3c4f81d..0000000 --- a/card/mine.py +++ /dev/null @@ -1,8 +0,0 @@ -from card.card import Card -from card.card_gain_trash import CardGainTrash - - -class Mine(CardGainTrash): - coin_gain = 3 - trashable_type_restriction = [Card.CardType.Treasure] - gainable_type_restriction = [Card.CardType.Treasure] diff --git a/card/moat.py b/card/moat.py deleted file mode 100644 index 76cdfd4..0000000 --- a/card/moat.py +++ /dev/null @@ -1,5 +0,0 @@ -from card.card import Card - - -class Moat(Card): - prevent_attack = True diff --git a/card/cellar.py b/card/named/cellar.py similarity index 92% rename from card/cellar.py rename to card/named/cellar.py index a4fd832..da3d5d5 100644 --- a/card/cellar.py +++ b/card/named/cellar.py @@ -1,7 +1,7 @@ -from card.card import Card +from card.basic.card_action import Action -class Cellar(Card): +class Cellar(Action): def effect(self): hand_index = 0 cards_discarded = 0 diff --git a/card/named/copper.py b/card/named/copper.py new file mode 100644 index 0000000..35112e1 --- /dev/null +++ b/card/named/copper.py @@ -0,0 +1,5 @@ +from card.basic.card_treasure import Treasure + + +class Copper(Treasure): + pile_player_rate = 60 diff --git a/card/named/estate.py b/card/named/estate.py new file mode 100644 index 0000000..c913a43 --- /dev/null +++ b/card/named/estate.py @@ -0,0 +1,8 @@ +from card.basic.card_victory import Victory + + +class Estate(Victory): + two_player_count = 14 + four_player_count = 18 + five_player_count = 21 + six_player_count = 24 diff --git a/card/named/gold.py b/card/named/gold.py new file mode 100644 index 0000000..cd81068 --- /dev/null +++ b/card/named/gold.py @@ -0,0 +1,5 @@ +from card.basic.card_treasure import Treasure + + +class Gold(Treasure): + pile_player_rate = 30 \ No newline at end of file diff --git a/card/merchant.py b/card/named/merchant.py similarity index 88% rename from card/merchant.py rename to card/named/merchant.py index cb9df3d..cf0b9b4 100644 --- a/card/merchant.py +++ b/card/named/merchant.py @@ -1,7 +1,7 @@ -from card.card import Card +from card.basic.card_action import Action -class Merchant(Card): +class Merchant(Action): def effect(self): silver_card_index = self._Card__owner.get_hand().get_index_of_card_by_name("Silver") if silver_card_index >= 0: diff --git a/card/militia.py b/card/named/militia.py similarity index 51% rename from card/militia.py rename to card/named/militia.py index da037bd..6711e1b 100644 --- a/card/militia.py +++ b/card/named/militia.py @@ -1,14 +1,13 @@ -from card.card import Card +from card.basic.card_attack import Attack +from card.basic.card_action import Action from random import randint -class Militia(Card): - def effect(self): - for player in self._Card__owner.get_table().get_players(): - if self._Card__owner != player and not player.get_hand().blocks_attack(self.get_name()): - player.print_hand() - print("Player " + str(player.get_player_index()) + ", you MUST discard down to 3 card.") - self.__force_discard(self._Card__owner.get_std_chances(), player) +class Militia(Action, Attack): + def attack(self, player): + player.print_hand() + print("Player " + str(player.get_player_index()) + ", you MUST discard down to 3 card.") + self.__force_discard(self.get_owner().get_std_chances(), player) def __force_discard(self, chances, player): if player.get_hand().get_remaining() > 3 and chances > 0: @@ -16,16 +15,17 @@ class Militia(Card): " 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: + elif self.get_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.") - player.discard_from_hand(randint(0, self.__hand.get_remaining() - 1)) + player.discard_from_hand(randint(0, self.get_owner().get_hand().get_remaining() - 1)) def __check_discard(self, index, player, chances): - if 0 > index or index >= self._Card__owner.get_hand().get_remaining(): - print("Valid inputs range from 0 to " + str(player.get_hand().get_remaining() - 1) + ". 1 chance lost.") + if 0 > index >= player.get_hand().get_remaining(): + print("Valid inputs range from 0 to " + str(player.get_hand().get_remaining() - 1) + ". " + str(chances - 1) + + "chances to input a valid index.") self.__force_discard(chances - 1, player) else: print("Discarding " + player.get_hand().get_card(index).get_name() + ".") player.discard_from_hand(index) player.print_hand() - self.__force_discard(self._Card__owner.get_std_chances(), player) + self.__force_discard(self.get_owner().get_std_chances(), player) diff --git a/card/named/mine.py b/card/named/mine.py new file mode 100644 index 0000000..a667f38 --- /dev/null +++ b/card/named/mine.py @@ -0,0 +1,9 @@ +from card.basic.card_action import Action +from card.basic.card_treasure import Treasure +from card.special.card_gain_trash import CardGainTrash + + +class Mine(Action, CardGainTrash): + coin_gain = 3 + trashable_type_restriction = Treasure + gainable_type_restriction = Treasure diff --git a/card/named/moat.py b/card/named/moat.py new file mode 100644 index 0000000..d15679b --- /dev/null +++ b/card/named/moat.py @@ -0,0 +1,10 @@ +from card.basic.card_action import Action +from card.basic.card_reaction import Reaction + + +class Moat(Action, Reaction): + def react(self, what_attack): + owner = self.get_owner() + return "Y" == owner.get_general_input("Player " + str(owner.get_player_index()) + ", enter 'Y' if you'd " + "like to reveal " + str(self) + " to block the " + str(what_attack) + + " attack: ", str) diff --git a/card/named/province.py b/card/named/province.py new file mode 100644 index 0000000..1f0eec4 --- /dev/null +++ b/card/named/province.py @@ -0,0 +1,5 @@ +from card.basic.card_victory import Victory + + +class Province(Victory): + pass diff --git a/card/named/remodel.py b/card/named/remodel.py new file mode 100644 index 0000000..5bfda77 --- /dev/null +++ b/card/named/remodel.py @@ -0,0 +1,6 @@ +from card.basic.card_action import Action +from card.special.card_gain_trash import CardGainTrash + + +class Remodel(Action, CardGainTrash): + coin_gain = 2 diff --git a/card/named/silver.py b/card/named/silver.py new file mode 100644 index 0000000..073e8b2 --- /dev/null +++ b/card/named/silver.py @@ -0,0 +1,6 @@ +from card.basic.card_treasure import Treasure + + +class Silver(Treasure): + pile_player_rate = 40 + diff --git a/card/named/workshop.py b/card/named/workshop.py new file mode 100644 index 0000000..3166050 --- /dev/null +++ b/card/named/workshop.py @@ -0,0 +1,9 @@ +from card.basic.card_action import Action +from card.special.card_gain import CardGain + + +class Workshop(Action, CardGain): + coin_gain = 4 + + def effect(self): + self.gain_card(self.coin_gain) diff --git a/card/remodel.py b/card/remodel.py deleted file mode 100644 index 4d95eef..0000000 --- a/card/remodel.py +++ /dev/null @@ -1,5 +0,0 @@ -from card.card_gain_trash import CardGainTrash - - -class Remodel(CardGainTrash): - coin_gain = 2 diff --git a/card/card_gain.py b/card/special/card_gain.py similarity index 50% rename from card/card_gain.py rename to card/special/card_gain.py index 1020c29..bf724c4 100644 --- a/card/card_gain.py +++ b/card/special/card_gain.py @@ -6,9 +6,9 @@ class CardGain(Card): def gain_card(self, spending_limit): gainable_cards = self.__get_gainable_cards(spending_limit) - self._Card__print_card_list(gainable_cards, "Gainable Cards: ") + self.print_card_list(gainable_cards, "Gainable Cards: ") index = 0 - chances = self._Card__owner.get_std_chances() + chances = self.get_owner().get_std_chances() while len(gainable_cards) > 0 and 0 <= index < len(gainable_cards) - 1 and chances > 0: index = self.__get_gain_card() @@ -18,24 +18,24 @@ class CardGain(Card): index = 0 chances -= 1 else: - pile_index = self._Card__owner.get_table().get_pile_index_of_card(gainable_cards[index].get_name()) - print("Player " + str(self._Card__owner.get_player_index()) + " drawing " - + self._Card__owner.get_table().get_pile(pile_index).get_card_group().get_name() + " to hand.") - self._Card__owner.get_table().get_pile(pile_index).transfer_top_card(self._Card__owner.get_hand()) - self._Card__owner.claim_top_card(self._Card__owner.get_hand()) + pile_index = self.get_owner().get_table().get_pile_index_of_card(gainable_cards[index].get_name()) + print("Player " + str(self.get_owner().get_player_index()) + " drawing " + + self.get_owner().get_table().get_pile(pile_index).get_card_group().get_name() + " to hand.") + self.get_owner().get_table().get_pile(pile_index).transfer_top_card(self.get_owner().get_hand()) + self.get_owner().claim_top_card(self.get_owner().get_hand()) chances = 0 def __get_gain_card(self): - return self.__Card_owner.get_general_input("\nPlease identify the index of which card you would like to " + return self.get_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() - for p in self._Card__owner.get_table().get_piles(): + for p in self.get_owner().get_table().get_piles(): if p.get_card_group().get_cost() <= spending_limit: if self.gainable_type_restriction is None: result.append(p.get_card_group()) - elif p.get_card_group().get_type() in self.gainable_type_restriction: + elif isinstance(p.get_card_group(), self.gainable_type_restriction): result.append(p.get_card_group()) return result diff --git a/card/card_gain_trash.py b/card/special/card_gain_trash.py similarity index 58% rename from card/card_gain_trash.py rename to card/special/card_gain_trash.py index c68bd91..0144f1a 100644 --- a/card/card_gain_trash.py +++ b/card/special/card_gain_trash.py @@ -1,5 +1,5 @@ -from card.card_trash import CardTrash -from card.card_gain import CardGain +from card.special.card_trash import CardTrash +from card.special.card_gain import CardGain class CardGainTrash(CardTrash, CardGain): diff --git a/card/card_trash.py b/card/special/card_trash.py similarity index 56% rename from card/card_trash.py rename to card/special/card_trash.py index 5d6d198..8925171 100644 --- a/card/card_trash.py +++ b/card/special/card_trash.py @@ -6,10 +6,10 @@ class CardTrash(Card): def trash_card_get_cost(self): tc = self.__get_trashable_cards() - self._Card__print_card_list(tc, " Trashable Cards: ") + self.print_card_list(tc, " Trashable Cards: ") index = 0 bonus = 0 - chances = self._Card__owner.get_std_chances() + chances = self.get_owner().get_std_chances() while 0 < len(tc) and 0 <= index < len(tc) - 1 and chances > 0: index = self.__get_card_to_trash() @@ -19,9 +19,9 @@ class CardTrash(Card): index = 0 chances -= 1 else: - print("Player " + str(self._Card__owner.get_player_index()) + " trashing " + tc[index].get_name() + ".") + print("Player " + str(self.get_owner().get_player_index()) + " trashing " + tc[index].get_name() + ".") bonus = tc[index].get_cost() - self._Card__owner.get_hand().transfer_card_by_card(tc[index], self._Card__owner.get_table().get_trash()) + self.get_owner().get_hand().transfer_card_by_card(tc[index], self.get_owner().get_table().get_trash()) chances = 0 return bonus @@ -29,15 +29,15 @@ class CardTrash(Card): self.trash_card_get_cost() def __get_card_to_trash(self): - return self.__Card_owner.get_general_input("\nPlease identify the index of the desired card to trash: ", int) + return self.get_owner().get_general_input("\nPlease identify the index of the desired card to trash: ", int) def __get_trashable_cards(self): result = list() - for c in self._Card__owner.get_hand().get_supply(): + for c in self.get_owner().get_hand().get_supply(): if c != self: if self.trashable_type_restriction is None: result.append(c) - elif c.get_type() in self.trashable_type_restriction: + elif isinstance(c, self.trashable_type_restriction): result.append(c) return result diff --git a/card/workshop.py b/card/workshop.py deleted file mode 100644 index 30b5fbd..0000000 --- a/card/workshop.py +++ /dev/null @@ -1,8 +0,0 @@ -from card.card_gain import CardGain - - -class Workshop(CardGain): - coin_gain = 4 - - def effect(self): - self.gain_card(self.coin_gain) diff --git a/codestyles/Default.xml b/codestyles/Default.xml deleted file mode 100644 index 1345acf..0000000 --- a/codestyles/Default.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/databaseDrivers.xml b/databaseDrivers.xml deleted file mode 100644 index 98bf5b5..0000000 --- a/databaseDrivers.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/databaseSettings.xml b/databaseSettings.xml deleted file mode 100644 index 0962833..0000000 --- a/databaseSettings.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/debugger.xml b/debugger.xml deleted file mode 100644 index 544ab15..0000000 --- a/debugger.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/editor.xml b/editor.xml index e8334e3..66a0938 100644 --- a/editor.xml +++ b/editor.xml @@ -3,7 +3,8 @@