Tabla de Contenidos

75.07 Algoritmos y Programación III - Trabajo Práctico - CivilizAlgoIII - Fontela

Período: 2do Cuatrimestre 2005

Alumnos:

Enunciado

PDF

Informe

Manual de Usuario

Suposiciones y extensiones al enunciado adoptadas por el grupo

Breve descripción de la arquitectura del sistema (memoria técnica)

A continuación se detalla el diseño de la estrategia utilizado para resolver el problema que el enunciado plantea con cierta abstracción del patrón anteriormente explicado:

Dada esta introducción explicativa se puede describir la secuencia del juego a modo de ejemplo de desarrollo:

  1. Un juego comienza cargando una partida guardada o iniciando una nueva. Luego de haberse cargado la misma se inicia la secuencia cíclica de turnos sobre todos los jugadores.
  2. En general, cada turno comenzará con la inicialización de la civilización. Esto significa que se deben realizar ciertas modificaciones sobre las características de la misma para estar potencialmente listas para jugar su turno. Las mismas consisten en restituir el movimiento de todas las unidades y restar un turno a los restantes para completar la creación de una unidad o la investigación de una tecnología en proceso.
  3. En caso de haber terminado con el entrenamiento de una unidad, se produce su aparición en las inmediaciones de la ciudad donde se la estaba entrenando.
  4. Una vez inicializado el turno, se toma el manejo de las unidades correspondientes a la civilización que juega. Las acciones permitidas son las de mover sobre terreno pisable (simultaneamente se ira explorando el terreno pisado), atacar (a una unidad o ciudad perteneciente a otra civilización que este dentro del rango de ataque), y otras particulares a la unidad que juega (un trabajador puede extraer oro, un colono puede construir ciudad, etc.).
  5. Toda acción realizable por una unidad, le resta movimiento. Esto se puede interpretar si se piensa que las unidades tienen una cantidad de acciones posibles, y puede utilizarlas para moverse, atacar, extraer oro u otra acción.
  6. Seleccionando alguna ciudad creada perteneciente a la civilización de turno, se puede entrenar una unidad (la cual una vez creada aparecerá un los alrededores de la misma) o investigar alguna tecnología.

Estudio de extensibilidad del sistema desarrollado

Extensibilidad a nivel contenidos

Agregar una nueva unidad

Pasos minimos:

  1. Crear una nueva clase en el paquete modelo.unidades que herede de la clase modelo.juego.Unidad y lleve como nombre, preferentemente, la denominación de la nueva unidad.
  2. Dentro del constructor de esta nueva clase, llamar al constructor del padre y a continuación definir los atributos mediante los setters del padre.
  3. Redefinir el método toString() de tal manera que devuelva el nombre de la unidad.
  4. Crear un constructor alternativo para la carga desde XML que reciba como parametro un objeto de la clase org.w3c.dom.Element y lo primero que haga sea llamar al constructor del padre con este mismo parámetro.

Ejemplo:

package modelo.unidades;
import modelo.juego.Unidad;
 
public class Mago extends Unidad {
 
	public Mago(){
		super();
		setCantidadVida(25);
		setAtaque(20);
		setRangoAvance(2);
		setRangoAtaque(5);		
		setCostoCreacion(400);
		setTiempoEntrenamiento(30);
	}
 
	public String toString(){
		return "Mago";
	}
 
	public Mago(org.w3c.dom.Element elementoUnidad){
		super(elementoUnidad);
	}
}

Persistir nuevos atributos:

Redefinir el método getElementoXML() de la siguiente manera:

public Element getElementoXML(){
	Element aux = super.getElementoXML();
       	aux.addAttribute("ATRIBUTO",getNuevoAtributo()+"");
	return aux;
}

Y para obtenerlo en el momento de la carga modificar el contructor alternativo de la siguiente manera:

public NuevaUnidad(org.w3c.dom.Element elementoUnidad){
	super(elementoUnidad);
	setNuevoAtributo(Integer.parseInt(elementoUnidad.getAttribute("ATRIBUTO")));
}
Agregar una nueva Tecnologia
  1. Crear una nueva clase en el paquete modelo.tecnologias que herede de la clase modelo.juego.Tecnologia y lleve como nombre, preferentemente, la denominación de la nueva tecnología.
  2. Respetar el patrón de diseño Singleton.
  3. Dentro del constructor definir los atributos mediante los setters del padre.
  4. Definir dentro del metodo aplicarCambios() toda aquella modificacion que la tecnologia produce en la civilizacion que la termina de investigar.

Ejemplo:

package modelo.tecnologias;
import modelo.juego.Civilizacion;
import modelo.juego.Tecnologia;
import modelo.unidades.Mago;
 
public class Magia extends Tecnologia {
 
	static private Magia instanciaUnica = null;
 	public static void setInstanciaUnica(Magia i){instanciaUnica = i;}
    	static public Magia getInstanciaUnica(){
      		if (instanciaUnica == null){
        			setInstanciaUnica(new Magia());
		}
	        	return instanciaUnica;
	}
 
	private Magia(){ 
    		setNombre("Magia");
    		setDescripcion("Permite entrenar magos y acelera un 20% la creacion de unidades.");
    		setCostoInvestigacion(400);
    		setTiempoInvestigacion(40);
    	}
 
    	public void aplicarCambios(Civilizacion c) {
    		c.getListaUnidades().setVelocidadEntrenamiento(c.getListaUnidades().getVelocidadEntrenamiento()+20);
    		c.agregarUnidadDisponible(new Mago());
    	}
}

Extensibilidad de la Inteligencia Artificial

El diseño general del sistema permite que la Inteligencia Artificial pueda ser mejorada hasta niveles realmente complejos y desafiantes sin necesidad de introducir cambios en el modelo.
Esto se ha logrado mudando toda la lógica relacionada a la Inteligencia Artificial al paquete de control.

Para redefinir el comportamiento, habrá que reescribir el metodo jugar() en la clase control.IA heredado de la clase control.Jugador.

Extensibilidad de los controladores

El diseño presentado incluye dos tipos de controladores, uno preparado para recibir órdenes desde el teclado y el mouse, y otro que toma las decisiones internamente mediante una lógica de Inteligencia Artificial. Para agregar un nuevo controlador, hay que crear una nueva clase en el paquete control que herede de la clase control.Jugador.

Si por ejemplo se quisiera agregar un controlador que reciba las ordenes desde un socket, habría que que agregar un método abstracto en la clase control.Jugador llamado eventoSocket() para luego ser redefinido en la nueva clase controladora.

Si bien esta extensión no es tan simple como las anteriormente explicadas, ya que requeriróa modificar ligeramente la interfaz visual para mostrar nueva información y nuevas opciones, nuevamente, no se necesitaría introducir cambios en el modelo.

Capturas de pantalla

civilizalgo3_screen1.png

Discusión

En el foro