Advertisement
Guest User

Untitled

a guest
Jul 7th, 2015
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 36.14 KB | None | 0 0
  1. # coding=utf-8
  2. import random
  3.  
  4. from carta import CartaClimax, CartaPersonaje, CartaEvento
  5.  
  6. BENEFICIO_AUMENTAR_CLOCK = 2
  7.  
  8. NIVEL_MAX = 4
  9. CLOCK_PARA_NIVEL = 7
  10.  
  11. RETAGUARDIA = 2
  12. CAMPO_FRONTAL = 1
  13. ZONAS = [RETAGUARDIA, CAMPO_FRONTAL]
  14.  
  15. FRONTAL_IZQUIERDA = -1
  16. FRONTAL_CENTRO = 0
  17. FRONTAL_DERECHA = 1
  18. POSICIONES_CAMPO_FRONTAL = [FRONTAL_IZQUIERDA, FRONTAL_CENTRO, FRONTAL_DERECHA]
  19.  
  20. RETAGUARDIA_IZQUIERDA = 0
  21. RETAGUARDIA_DERECHA = 1
  22. POSICIONES_RETAGUARDIA = [RETAGUARDIA_IZQUIERDA, RETAGUARDIA_DERECHA]
  23.  
  24. SCHWARZ = "Schwarz"
  25. WEISS = "Weiss"
  26.  
  27. SIN_GANADOR = ""
  28.  
  29. EFECTO_CONTINUO = 0
  30. EFECTO_TEMPORAL = 1
  31.  
  32. POSICION_DESTRUIR_DEFENSOR = 1
  33. POSICION_DESTRUIR_ATACANTE = 0
  34.  
  35.  
  36. class _CampoJugador(object):
  37.     """ Campo de un jugador. Mantiene el estado de su campo de juego, ejecuta y resuelve las acciones efectuadas por el
  38.        jugador y las fases del juego (robar cartas, poner en el campo, combate, etc.)."""
  39.  
  40.     def __init__(self, nombre, mazo):
  41.         """
  42.        :param nombre: Nombre del jugador.
  43.        :param mazo: Mazo del jugador
  44.        :return: No tiene valor de retorno.
  45.        """
  46.         self.area_clock = []
  47.         self.area_recursos = []
  48.         self.area_nivel = []
  49.         self.area_climax = None
  50.         self.area_espera = []
  51.         self.campo_frontal = [None, None, None]
  52.         self.retaguardia = [None, None]
  53.  
  54.         self.mazo = mazo
  55.         self.nombre = nombre
  56.  
  57.     def recibir_ataque(self, posicion_atacante, posicion_defensor, campo_oponente, interfaz):
  58.         """
  59.        Resuelve el combate entre la carta en posicion_atacante en el campo frontal del jugador y la carta en
  60.        posicion_defensor del campo frontal del oponente. Devuelve el resultado del ataque, indicando que carta/s
  61.        deben destruirse.
  62.        :param posicion_atacante: Posicion en el campo del atacante de la carta atacante. Debe ser una de las
  63.                                  constantes FRONTAL_IZQUIERDA,FRONTAL_CENTRO o FRONTAL_DERECHA.
  64.        :param posicion_defensor: Posicion en el campo del defensor de la carta defensora. Debe ser una de las
  65.                                  constantes FRONTAL_IZQUIERDA,FRONTAL_CENTRO o FRONTAL_DERECHA.
  66.        :param campo_oponente: Referencia a un objeto de clase _CampoJugador, que corresponde al campo del oponente.
  67.        :param interfaz: Referencia a la interfaz grafica.
  68.        :return: Lista de la forma [destruir_atacante, destruir_defensora]. Cada posicion es True si la carta debe ser
  69.        destruida, False en caso contrario.
  70.        """
  71.         numero_carta_atacante = POSICIONES_CAMPO_FRONTAL.index(posicion_atacante)
  72.         numero_carta_defensor = POSICIONES_CAMPO_FRONTAL.index(posicion_defensor)
  73.         carta_atacante = self.campo_frontal[numero_carta_atacante]
  74.         carta_defensora = campo_oponente.campo_frontal[numero_carta_defensor]
  75.         resultado = [False, False]
  76.  
  77.         # Si el atacante tiene poder igual o menor al defensor, el combate resulta en empate o derrota
  78.         if carta_defensora and carta_atacante.poder <= carta_defensora.poder:
  79.             # Em ambos casos se destruye el atacante
  80.             resultado[POSICION_DESTRUIR_ATACANTE] = True
  81.             # Si tienen el mismo poder, es un empate y se destruye también el defensor
  82.             if carta_atacante.poder == carta_defensora.poder:
  83.                 resultado[POSICION_DESTRUIR_DEFENSOR] = True
  84.             return resultado
  85.  
  86.         # Si se gana el combate (haya o no defensor), se activa el efecto extra del ataque
  87.         carta_efecto_extra = self.mazo.robar_carta()
  88.         puntos_efecto_extra = carta_efecto_extra.obetener_puntos_efecto_extra()
  89.         puntos_alma = carta_atacante.puntos_alma + puntos_efecto_extra
  90.  
  91.         # Si no hay defensor, es un ataque directo y suma bono a los puntos de alma
  92.         if not carta_defensora:
  93.             puntos_alma += 1
  94.         # Si hay defensor y su poder es menor que el atacante, se destruye
  95.         elif carta_atacante.poder > carta_defensora.poder:
  96.             resultado[POSICION_DESTRUIR_DEFENSOR] = True
  97.  
  98.         # Se muestra la carta del efecto extra y el bono que suma en la interfaz
  99.         interfaz.mostrar_carta(carta_efecto_extra,
  100.                                "Carta efecto extra: +" + str(puntos_efecto_extra) + " puntos de alma")
  101.         # Se aplica el daño al oponente
  102.         campo_oponente.resolver_ataque(puntos_alma, interfaz)
  103.         # La carta de efecto extra se guarda como recurso
  104.         self.area_recursos.append(carta_efecto_extra)
  105.  
  106.         return resultado
  107.  
  108.     def subir_nivel(self, interfaz):
  109.         """
  110.        Sube el nivel del jugador. Vacia el area de clock, colocando una carta aleatoria en el area de nivel y el resto
  111.        en el area de espera.
  112.        :param interfaz: Referencia a la interfaz grafica.
  113.        :return: No tiene valor de retorno.
  114.        """
  115.         # Eleccion de la carta a mover de zona
  116.         carta_seleccionada = random.choice(self.area_clock)
  117.         self.area_clock.remove(carta_seleccionada)
  118.         self.area_nivel.append(carta_seleccionada)
  119.         # Vacia el area de clock
  120.         self.area_espera += self.area_clock
  121.         self.area_clock = []
  122.  
  123.         interfaz.mostrar_informacion(
  124.             "Jugador: " + self.nombre + " subio de nivel\n\nNivel actual:" + str(self.obtener_nivel()),
  125.             "Aumento de nivel")
  126.  
  127.     def resolver_ataque(self, puntos_alma, interfaz):
  128.         """
  129.        Aplica un daño igual a la cantidad de puntos de alma recibidos por parametro. Roba del mazo esa cantidad de
  130.        cartas y las envia al area de clock, salvo que el daño sea cancelado por una carta de Climax. En ese caso, se
  131.        dejan de robar cartas, y las ya tomadas se envian al area de espera.
  132.        :param puntos_alma: Puntos de alma de la carta que esta haciendo el daño. Debe ser un entero mayor a 0.
  133.        :param interfaz: Referencia a la interfaz grafica.
  134.        :return: No tiene valor de retorno.
  135.        """
  136.         # Se envian al area de clock tantas cartas como puntos de daño se reciba
  137.         cartas_a_descartar = []
  138.         for c in xrange(puntos_alma):
  139.             cartas_a_descartar.append(self.mazo.robar_carta())
  140.             # Si la carta es una carta de climax, se cancela el daño y las cartas ya robadas van al area de espera
  141.             if isinstance(cartas_a_descartar[-1], CartaClimax):
  142.                 interfaz.mostrar_informacion("Sacada carta: {0}\n Daño cancelado".format(str(cartas_a_descartar[-1])),
  143.                                              "Daño cancelado")
  144.                 for carta in cartas_a_descartar:
  145.                     self.area_espera.append(carta)
  146.                 return
  147.         self.area_clock += cartas_a_descartar
  148.  
  149.         interfaz.mostrar_informacion("El jugador " + self.nombre + " recibio " + str(puntos_alma) + " puntos de daño",
  150.                                      "Daño recibido")
  151.  
  152.         # Si la cantidad de cartas en el area de clock es suficiente para subir de nivel, se sube
  153.         if len(self.area_clock) >= CLOCK_PARA_NIVEL:
  154.             self.subir_nivel(interfaz)
  155.  
  156.     def remover_carta(self, zona_campo, posicion_carta):
  157.         """
  158.        Remueve la carta del campo y la envia a la zona de espera.
  159.        :param zona_campo: Zona en la que se encuentra la carta a remover. Debe ser una de las constantes CAMPO_FRONTAL
  160.                           o RETAGUARDIA.
  161.        :param posicion_carta: Posicion en la zona del campo de la carta. Debe ser una de las constantes
  162.                               FRONTAL_IZQUIERDA,FRONTAL_CENTRO o FRONTAL_DERECHA si es del campo frontal, o
  163.                               RETAGUARDIA_IZQUIERDA o RETAGUARDIA_DERECHA si es de la retaguardia.
  164.        :return: La carta removida.
  165.        """
  166.         if zona_campo == CAMPO_FRONTAL:
  167.             numero_de_carta = POSICIONES_CAMPO_FRONTAL.index(posicion_carta)
  168.             carta_removida = self.campo_frontal[numero_de_carta]
  169.             self.campo_frontal[numero_de_carta] = None
  170.         elif zona_campo == RETAGUARDIA:
  171.             numero_de_carta = POSICIONES_RETAGUARDIA.index(posicion_carta)
  172.             carta_removida = self.retaguardia[numero_de_carta]
  173.             self.retaguardia[numero_de_carta] = None
  174.         self.area_espera.append(carta_removida)
  175.         return carta_removida
  176.  
  177.     def robar_cartas(self, cantidad):
  178.         """
  179.        Roba del mazo la cantidad de cartas especificada. Si el mazo contiene menos cartas que las que se quieren
  180.        robar, se toman todas las que haya y se recarga el mazo.
  181.        :param cantidad: Cantidad de cartas a remover. Debe ser un entero mayor o igual a 0.
  182.        :return: Lista con las cartas que se robaron del mazo.
  183.        """
  184.         cartas_robadas = []
  185.         while (not self.mazo.esta_vacio()) and (cantidad > len(cartas_robadas)):
  186.             cartas_robadas.append(self.mazo.robar_carta())
  187.  
  188.         if self.mazo.esta_vacio():
  189.             self.recargar_mazo()
  190.  
  191.         return cartas_robadas
  192.  
  193.     def recargar_mazo(self):
  194.         """
  195.        Saca todas las cartas del area de espera y las coloca mezcladas en el mazo (tenga o no otras cartas).
  196.        :return: No tiene valor de retorno.
  197.        """
  198.         self.mazo.agregar_cartas(self.area_espera)
  199.         self.mazo.mezclar()
  200.         self.area_espera = []
  201.  
  202.     def obtener_cantidad_clock(self):
  203.         """
  204.        Devuelve la cantidad de cartas en el area de clock.
  205.        :return: Entero mayor o igual a 0, igual a la cantidad de cartas en el area de clock.
  206.        """
  207.         return len(self.area_clock)
  208.  
  209.     def obtener_nivel(self):
  210.         """
  211.        Devuelve el nivel del jugador, que es igual a la cantidad de cartas en el area de nivel.
  212.        :return: Entero mayor o igual a 0, igual a la cantidad de cartas en el area de nivel.
  213.        """
  214.         return len(self.area_nivel)
  215.  
  216.     def aumentar_clock(self, carta):
  217.         """
  218.        Coloca la carta pasada por parametro en el area de clock, y roba del mazo una cantidad de cartas igual a la
  219.        constante BENEFICIO_AUMENTAR_CLOCK.
  220.        :param carta: Carta a poner en el area de clock.
  221.        :return: Lista de las cartas robadas del mazo.
  222.        """
  223.         self.area_clock.append(carta)
  224.         return self.robar_cartas(BENEFICIO_AUMENTAR_CLOCK)
  225.  
  226.     def obtener_colores_clock(self):
  227.         """
  228.        Devuelve una lista con todos los colores de cartas que hay en el area de clock.
  229.        :return: Lista de strings.
  230.        """
  231.         colores = {}
  232.         for carta in self.area_clock:
  233.             colores[carta.obtener_color()] = 0
  234.         return colores.keys()
  235.  
  236.     def obtener_colores_nivel(self):
  237.         """
  238.        Devuelve una lista con todos los colores de cartas que hay en el area de nivel.
  239.        :return: Lista de strings.
  240.        """
  241.         colores = {}
  242.         for carta in self.area_nivel:
  243.             colores[carta.obtener_color()] = 0
  244.         return colores.keys()
  245.  
  246.     def obtener_colores_recursos(self):
  247.         """
  248.        Devuelve una lista con todos los colores de cartas que hay en el area de recursos.
  249.        :return: Lista de strings.
  250.        """
  251.         colores = {}
  252.         for carta in self.area_recursos:
  253.             colores[carta.obtener_color()] = 0
  254.         return colores.keys()
  255.  
  256.     def puede_jugar_carta(self, carta):
  257.         """
  258.        Devuelve si la carta pasada por parametro pueda ser jugada o no.
  259.        :param carta: Carta que se quiere jugar.
  260.        :return: Booleano que indica si la carta pasada puede jugarse o no.
  261.        """
  262.         # Se chequea si hay lugar en el campo
  263.         if None not in self.campo_frontal + self.retaguardia:
  264.             return False
  265.         # Se chequea si el nivel del jugador es mayor o igual que el de la carta
  266.         if carta.obtener_nivel() > self.obtener_nivel():
  267.             return False
  268.         # Se chequea si la cantidad de cartas en el area de recursos alcanzan para pagar el costo de la carta
  269.         if carta.obtener_costo() > len(self.area_recursos):
  270.             return False
  271.         # Se chequea si se pueden jugar cartas de ese color
  272.         playable_colors = self.obtener_colores_clock()
  273.         playable_colors += self.obtener_colores_nivel()
  274.         if carta.obtener_color() not in playable_colors:
  275.             if carta.obtener_nivel() != 0:
  276.                 return False
  277.  
  278.         return True
  279.  
  280.     def pagar_costo(self, costo_a_pagar):
  281.         """
  282.        Desapila del area de recursos una cantidad de cartas igual al costo pasado por parametro, y las mueve al area
  283.        de espera.
  284.        :param costo_a_pagar: Entero mayor o igual a 0, que indica el costo a pagar (cantidad de cartas a mover).
  285.        :return: No tiene valor de retorno.
  286.        """
  287.         for c in xrange(costo_a_pagar):
  288.             carta = self.area_recursos.pop()
  289.             self.area_espera.append(carta)
  290.  
  291.     def jugar_personaje(self, carta, interfaz):
  292.         """
  293.        Coloca, si se puede, la carta de personaje pasada por parametro en el campo. Despliega menues para seleccionar
  294.        en que zona del campo y posicion jugar la carta. Devuelve si la carta se pudo jugar o no.
  295.        :param carta: Carta de personaje que se quiere jugar.
  296.        :param interfaz: Referencia a la interfaz grafica.
  297.        :return: Booleano que indica si la carta fue colocada en el campo o no.
  298.        """
  299.         if not self.puede_jugar_carta(carta):
  300.             return False
  301.  
  302.         while True:
  303.             seleccion_zona = interfaz.obtener_entero("Ingrese la zona del campo donde jugar la carta:\n\n"
  304.                                                      "[1] Campo frontal\n[2] Retaguardia",
  305.                                                      titulo="Seleccion de zona del campo", intervalo=[1, len(ZONAS)])
  306.             if not seleccion_zona:
  307.                 return False
  308.             zona_campo = None
  309.             posicion = None
  310.  
  311.             if seleccion_zona == CAMPO_FRONTAL:
  312.                 posicion = interfaz.obtener_entero(
  313.                     "Ingrese la posicion dentro de la zona del campo:\n\n"
  314.                     "Posiciones: [1-" + str(len(POSICIONES_CAMPO_FRONTAL)) + "]",
  315.                     titulo="Seleccion de posicion", intervalo=[1, len(POSICIONES_CAMPO_FRONTAL)])
  316.                 zona_campo = self.campo_frontal
  317.             elif seleccion_zona == RETAGUARDIA:
  318.                 posicion = interfaz.obtener_entero(
  319.                     "Ingrese la posicion dentro de la zona del campo:\n\n"
  320.                     "Posiciones: [1-" + str(len(POSICIONES_RETAGUARDIA)) + "]",
  321.                     titulo="Seleccion de posicion", intervalo=[1, len(POSICIONES_RETAGUARDIA)])
  322.                 zona_campo = self.retaguardia
  323.  
  324.             if not posicion:
  325.                 return False
  326.  
  327.             posicion -= 1
  328.             if zona_campo[posicion]:
  329.                 interfaz.mostrar_informacion("No se puede jugar en esa posicion, esta ocupada", titulo="")
  330.                 if not interfaz.preguntar_si_no("Elegir otra posicion?", titulo=""):
  331.                     return False
  332.             else:
  333.                 zona_campo[posicion] = carta
  334.                 self.pagar_costo(carta.obtener_costo())
  335.                 return True
  336.  
  337.     def puede_jugar_carta_climax(self, carta):
  338.         """
  339.        Devuelve si la carta de climax pasada por parametro pueda ser jugada o no.
  340.        :param carta: Carta de climax que se quiere jugar.
  341.        :return: Booleano que indica si la carta de climax pasada puede jugarse o no.
  342.        """
  343.         # Si hay una carta en el area de climax no puede jugarse otra
  344.         if self.area_climax:
  345.             return False
  346.  
  347.         colores_jugables = self.obtener_colores_clock()
  348.         colores_jugables += self.obtener_colores_nivel()
  349.         if carta.obtener_color() not in colores_jugables:
  350.             return False
  351.  
  352.         return True
  353.  
  354.     def jugar_evento(self, carta, interfaz):
  355.         """
  356.        Juega, si se puede, la carta de evento pasada por parametro. Devuelve si la carta se pudo jugar o no.
  357.        :param carta: Carta de evento que se quiere jugar.
  358.        :param interfaz: Referencia a la interfaz grafica.
  359.        :return: Booleano que indica si la carta fue jugada o no.
  360.        """
  361.         if not self.puede_jugar_carta(carta):
  362.             return False
  363.         self.pagar_costo(carta.obtener_costo())
  364.         self.area_espera.append(carta)
  365.         return True
  366.  
  367.     def jugar_climax(self, carta, interfaz):
  368.         """
  369.        Coloca, si se puede, la carta de climax pasada por parametro en el campo. Devuelve si la carta se pudo jugar.
  370.        :param carta: Carta de climax que se quiere jugar.
  371.        :param interfaz: Referencia a la interfaz grafica.
  372.        :return: Booleano que indica si la carta fue jugada o no.
  373.        """
  374.         if not self.puede_jugar_carta_climax(carta):
  375.             return False
  376.         self.area_climax = carta
  377.         return True
  378.  
  379.     def remover_climax(self):
  380.         """
  381.        Remueve la carta del area de climax, si hay alguna, y la coloca en el area de espera.
  382.        :return: No tiene valor de retorno.
  383.        """
  384.         if not self.area_climax:
  385.             return
  386.         self.area_espera.append(self.area_climax)
  387.         self.area_climax = None
  388.  
  389.     def obtener_mazo(self):
  390.         """
  391.        Devuelve el mazo
  392.        """
  393.         return self.mazo
  394.  
  395.     def descartar_carta(self, carta):
  396.         """
  397.        Agrega una carta al tope de la zona de espera
  398.        :param carta: Carta que se quiere descartar
  399.        :return: No tiene valor de retorno
  400.        """
  401.         self.area_espera.append(carta)
  402.  
  403.     def remover_carta_clock(self):
  404.         """
  405.        Saca la ultima carta del area de clock
  406.        :return: Carta la ultima carta del area de clock
  407.        """
  408.         return self.area_clock.pop()
  409.  
  410.  
  411.     def obtener_cantidad_recursos(self):
  412.         """
  413.        Devuelve la cantidad de cartas en el area de recursos.
  414.        :return: Entero mayor o igual a 0, igual a la cantidad de cartas en el area de recursos.
  415.        """
  416.         return len(self.area_recursos)
  417.  
  418.     def obtener_area_nivel(self):
  419.         """
  420.        Devuelve el area de nivel
  421.        :return: Lista con las cartas del area de nivel
  422.        """
  423.         return self.area_nivel
  424.  
  425.  
  426. class TableroJuego(object):
  427.     """ Tablero de juego. Mantiene los campos de los dos jugadores, las habilidades aplicadas (tanto actuales como en
  428.        turnos anteriores) y la referencia a la interfaz grafica. Ejecuta y resuelve las acciones efectuadas por los
  429.        jugadores y las fases del juego (robar cartas, poner en el campo, combate, etc.)."""
  430.  
  431.     def __init__(self, interfaz, mazo_weiss, mazo_schwarz):
  432.         """
  433.        :param interfaz: Refencia a la interfaz grafica.
  434.        :param mazo_*: Referencia a un mazo
  435.        :return: No tiene valor de retorno.
  436.        """
  437.  
  438.         self.habilidades_aplicadas = []  # Debe comportarse como una pila
  439.         self.habilidades_turno_anterior = []  # Debe comportarse como una cola
  440.  
  441.         # Blanco (Weiss)
  442.         self.weiss = _CampoJugador(WEISS, mazo_weiss)
  443.         # Negro (Schwarz)
  444.         self.schwarz = _CampoJugador(SCHWARZ, mazo_schwarz)
  445.         self.interfaz = interfaz
  446.  
  447.     def obtener_oponente(self, jugador):
  448.         """
  449.        Devuelve el oponente del jugador pasado por parametro.
  450.        :param jugador: Jugador del que se desea obtener el oponente. Debe ser una de las constantes WEISS o SCHWARZ.
  451.        :return: Constante WEISS o SCHWARZ, dependiendo del jugador pasado por parametro.
  452.        """
  453.         if jugador == WEISS:
  454.             return SCHWARZ
  455.         return WEISS
  456.  
  457.     def obtener_campo_jugador(self, jugador):
  458.         """
  459.        Devuelve el campo de juego del jugador cuyo turno se esta jugando actualmente.
  460.        :param jugador: Jugador actual. Debe ser una de las constantes WEISS o SCHWARZ.
  461.        :return: _CampoJugador que corresponde al jugador actual.
  462.        """
  463.         if jugador == WEISS:
  464.             return self.weiss
  465.         return self.schwarz
  466.  
  467.     def remover_carta(self, jugador, zona_campo, posicion_carta):
  468.         """
  469.        Remueve la carta del campo del jugador y la envia a la zona de espera.
  470.        :param jugador: Jugador al que se le removera la carta. Debe ser una de las constantes WEISS o SCHWARZ.
  471.        :param zona_campo: Zona en la que se encuentra la carta a remover. Debe ser una de las constantes CAMPO_FRONTAL
  472.                           o RETAGUARDIA.
  473.        :param posicion_carta: Posicion en la zona del campo de la carta. Debe ser una de las constantes
  474.                               FRONTAL_IZQUIERDA,FRONTAL_CENTRO o FRONTAL_DERECHA si es del campo frontal, o
  475.                               RETAGUARDIA_IZQUIERDA o RETAGUARDIA_DERECHA si es de la retaguardia.
  476.        :return: La carta removida.
  477.        """
  478.         campo_jugador = self.obtener_campo_jugador(jugador)
  479.         carta_removida = campo_jugador.remover_carta(zona_campo, posicion_carta)
  480.         self.revertir_habilidades_sobre_carta(carta_removida)
  481.         self.remover_habilidad(jugador, carta_removida.obtener_habilidad())
  482.  
  483.     def declarar_ataque(self, jugador, posicion_atacante):
  484.         """
  485.        Efectua y resuelve el ataque de la carta que se encuentra en la posicion pasada por parametro el campo del
  486.        jugador pasado. Remueve las cartas que correspondan como resultado del ataque, y revierte las habilidades
  487.        aplicadas sobre ellas (si las hay).
  488.        :param jugador: Jugador atacante. Debe ser una de las constantes WEISS o SCHWARZ.
  489.        :param posicion_atacante: Posicion en el campo frontal del jugador de la carta atacante. Debe ser una de las
  490.                                  constantes FRONTAL_IZQUIERDA, FRONTAL_CENTRO o FRONTAL_DERECHA.
  491.        :return: No tiene valor de retorno.
  492.        """
  493.         campo_atacante = None
  494.         campo_defensor = None
  495.         if jugador == WEISS:
  496.             campo_atacante = self.weiss
  497.             campo_defensor = self.schwarz
  498.         elif jugador == SCHWARZ:
  499.             campo_atacante = self.schwarz
  500.             campo_defensor = self.weiss
  501.         oponente = self.obtener_oponente(jugador)
  502.         posicion_defensora = -1 * posicion_atacante
  503.         resultado = campo_atacante.recibir_ataque(posicion_atacante, posicion_defensora, campo_defensor, self.interfaz)
  504.         if resultado[POSICION_DESTRUIR_ATACANTE]:
  505.             self.remover_carta(jugador, CAMPO_FRONTAL, posicion_atacante)
  506.         if resultado[POSICION_DESTRUIR_DEFENSOR]:
  507.             self.remover_carta(oponente, CAMPO_FRONTAL, posicion_defensora)
  508.  
  509.     def jugar_carta(self, jugador, carta):
  510.         """
  511.        Juega, si se puede, la carta pasada por parametro. Devuelve si la carta pudo jugarse o no.
  512.        :param jugador: Jugador que juega la carta. Debe ser una de las constantes WEISS o SCHWARZ.
  513.        :param carta: Carta que se quiere jugar.
  514.        :return: Booleano que indica si se pudo jugar la carta o no.
  515.        """
  516.         if isinstance(carta, CartaPersonaje):
  517.             if self.jugar_personaje(jugador, carta):
  518.                 self.aplicar_habilidad_sobre_tablero(jugador, carta.obtener_habilidad(), EFECTO_CONTINUO)
  519.                 return True
  520.             return False
  521.         elif isinstance(carta, CartaEvento):
  522.             if self.jugar_evento(jugador, carta):
  523.                 self.aplicar_habilidad_sobre_tablero(jugador, carta.obtener_habilidad(), EFECTO_TEMPORAL)
  524.                 return True
  525.             return False
  526.         elif isinstance(carta, CartaClimax):
  527.             if self.jugar_climax(jugador, carta):
  528.                 self.aplicar_habilidad_sobre_tablero(jugador, carta.obtener_habilidad(), EFECTO_TEMPORAL)
  529.                 return True
  530.             return False
  531.         else:
  532.             return False
  533.  
  534.     def jugar_personaje(self, jugador, carta):
  535.         """
  536.        Coloca, si se puede, la carta de personaje pasada por parametro en el campo del jugador pasado. Devuelve si la
  537.        carta de personaje se pudo jugar o no.
  538.        :param jugador: Jugador que juega la carta. Debe ser una de las constantes WEISS o SCHWARZ.
  539.        :param carta: Carta de personaje que se quiere jugar.
  540.        :return: Booleano que indica si la carta fue colocada en el campo o no.
  541.        """
  542.         if not self.obtener_campo_jugador(jugador).jugar_personaje(carta, self.interfaz):
  543.             return False
  544.         self.aplicar_habilidades_en_carta(carta)
  545.         return True
  546.  
  547.     def jugar_evento(self, jugador, carta):
  548.         """
  549.        Juega, si se puede, la carta de evento pasada por parametro. Devuelve si la carta se pudo jugar o no.
  550.        :param jugador: Jugador que juega la carta. Debe ser una de las constantes WEISS o SCHWARZ.
  551.        :param carta: Carta de evento que se quiere jugar.
  552.        :return: Booleano que indica si la carta fue jugada o no.
  553.        """
  554.         return self.obtener_campo_jugador(jugador).jugar_evento(carta, self.interfaz)
  555.  
  556.     def jugar_climax(self, jugador, carta):
  557.         """
  558.        Coloca, si se puede, la carta de climax pasada por parametro en el campo del jugador pasado. Devuelve si la
  559.        carta se pudo jugar.
  560.        :param jugador: Jugador que juega la carta. Debe ser una de las constantes WEISS o SCHWARZ.
  561.        :param carta: Carta de climax que se quiere jugar.
  562.        :return: Booleano que indica si la carta fue jugada o no.
  563.        """
  564.         return self.obtener_campo_jugador(jugador).jugar_climax(carta, self.interfaz)
  565.  
  566.     def robar_cartas(self, jugador, cantidad=1):
  567.         """
  568.        Roba del mazo del jugador pasado por parametro la cantidad de cartas especificada. Si el mazo contiene menos
  569.        cartas que las que se quieren robar, se toman todas las que haya y se recarga el mazo.
  570.        :param jugador: Jugador que roba las cartas. Debe ser una de las constantes WEISS o SCHWARZ.
  571.        :param cantidad: Cantidad de cartas a remover. Debe ser un entero mayor o igual a 0.
  572.        :return: Lista con las cartas que se robaron del mazo.
  573.        """
  574.         return self.obtener_campo_jugador(jugador).robar_cartas(cantidad)
  575.  
  576.     def obtener_nivel_jugador(self, jugador):
  577.         """
  578.        Devuelve el nivel del jugador pasado por parametro.
  579.        :param jugador: Debe ser una de las constantes WEISS o SCHWARZ.
  580.        :return: Entero mayor o igual a 0 que indica el nivel del jugador.
  581.        """
  582.         return self.obtener_campo_jugador(jugador).obtener_nivel()
  583.  
  584.     def obtener_cantidad_clock(self, jugador):
  585.         """
  586.        Devuelve la cantidad de cartas en el area de clock del jugador pasado por parametro.
  587.        :param jugador: Debe ser una de las constantes WEISS o SCHWARZ.
  588.        :return: Entero mayor o igual a 0 que indica la cantidad de cartas en el area de clock del jugador.
  589.        """
  590.         return self.obtener_campo_jugador(jugador).obtener_cantidad_clock()
  591.  
  592.     def aumentar_clock(self, jugador, carta):
  593.         """
  594.        Coloca la carta pasada por parametro en el area de clock del jugador, y roba del mazo del mismo una cantidad de
  595.        cartas igual a la constante BENEFICIO_AUMENTAR_CLOCK.
  596.        :param jugador: Debe ser una de las constantes WEISS o SCHWARZ.
  597.        :param carta: Carta a poner en el area de clock.
  598.        :return: Lista de las cartas robadas del mazo.
  599.        """
  600.         return self.obtener_campo_jugador(jugador).aumentar_clock(carta)
  601.  
  602.     def puede_jugar_carta(self, jugador, carta):
  603.         """
  604.        Verifica si el jugador pasado por parametro puede jugar la carta pasada. Devuelve True si puede hacerlo, False
  605.        en caso contrario.
  606.        :param jugador: Jugador que quiere jugar la carta. Debe ser una de las constantes WEISS o SCHWARZ.
  607.        :param carta: Carta que se quiere verificar si puede ser jugada.
  608.        :return: Booleano que indica si se puede o no jugar la carta.
  609.        """
  610.         if isinstance(carta, CartaClimax):
  611.             return self.obtener_campo_jugador(jugador).puede_jugar_carta_climax(carta)
  612.         else:
  613.             return self.obtener_campo_jugador(jugador).puede_jugar_carta(carta)
  614.  
  615.     def obtener_ganador(self):
  616.         """
  617.        Devuelve el jugador ganador si hay uno (constantes WEISS o SCHWARZ), o SIN_GANADOR si no hay uno.
  618.        :return: Constante WEISS, SCHWARZ o SIN_SIN_GANADOR.
  619.        """
  620.         if self.weiss.obtener_nivel() == NIVEL_MAX:
  621.             return SCHWARZ
  622.         if self.schwarz.obtener_nivel() == NIVEL_MAX:
  623.             return WEISS
  624.         return SIN_GANADOR
  625.  
  626.     def obtener_cartas_campo_frontal(self, jugador):
  627.         """
  628.        Obtiene las cartas del campo frontal del jugador pasado por parametro y la devuelve.
  629.        :param jugador: Jugador del que se quiere obtener el campo frontal. Debe ser una de las constantes WEISS o
  630.                        SCHWARZ.
  631.        :return: Lista de cartas.
  632.        """
  633.         return self.obtener_campo_jugador(jugador).campo_frontal[:]
  634.  
  635.     def obtener_cartas_nivel(self, jugador):
  636.         """
  637.        Obtiene las cartas del area de nivel del jugador pasado por parametro y la devuelve.
  638.        :param jugador: Jugador del que se quiere obtener el campo frontal. Debe ser una de las constantes WEISS o
  639.                        SCHWARZ.
  640.        :return: Lista de cartas.
  641.        """
  642.         return self.obtener_campo_jugador(jugador).area_nivel[:]
  643.  
  644.     def obtener_cartas_recursos(self, jugador):
  645.         """
  646.        Obtiene las cartas del area de recursos del jugador pasado por parametro y la devuelve.
  647.        :param jugador: Jugador del que se quiere obtener el campo frontal. Debe ser una de las constantes WEISS o
  648.                        SCHWARZ.
  649.        :return: Lista de cartas.
  650.        """
  651.         return self.obtener_campo_jugador(jugador).area_recursos[:]
  652.  
  653.     def obtener_cartas_clock(self, jugador):
  654.         """
  655.        Obtiene las cartas del area de clock del jugador pasado por parametro y la devuelve.
  656.        :param jugador: Jugador del que se quiere obtener el campo frontal. Debe ser una de las constantes WEISS o
  657.                        SCHWARZ.
  658.        :return: Lista de cartas.
  659.        """
  660.         return self.obtener_campo_jugador(jugador).area_clock[:]
  661.  
  662.     def obtener_cartas_retaguardia(self, jugador):
  663.         """
  664.        Obtiene las cartas de la retaguardia del jugador pasado por parametro y la devuelve.
  665.        :param jugador: Jugador del que se quiere obtener el campo frontal. Debe ser una de las constantes WEISS o
  666.                        SCHWARZ.
  667.        :return: Lista de cartas.
  668.        """
  669.         return self.obtener_campo_jugador(jugador).retaguardia[:]
  670.  
  671.     def obtener_todas_campo_frontal(self):
  672.         """
  673.        Devuelve una lista con todas las cartas que se encuentran en los campos frontales de ambos jugadores.
  674.        :return: Lista de cartas. Las primeras tres cartas son las del jugador Weiss y las ultimas tres de Schwarz.
  675.        """
  676.         cartas = []
  677.         cartas += self.weiss.campo_frontal
  678.         cartas += self.schwarz.campo_frontal
  679.         return cartas
  680.  
  681.     def obtener_tope_espera(self, jugador):
  682.         """
  683.        Devuelve la carta que se encuentra en el tope del area de espera, o None si no hay ninguna.
  684.        :param jugador: Jugador del que se quiere obtener el tope del area de espera. Debe ser una de las constantes
  685.                        WEISS o SCHWARZ.
  686.        :return: Carta del tope del area de espera, o None si el area esta vacia.
  687.        """
  688.         if self.obtener_campo_jugador(jugador).area_espera == []:
  689.             return None
  690.         return self.obtener_campo_jugador(jugador).area_espera[-1]
  691.  
  692.     def obtener_climax(self, jugador):
  693.         """
  694.        Devuelve la carta del area de climax del jugador pasado por parametro, si hay una.
  695.        :param jugador: Jugador del que se quiere obtener la carta del area de climax. Debe ser una de las constantes
  696.                        WEISS o SCHWARZ.
  697.        :return: Carta del area de climax, o None si el area esta vacia.
  698.        """
  699.         return self.obtener_campo_jugador(jugador).area_climax
  700.  
  701.     def iniciar_turno(self):
  702.         """
  703.        Inicia el turno aplicando las habilidades que quedaron en el campo durante el turno anterior
  704.        en el mismo orden que fueron aplicado en este.
  705.        :return: No tiene valor de retorno.
  706.        """
  707.         if len(self.habilidades_turno_anterior) != 0:
  708.             for jugador, habilidad, continuidad in self.habilidades_turno_anterior:
  709.                 hab = self.habilidades_turno_anterior.pop(0)[1]  #Desencola
  710.                 self.aplicar_habilidad_sobre_tablero(jugador, hab, continuidad) #Aplica en el tablero y apila
  711.  
  712.  
  713.     def terminar_turno(self):
  714.         """
  715.        Termina el turno. Revierte todos los efectos de las cartas aplicadas en el campo
  716.        en el orden inverso en que fueron aplicadas. Las habilidades EFECTO_CONTINUO deben guardarse
  717.        para ser aplicadas en el proximo turno (en el mismo orden en el que se aplicaron en este turno).
  718.        :return: No tiene tipo de retorno.
  719.        """
  720.         if len(self.habilidades_aplicadas) != 0:
  721.             for jugador, habilidad, continuidad in self.habilidades_aplicadas:
  722.                 hab = self.habilidades_aplicadas.pop()[1] #Desapila
  723.                 hab.revertir_en_tablero(self, TableroJuego, jugador)
  724.                 if continuidad == EFECTO_CONTINUO:
  725.                     self.habilidades_turno_anterior.append((jugador, habilidad, continuidad)) #Encola
  726.                 self.weis.remover_climax()
  727.                 self.schwarz.remover_climax()
  728.  
  729.     def aplicar_habilidades_en_carta(self, card):
  730.         """
  731.        Aplica las habilidades activas en el campo a la carta pasada como parametro. Se deben
  732.        aplicar en el orden que se aplicaron originalmente.
  733.        :param carta: Carta sobre la que aplicar las habilidades.
  734.        :return: No tiene valor de retorno.
  735.        """
  736.         pila_invertida = self.habilidades_aplicadas[::-1]
  737.         if len(pila_invertida) != 0:
  738.             for jugador, habilidad, continuidad in pila_invertida:
  739.                 habilidad.aplicar_en_carta(self, carta)
  740.  
  741.  
  742.     def aplicar_habilidad_sobre_tablero(self, jugador, habilidad, continuidad):
  743.         """
  744.        Aplica la habilidad pasada por parametro al campo del jugador pasado.
  745.        :param jugador: Jugador en el que se aplica la habilidad.
  746.        :param habilidad: Referencia a la habilidad a aplicar. Debe ser un objeto de una clase que herede de Habilidad.
  747.        :param continuidad: Indica si es una habilidad continua o que solo tiene efecto por un turno. Debe ser una de
  748.                            las constantes EFECTO_CONTINUO o EFECTO_TEMPORAL.
  749.        :return: No tiene valor de retorno.
  750.        """
  751.         if not habilidad:
  752.             return
  753.         habilidad.aplicar_en_tablero(self, TableroJuego, jugador)
  754.         self.habilidades_aplicadas.append((jugador, habilidad, continuidad))
  755.  
  756.     def revertir_habilidades_sobre_carta(self, carta):
  757.         """
  758.        Revierte los efectos sobre la carta pasada como paramtero en el orden inverso en que fueron aplicados.
  759.        :param carta:Carta a la que se le deben revertir las habilidades
  760.        :return: No tiene valor de retorno.
  761.        """
  762.         if len(self.habilidades_aplicadas) != 0:
  763.             n = -1
  764.             for jugador, habilidad, continuidad in self.habilidades_aplicadas:
  765.                 hab = self.habilidades_aplicadas[n][1] #Para que sea en orden inverso
  766.                 hab.revertir_en_carta(self, carta)
  767.                 n -= 1
  768.  
  769.     def remover_habilidad(self, jugador, habilidad):
  770.         """
  771.        Remueve la habilidad pasada por parametro, aplicada por el jugador pasado, de la pila de habilidades aplicadas.
  772.        :param jugador: Jugador que aplico la habilidad originalmente. Debe ser una de las constantes WEISS o SCHWARZ.
  773.        :param habilidad: Habilidad a deshacer. Debe ser un objeto de una clase que herede de Habilidad.
  774.        :return: No tiene valor de retorno.
  775.        """
  776.         pila_auxiliar = []
  777.         pila_invertida = self.habilidades_aplicadas[::-1]
  778.         for jugador, habilidad_act, continuidad in pila_invertida:
  779.             tmp = self.habilidades_aplicadas.pop()
  780.             habilidad.revertir_en_tablero(self, TableroJuego, jugador)
  781.             if habilidad_act == habilidad:
  782.                 habilidad.resetear_habilidad()
  783.                 break
  784.             else:
  785.                 pila_auxiliar.insert(0, tmp)
  786.         for jugador, habilidad_act, continuidad in pila_auxiliar:
  787.             self.aplicar_habilidad_sobre_tablero(jugador, habilidad_act, continuidad)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement