Example #1
0
 def join_player(self, player: PlayerLogic, is_admin: bool) -> None:
     if self.get_state() != GameLogic.State.WAITROOM:
         raise UserError("Невозможно присоединиться к запущенной игре",
                         error_type=UserError.ErrorType.INVALID_GAME)
     if is_admin:
         player.make_admin()
     self.set_dirty()
Example #2
0
    def deal_roundcompleted(self, player: PlayerLogic, avg_spend: int):
        player_off_cards_count = len([
            x for x in player.get_hand()
            if x.model.type.enumType == CardTypeEnum.OFFENCE
        ])
        self.deal(player, self.card_manager.get_type(CardTypeEnum.OFFENCE),
                  self.params.initial_offence_cards - player_off_cards_count)

        player_def_cards_count = len([
            x for x in player.get_hand()
            if x.model.type.enumType == CardTypeEnum.DEFENCE
        ])
        def_card_count = 0
        if self.params.def_card_deal == DefCardDeal.DealFixed:
            def_card_count = self.params.def_card_deal_size
        elif self.params.def_card_deal == DefCardDeal.KeepSize:
            def_card_count = self.params.initial_defence_cards - player_def_cards_count
        elif self.params.def_card_deal == DefCardDeal.RemainingPlusFixed:
            def_card_count = player_def_cards_count + self.params.def_card_deal_size
        elif self.params.def_card_deal == DefCardDeal.DealPlayerCount:
            def_card_count = len(self.model.players)
        elif self.params.def_card_deal == DefCardDeal.DealAverageSpend:
            def_card_count = avg_spend
        def_card_count = max(0, def_card_count)
        self.deal(player, self.card_manager.get_type(CardTypeEnum.DEFENCE),
                  def_card_count)
Example #3
0
    def complete_battle(self, battle: BattleLogic, bypass=False):
        if not bypass:
            self.assert_running()
        self.set_dirty()
        btl_model = battle.model
        if not bypass and btl_model.offensiveCard is None:
            raise UserError("Нельзя завершить битву без карты атаки!")
        if not bypass:
            self.calculate_battle_falsics(battle)
        btl_model.isComplete = True
        if self.cur_round.isAccidentComplete:
            next_player = self.get_neighbour(
                PlayerLogic(self.db, btl_model.offendingPlayer))
            if next_player != self.get_players(True)[0].model:
                self.start_battle(PlayerLogic(self.db, next_player))

        if all(map(lambda b: b.model.isComplete, self.get_battles())):
            if btl_model.offensiveCard is not None and btl_model.offensiveCard.type.enumType == CardTypeEnum.ACCIDENT:
                print("Round", self.cur_round.roundNo,
                      "has accident completed")
                self.on_accident_played()
            else:
                print("Round", self.cur_round.roundNo, "is complete")
                self.on_round_completed()
                if not self.is_complete():
                    self.new_round()
Example #4
0
 def leave_player(self, player: PlayerLogic):
     player.leave()
     if self.is_running():
         player.model.neighbourLeft.neighbourRight = player.model.neighbourRight
         for battle in self.get_battles(False):
             if battle.model.offendingPlayer == player.model \
                     or battle.model.defendingPlayer == player.model \
                     and not battle.model.isComplete:
                 self.complete_battle(battle, True)
                 self.db.session.delete(battle.model)
Example #5
0
 def play_card(self, card: CardLogic, player: PlayerLogic):
     if not self.can_play_card(card, player):
         raise UserError("Сейчас нельзя сыграть эту карту")
     self.set_dirty()
     battle = self.get_player_battle(player)
     if battle.offendingPlayer == player.model:
         battle.offensiveCard = card.model
     else:
         BattleLogic(self.db, battle).add_defensive_card(card)
     player.drop_card(card)
Example #6
0
def prepare_state(game: GameLogic, player: PlayerLogic) -> GameState:
    pm = PlayerManager(db)
    if player is None:
        return GameState(redirect_to='/')
    players = game.get_players(False)
    round_number = 0 if game.cur_round is None else game.cur_round.roundNo
    ui_game = UiGame(
        game_name=game.model.uniqueCode,
        self_player=player.model.id,
        players=[
            UiPlayer(
                id=p.model.id,
                name=p.model.name,
                is_admin=p.model.isAdmin,
                is_online=p.model.isOnline,
                has_left=p.model.hasLeft,
                on_offence=False,
                on_defence=False,
                neighbour_right=p.model.neighbourId,
                can_attack=game.can_attack(player, p),
                money=p.get_money(),
            ) for p in players
        ],
        hand=map_opt(lambda c: make_ui(c, game, player), player.get_hand()),
        current_battles=[battle.to_ui() for battle in game.get_battles(True)],
        round_no=round_number,
        is_complete=game.is_complete(),
    )

    return GameState(redirect_to='', game=ui_game)
