2011-11-09 16 views
15

Tengo una clase que describe piezas de ajedrez. Hago para todo tipo de pieza en el tablero una clase por ejemplo Peón, Reina, entusiasta, etc ... Tengo un problema en la clase de peón Quiero convertir a Reina u otro objeto que tenga una clase (cuando el peón va a la 8va fila luego conviértelo en algo diferente) ¿cómo puedo hacer esto?¿Puedo convertir dinámicamente una instancia de una clase a otra?

class Pawn: 
    def __init__(self ,x ,y): 
     self.x = x 
     self.y = y 
    def move(self ,unit=1): 
     if self.y ==7 : 
      self.y += 1 
      what = raw_input("queen/rook/knight/bishop/(Q,R,K,B)?") 
      # There is most be changed that may be convert to: 
      # Queen ,knight ,bishop ,rook 
     if self.y != 2 and unit == 2: 
      print ("not accesible!!") 
     elif self.y ==2 and unit == 2: 
      self.y += 2 
     elif unit == 1: 
      self.y += 1 
     else: 
      print("can`t move over there") 

Respuesta

21

En realidad, es posible asignar a self.__class__ en Python, pero que realmente tiene que saber lo que está haciendo. Las dos clases tienen que ser compatibles de alguna manera (ambas son clases definidas por el usuario, ambas son de estilo antiguo o de estilo nuevo, y no estoy seguro del uso de __slots__). También, si lo hace pawn.__class__ = Queen, el objeto de empeño no ha sido construido por el constructor de la reina, por lo esperado ejemplo atributos podrían no estar allí, etc.

Una alternativa sería una especie de constructor de copia así:

class ChessPiece(object): 
    @classmethod 
    def from_other_piece(cls, other_piece): 
    return cls(other_piece.x, other_piece.y) 

Editar: Véase también Assigning to an instance's __class__ attribute in Python

0

un objeto en Python siempre será una instancia de su clase. No hay forma de cambiar eso sin recurrir a "hacks sucios".

En su caso, probablemente debería considerar la refactorización de la lógica. En lugar de dejar que una pieza se mueva, defina algún tipo de controlador que mueva las piezas. Si un peón llega a la última fila, este controlador puede reemplazar fácilmente una pieza por otra.

0

Una forma de resolver esto es tener una clase genérica Piece y otra clase Strategy o Characteristics. La pieza proporciona una interfaz genérica común a todas las piezas (como move_to, o algo así) y Strategy decide si es posible y cómo ejecutar el comando. Cuando quieres cambiar un peón por una reina, cambias la estrategia de la pieza.

Editar: En su caso, podría no ser necesario hacerlo tan complicado. Usted podría tener algo como esto:

class Piece: 
    def __init__(self, movefunc): 
     self.move = movefunc 

def move_pawn(inst, unit=1): 
    pass 

pawn = Piece(move_pawn) 
0

Una solución podría consistir en dejar que Pawn, por ejemplo, a través de en Pawn.promote_to('Q'), devuelva una reina tal que piece = piece.update() sería sensible en cualquier caso.

Cuestiones relacionadas