示例#1
0
    def apply(self, action: "PlayCard", game: "Game") -> GameUpdate:
        logger.info("latex-glove played")

        update = GameUpdate(game)

        for player in game.get_unfinished_players():
            if player == action.caller:
                continue

            # Vaciamos la mano del oponente
            player.empty_hand(return_to=game.deck)
            # Añadimos la mano vacía al GameUpdate
            update.add(player.name, {"hand": []})

        update.msg = "un Guante de Látex"
        return update
示例#2
0
    def apply(self, action: "PlayCard", game: "Game") -> GameUpdate:
        self.get_action_data(action, game)

        # Comprobamos que la pila tiene órgano
        if self.organ_pile.is_empty():
            raise GameLogicException("No puedes robar órganos inexistentes")

        # Comprobamos que ninguno de los dos órganos está inmunizado
        if self.organ_pile.is_immune():
            raise GameLogicException("No puedes robar órganos inmunes")

        # Comprobamos que el caller no tiene ya un órgano de ese color
        if not action.caller.body.organ_unique(self.organ_pile.organ):
            raise GameLogicException("Ya tienes un órgano de ese color")

        # Comprobamos que no se va a robar un órgano a sí mismo
        if action.caller == self.target:
            raise GameLogicException("No puedes robarte un órgano a ti mismo")

        # Obtenemos un espacio libre del caller
        self.empty_slot = None
        for (slot, pile) in enumerate(action.caller.body.piles):
            if pile.is_empty():
                self.empty_slot = slot
                break
        if self.empty_slot is None:
            raise GameLogicException("No tienes espacio libre")

        logger.info("organ-thief played")

        # Robamos la pila del target y la guardamos en el caller
        empty_pile = action.caller.body.piles[self.empty_slot]
        action.caller.body.piles[self.empty_slot] = self.organ_pile
        self.target.body.piles[self.organ_pile_slot] = empty_pile

        update = GameUpdate(game)
        # Añadimos el cuerpo del caller al GameUpdate
        update.repeat({
            "bodies": {
                self.target.name: self.target.body.piles,
                action.caller.name: action.caller.body.piles,
            },
        })

        update.msg = f"un Ladrón de Órganos sobre {self.target.name}"
        return update
示例#3
0
    def apply(self, action: "PlayCard", game: "Game") -> GameUpdate:
        self.get_action_data(action, game)

        # Comprobamos que las dos pilas tienen órgano
        if self.organ_pile1.is_empty() or self.organ_pile2.is_empty():
            raise GameLogicException(
                "No puedes intercambiar órganos inexistentes")

        # Comprobamos que ninguno de los dos órganos está inmunizado
        if self.organ_pile1.is_immune() or self.organ_pile2.is_immune():
            raise GameLogicException("No puedes intercambiar órganos inmunes")

        # Comprobamos que no se haga un transplante a sí mismo.
        if self.player1 == self.player2:
            raise GameLogicException(
                "No puedes intercambiar óganos entre el mismo jugador")

        # Comprobamos que ninguno de los dos jugadores tienen ya un órgano del
        # mismo color del órgano a añadir. NOTE: Ignoramos las pilas sobre las
        # que se va a reemplazar, porque no crean conflicto.
        if not (self.player1.body.organ_unique(self.organ_pile2.organ,
                                               ignored_piles=[self.pile_slot1])
                and self.player2.body.organ_unique(
                    self.organ_pile1.organ, ignored_piles=[self.pile_slot2])):
            raise GameLogicException("Ya tiene un órgano de ese color")

        logger.info("transplant played")

        update = GameUpdate(game)

        # Intercambiamos las pilas de ambos jugadores
        tmp = self.player1.body.piles[self.pile_slot1]
        self.player1.body.piles[self.pile_slot1] = self.player2.body.piles[
            self.pile_slot2]
        self.player2.body.piles[self.pile_slot2] = tmp
        # Añadimos los dos cuerpos al GameUpdate
        update.repeat({
            "bodies": {
                self.player1.name: self.player1.body.piles,
                self.player2.name: self.player2.body.piles,
            },
        })

        update.msg = f"un Transplante entre {self.player1.name} y {self.player2.name}"
        return update
示例#4
0
    def apply(self, action: "PlayCard", game: "Game") -> GameUpdate:
        self.get_action_data(action, game)

        if action.caller == self.target:
            raise GameLogicException(
                "No puedes intercambiar tu cuerpo contigo mismo")

        logger.info("medical-error played")

        update = GameUpdate(game)

        # Intercambiamos los cuerpos de ambos jugadores
        action.caller.body, self.target.body = self.target.body, action.caller.body
        # Añadimos los dos cuerpos al GameUpdate
        update.repeat({
            "bodies": {
                self.target.name: self.target.body.piles,
                action.caller.name: action.caller.body.piles,
            },
        })

        update.msg = f"un Error Médico sobre {self.target.name}"
        return update
示例#5
0
    def apply(self, action: "PlayCard", game: "Game") -> GameUpdate:
        logger.info("infection played")

        # Diccionario: color -> lista de pilas con virus de ese color
        virus = dict()
        for color in Color:
            virus[color] = []

        # Listamos los virus que tiene en el cuerpo accediendo en orden
        # aleatorio a las pilas.
        for pile in random.sample(action.caller.body.piles, 4):
            if pile.is_infected():
                color = pile.get_top_color()
                virus[color].append(pile)

        if all(map(lambda x: len(x) == 0, virus.values())):
            raise GameLogicException("No tienes virus disponibles")

        # Lista de pilas libres de todos los jugadores
        candidates = []

        # Accederemos a los jugadores en orden aleatorio
        unfinished = game.get_unfinished_players()
        random.shuffle(unfinished)
        for player in unfinished:
            # Eliminamos al caller de la iteración
            if player == action.caller:
                continue

            # Añadimos las pilas libres a la lista de candidatas
            candidates.extend(
                list(filter(lambda p: p.is_free(), player.body.piles)))

        if len(candidates) == 0:
            raise GameLogicException(
                "No hay nadie que pueda recibir tus virus")

        # Aplicamos un orden aleatorio también a las pilas candidatas
        for candidate_pile in random.sample(candidates, len(candidates)):
            color = candidate_pile.get_top_color()

            # Asignamos el primer virus de ese color y lo quitamos de los
            # posibles.

            if len(virus[color]) == 0:
                # Si no hay virus de ese color -> comprobamos si hay virus
                # multicolor
                if len(virus[Color.All]) > 0:
                    color = Color.All
                else:  # No tenemos opción
                    continue

            pile = virus[color].pop()
            # Eliminamos el virus del cuerpo del caller
            pile.pop_modifiers()
            # Lo colocamos en la pila candidata
            candidate_pile.add_modifier(Virus(color=color))

        # Por simplificar, devolvemos el cuerpo de todos los jugadores
        update = GameUpdate(game)
        for player in game.players:
            body_update = GameUpdate(game)
            body_update.repeat({"bodies": {player.name: player.body.piles}})
            update.merge_with(body_update)

        update.msg = "un Contagio"
        return update