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
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
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
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
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