diff --git a/server/Characters/Architect.py b/server/Characters/Architect.py new file mode 100644 index 0000000..3c9695e --- /dev/null +++ b/server/Characters/Architect.py @@ -0,0 +1,28 @@ +from CharactersList import CharactersList +from server.Characters.Character import Character +from server.District import DistrictsList + + +class Architect(Character): + + def __init__(self): + super().__init__(CharactersList.Architect) + self.new_cards = None + self.text = "After you take an action, you draw two additional district cards and put both in your hand." + + def action(self, self_player, other_player, list_of_the_districts): + self.new_cards = DistrictsList.take_the_cards(2) + self_player.districts_in_hand.extend(self.new_cards) + """The action of this character""" + + def get_progress_information(self): + """Print info of this action""" + return super().get_progress_information(self).format("You receive {} {}").format(", ".join([self.new_cards[i].name for i in range(len(self.new_cards) - 1)]) if self.new_cards else "0", str(self.new_cards[len(self.new_cards) - 1].name) if self.new_cards else "cards") + + def get_info(self): + """Print info of this character""" + return super().get_info(self).format(self.character_name, self.text) + + def number_of_districts_can_build(self): + return 3 + diff --git a/server/Characters/Assassin.py b/server/Characters/Assassin.py index 5fa5b1c..13832bf 100644 --- a/server/Characters/Assassin.py +++ b/server/Characters/Assassin.py @@ -7,10 +7,12 @@ class Assassin(Character): def __init__(self): super().__init__(CharactersList.Assassin) self.choose_character = None + self.text = "Choose any character and kill him" - def action(self, character_name): + def action(self, self_player, other_player, list_of_the_districts): """The action of this character""" - self.choose_character = character_name + self.choose_character = other_player.character + other_player.character = None def get_progress_information(self): """Print info of this action""" @@ -20,3 +22,5 @@ def get_info(self): """Print info of this character""" return super(Assassin, self).get_info(self).format(self.character_name, "choose any character and kill him") + def is_thief_can_rob_you(self): + return False diff --git a/server/Characters/Bishop.py b/server/Characters/Bishop.py index dfb8f61..8c4d044 100644 --- a/server/Characters/Bishop.py +++ b/server/Characters/Bishop.py @@ -1,20 +1,28 @@ from CharactersList import CharactersList from server.Characters.Character import Character +from server.District import DistrictTypeList class Bishop(Character): def __init__(self): - super().__init__(CharactersList.Assassin) + super().__init__(CharactersList.Bishop) + self.text = "You receive one gold for each religious (blue) district in your city." + self.gold = 0 - def action(self, character_name=None): + def action(self, self_player, other_player, list_of_the_districts): """The action of this character""" + self.gold = len(list( + filter(lambda x: x.value.type_of_district == DistrictTypeList.Religious, self_player.districts_in_table))) + self_player.change_gold(self.gold) def get_progress_information(self): """Print info of this action""" - return super(Bishop, self).get_progress_information(self).format("You receive {} gold").format() + return super().get_progress_information(self).format("You receive {} gold").format(self.gold) def get_info(self): """Print info of this character""" - return super(Bishop, self).get_info(self).format(self.character_name, "You receive one gold for each " - "religious (blue) district in your city.") + return super().get_info(self).format(self.character_name, self.text) + + def is_warlord_can_destroy_your_districts(self): + return False diff --git a/server/Characters/Character.py b/server/Characters/Character.py index f017ebe..86d7e38 100644 --- a/server/Characters/Character.py +++ b/server/Characters/Character.py @@ -5,7 +5,7 @@ def __init__(self, character_name): """Constructor""" self.character_name = character_name - def action(self, character_name): + def action(self, self_player, other_player, list_of_the_districts): """The action of this character""" pass @@ -21,5 +21,14 @@ def get_progress_information(self): """Print info of this action""" return 'In your turn you {} ' + @staticmethod + def number_of_districts_can_build(): + return 1 + @staticmethod + def is_warlord_can_destroy_your_districts(): + return True + @staticmethod + def is_thief_can_rob_you(): + return True diff --git a/server/Characters/CharactersList.py b/server/Characters/CharactersList.py index d742a91..c6e44ba 100644 --- a/server/Characters/CharactersList.py +++ b/server/Characters/CharactersList.py @@ -1,6 +1,5 @@ import random from enum import Enum -from random import randrange class CharactersList(Enum): @@ -30,4 +29,3 @@ def all_characters(number): @staticmethod def default_characters(number): return random.choices([i for i in CharactersList if i.value % 2 == 1 and i.value < 16], k=number) - diff --git a/server/Characters/King.py b/server/Characters/King.py index 443774f..426cc5a 100644 --- a/server/Characters/King.py +++ b/server/Characters/King.py @@ -1,5 +1,7 @@ from CharactersList import CharactersList from server.Characters.Character import Character +from server.District import DistrictTypeList, DistrictsList +from server.Player import Player class King(Character): @@ -12,15 +14,18 @@ def __init__(self): the Crown. You now call the characters, and you will be the first player to choose your character during the next round.""" + self.gold = 0 - def action(self, character_name): + def action(self, self_player, other_player, list_of_the_districts): """The action of this character""" - pass + self.gold = len(list(filter(lambda x: x.value.type_of_district == DistrictTypeList.Noble, list_of_the_districts))) + self_player.change_gold(self.gold) def get_progress_information(self): """Print info of this action""" - return super(King, self).get_progress_information(self).format("must be strong") + return super(King, self).get_progress_information(self).format("receive {} gold").format(self.gold) def get_info(self): """Print info of this character""" - return super(King, self).get_info(self).format(self.character_name, self.text) + return super().get_info(self).format(self.character_name, self.text) + diff --git a/server/Characters/Magician.py b/server/Characters/Magician.py index 894d6fd..1cdc082 100644 --- a/server/Characters/Magician.py +++ b/server/Characters/Magician.py @@ -1,5 +1,6 @@ from CharactersList import CharactersList from server.Characters.Character import Character +from server.District import DistrictsList class Magician(Character): @@ -15,16 +16,23 @@ def __init__(self): facedown at the bottom of the District Deck, and then draw an equal number of cards from the top of the District Deck.""" - self.character_name = None + self.list_of_the_card = None - def action(self, character_name=None): + def action(self, self_player, other_player, list_of_the_districts): """The action of this character""" - self.character_name = character_name + self.list_of_the_card = list_of_the_districts + if other_player: + other_player.districts_in_hand, self_player.districts_in_hand = self_player.districts_in_hand, other_player.districts_in_hand + else: + for i in self.list_of_the_card: + self_player.districts_in_hand.remove(i) + self.list_of_the_card = DistrictsList.take_the_cards(len(self.list_of_the_card)) + self_player.districts_in_hand.extend(self.list_of_the_card) def get_progress_information(self): """Print info of this action""" - return super(Magician, self).get_progress_information(self).format(self.first_move if self.character_name else self.second_move) + return super().get_progress_information(self).format("Your change {} cards").format(len(self.list_of_the_card) if self.list_of_the_card else 0) def get_info(self): """Print info of this character""" - return super(Magician, self).get_info(self).format(self.character_name, """{} \n Or \n {}""").format(self.first_move, self.second_move) + return super().get_info(self).format(self.character_name, """{} \n Or \n {}""").format(self.first_move, self.second_move) diff --git a/server/Characters/Merchant.py b/server/Characters/Merchant.py new file mode 100644 index 0000000..fc6806c --- /dev/null +++ b/server/Characters/Merchant.py @@ -0,0 +1,25 @@ +from CharactersList import CharactersList +from server.Characters.Character import Character +from server.District import DistrictTypeList + + +class Merchant(Character): + + def __init__(self): + super().__init__(CharactersList.Assassin) + + def action(self, self_player, other_player, list_of_the_districts): + """The action of this character""" + self_player.change_gold(self.get_gold(self_player.districts_in_table)) + + def get_progress_information(self): + """Print info of this action""" + return super().get_progress_information(self).format("You receive {} gold").format(self.get_gold(districts_in_table)) + + def get_info(self): + """Print info of this character""" + return super().get_info(self).format(self.character_name, "You receive one gold for each trade (green)district in your city") + + @staticmethod + def get_gold(districts_in_table): + return len(list(filter(lambda x: x.value.type_of_district == DistrictTypeList.Trade, districts_in_table))) diff --git a/server/Characters/Thief.py b/server/Characters/Thief.py index 09132b9..92efc6a 100644 --- a/server/Characters/Thief.py +++ b/server/Characters/Thief.py @@ -7,16 +7,22 @@ class Thief(Character): def __init__(self): super().__init__(CharactersList.Thief) self.choose_character = None + self.text = "choose any character and rob him" - def action(self, character_name): + def action(self, self_player, other_player, list_of_the_districts): """The action of this character""" - self.choose_character = character_name + self.choose_character = other_player.character + self_player.change_gold(other_player.gold) + other_player.change_gold(-other_player.gold) def get_progress_information(self): """Print info of this action""" - return super(Thief, self).get_progress_information(self).format("rob {}").format(self.choose_character) + return super().get_progress_information(self).format("rob {}").format(self.choose_character) def get_info(self): """Print info of this character""" - return super(Thief, self).get_info(self).format(self.character_name, "choose any character and rob him") + return super().get_info(self).format(self.character_name, self.text) + + def can_rab(self, other_character): + return other_character != CharactersList.Assassin diff --git a/server/Characters/Warlord.py b/server/Characters/Warlord.py new file mode 100644 index 0000000..0a7371b --- /dev/null +++ b/server/Characters/Warlord.py @@ -0,0 +1,41 @@ +from CharactersList import CharactersList +from server.Characters.Character import Character +from server.District import DistrictTypeList, DistrictsList + + +class Warlord(Character): + + def __init__(self): + super().__init__(CharactersList.Warlord) + self.choose_character = None + self.text = """You receive one gold for each military (red) +district in your city. At the end of your turn, you +may destroy one district of your choice by paying +a number of gold equal to one less than the cost +of the district. Thus, you may destroy a cost one +district for free, a cost two district for one gold, +or a cost six district for five gold, etc. You may +destroy one of your own districts. You may not, +however, destroy a district in a city that is already +completed by having eight districts (or seven +districts when the Bell Tower is in play).""" + self.gold = 0 + + def action(self, self_player, other_player, district): + """The action of this character""" + self.gold = len(list(filter(lambda x: x.value.type_of_district == DistrictTypeList.Religious, self_player.districts_in_table))) + self_player.change_gold(self.gold) + other_player.districts_in_table.remove(district) + + def get_progress_information(self): + """Print info of this action""" + return super().get_progress_information(self).format("You receive {} gold {}").format(self.gold) + + def get_info(self): + """Print info of this character""" + return super().get_info(self).format(self.character_name, self.text) + + + @staticmethod + def can_destroy_district(self_player, other_player, district): + return other_player.character != CharactersList.Bishop and self_player.gold >= district.price + 1 diff --git a/server/District.py b/server/District.py new file mode 100644 index 0000000..079a7c3 --- /dev/null +++ b/server/District.py @@ -0,0 +1,49 @@ +import random +from enum import Enum + + +class DistrictTypeList(Enum): + Bonus = 0 + Military = 1 + Religious = 2 + Noble = 3 + Trade = 4 + + +class District(object): + """Is a Basic character class""" + + def __init__(self, name, type_of_district, price, quantity): + """Constructor""" + self.name = name + self.type_of_district = type_of_district + self.price = price + self.quantity = quantity + + +class DistrictsList(Enum): + Watchtower = District("watchtower", DistrictTypeList.Military, 1, 3) + Prison = District("prison", DistrictTypeList.Military, 2, 3) + The_Field_of_Mars = District("the Field of Mars", DistrictTypeList.Military, 3, 3) + Fortress = District("fortress", DistrictTypeList.Military, 5, 2) + + Temple = District("temple", DistrictTypeList.Religious, 1, 3) + Church = District("church", DistrictTypeList.Religious, 2, 3) + Monastery = District("monastery", DistrictTypeList.Religious, 3, 3) + Cathedral = District("cathedral", DistrictTypeList.Religious, 5, 2) + + Estate = District("estate", DistrictTypeList.Noble, 3, 5) + Castle = District("castle", DistrictTypeList.Noble, 4, 4) + Palazzo = District("castle", DistrictTypeList.Noble, 5, 3) + + Tavern = District("tavern", DistrictTypeList.Trade, 1, 5) + Market = District("market", DistrictTypeList.Trade, 2, 4) + Shop = District("shop", DistrictTypeList.Trade, 2, 3) + Port = District("port", DistrictTypeList.Trade, 3, 3) + Harbor = District("harbor", DistrictTypeList.Trade, 4, 3) + Guildhall = District("guildhall", DistrictTypeList.Trade, 5, 2) + + @staticmethod + def take_the_cards(number=1, type_of_district=None): + return random.choices([i for i in DistrictsList if (type_of_district is None or i.value.type_of_district == type_of_district)], k=number) + diff --git a/server/Player.py b/server/Player.py index 664df9b..0079211 100644 --- a/server/Player.py +++ b/server/Player.py @@ -1,17 +1,94 @@ from server.Characters.Character import Character +from server.Characters.CharactersList import CharactersList +from server.District import DistrictsList class Player(object): - def __init__(self, player_name): self.character = Character(None) self.player_name = player_name + self.districts_in_hand = DistrictsList.take_the_cards(4) + self.districts_in_table = set() + self.gold = 2 def choose_character(self, character): - self.character = character + self.character = Character(character.name) def get_info(self): - pass + self.character.get_info(self.character) def get_progress_information(self): - pass + return self.character.get_progress_information(self.character) if self.character else "" + + def get_districts_in_hand(self, list_of_districts): + self.districts_in_hand.extend(list_of_districts) if self.character else "" + + def put_cards_on_the_table(self, districts): + for district in districts: + if district not in self.districts_in_table: + self.districts_in_hand.remove(district) + self.districts_in_table.add(district) + self.change_gold(district.value.price) + + def character_move(self, other_player, district): + match self.character: + case CharactersList.Assassin: + self.character.action(self, other_player, None) + case CharactersList.Thief: + self.character.action(self, other_player, None) + case CharactersList.Magician: + self.character.action(self, other_player, []) + case CharactersList.King: + self.character.action(self, None, None) + case CharactersList.Bishop: + self.character.action(self, None, None) + case CharactersList.Merchant: + self.character.action(self, None, None) + case CharactersList.Architect: + self.character.action(self, None, None) + case CharactersList.Warlord: + self.character.action(self, other_player, district) + + def second_move(self, change_move): + if change_move == 1: + self.change_gold(2) + return None + elif change_move == 2: + return DistrictsList.take_the_cards(2) + + def after_move(self): + if self.character == CharactersList.Architect: + self.get_districts_in_hand(DistrictsList.take_the_cards(2)) + elif self.character == CharactersList.Merchant: + self.change_gold(1) + + def second_move_path_two(self, district): + self.get_districts_in_hand([district]) + + def return_districts(self): + return self.districts_in_table, self.districts_in_hand + + def change_gold(self, number): + self.gold += number + + def number_of_districts_can_build(self): + return self.character.number_of_districts_can_build() + + +# player1 = Player("Alex") +# player2 = Player("Ksenia") +# player3 = Player('Artem') +# player4 = Player('Dima') +# +# player2.choose_character(CharactersList.Thief) +# player1.choose_character(CharactersList.Assassin) +# player3.choose_character(CharactersList.Bishop) +# player4.choose_character(CharactersList.Merchant) +# +# for i in [player1, player2, player3, player4]: +# i.character_move(player2, []) +# i.second_move(1) +# i.second_move_path_two([]) +# i.after_move() +# i.get_info() +# i.put_cards_on_the_table(i.districts_in_hand[1:3])