Example #7
0
    def can_play_card(self, card: CardLogic, player: PlayerLogic) -> bool:
        if not self.is_running():
            return False
        my_battle = self.get_player_battle(player)
        if my_battle is None:
            return False
        if my_battle.isComplete:
            return False
        if my_battle.defendingPlayer is None:
            return False
        # Can't play a card we don't have
        if not any(map(lambda x: x.model == card.model, player.get_hand())):
            return False
        # If we're on offence
        if my_battle.offendingPlayer == player.model:
            # Card is already played
            if my_battle.offensiveCard is not None:
                return False
            return card.model.type.enumType == CardTypeEnum.OFFENCE

        # We're on defence then
        if card.model.type.enumType != CardTypeEnum.DEFENCE:
            return False
        cur_damage = BattleLogic(self.db, my_battle).get_curdamage()
        if cur_damage is None or cur_damage <= 0:
            # The round is either fully played, or has no offensive card yet
            return False
        return self.params.hardcore_mode or replace_none(
            card.get_defence_from(my_battle.offensiveCard), 0) > 0
Example #8
0
 def calculate_battle_falsics(self, battle: BattleLogic):
     btl_model = battle.model
     if btl_model.offensiveCard.isCovid:
         transfer_amount = btl_model.defendingPlayer.money // 2
         PlayerLogic(
             self.db,
             self.get_neighbour(
                 PlayerLogic(self.db,
                             btl_model.defendingPlayer))).change_money(
                                 transfer_amount)
         PlayerLogic(
             self.db,
             btl_model.defendingPlayer).change_money(-transfer_amount)
     else:
         PlayerLogic(self.db, btl_model.defendingPlayer).change_money(
             -battle.get_curdamage())
Example #9
0
 def get_players(self, only_live):
     all_players = [
         PlayerLogic(self.db, x, self) for x in self.model.players
     ]
     if only_live:
         return [p for p in all_players if p.is_alive()]
     else:
         return all_players
Example #10
0
 def create_player(self, name: str, game: 'GameLogic') -> PlayerLogic:
     player = Player(name=name, game=game.model, money=0, isAdmin=False, isOnline=False)
     self.db.session.add(player)
     try:
         self.db.session.commit()
     except IntegrityError as e:
         print("Player creation problem: " + str(e))
         self.db.session.rollback()
         raise UserError("Игрок с таким именем уже существует. Пожалуйста, измените имя.",
                         UserError.ErrorType.INVALID_NAME)
     return PlayerLogic(self.db, player)
Example #11
0
 def can_attack(self, me: PlayerLogic, defender: PlayerLogic):
     if not self.is_running():
         return False
     if me.model == defender.model:
         # Logically, the rules don't forbid attacking self... But it's nonsense, right?
         # We don't have tail loss here, but the player might want to get rid of defense cards?..
         return False
     if not defender.is_alive():
         return False
     if not self.cur_round.isAccidentComplete:
         return False
     my_battle = self.get_player_battle(me)
     if my_battle is None:
         return False
     if my_battle.offendingPlayer != me.model:
         return False
     return my_battle.defendingPlayer is None
Example #12
0
 def start_battle(self, offendingPlayer: PlayerLogic):
     self.assert_running()
     new_battle_no = 0
     if any(self.cur_round.battles):
         new_battle_no = max(
             map(lambda x: x.creationOrder, self.cur_round.battles)) + 1
     new_battle = RoundBattle(
         round=self.cur_round,
         offendingPlayer=None
         if offendingPlayer is None else offendingPlayer.model,
         isComplete=False,
         creationOrder=new_battle_no)
     self.db.session.add(new_battle)
     self.set_dirty()
     if not self.params.can_attack_anyone:
         self.attack(
             offendingPlayer,
             PlayerLogic(self.db,
                         self.get_neighbour(offendingPlayer),
                         game=self))
     return new_battle
Example #13
0
 def get_player(self, id: int) -> PlayerLogic:
     player = Player.query.filter_by(id=id).first()
     if player is None:
         return None
     return PlayerLogic(self.db, player)