75.07 Algoritmos y Programación III - Trabajo Práctico - CivilizAlgoIII - Fontela [Foros-FIUBA::Wiki]
 

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

Período: 2do Cuatrimestre 2005

Alumnos:

  • Albani Francisco
  • Moraña, María Eugenia
  • Mutti, Damián
  • Álvarez, Matías

Enunciado

PDF

Informe

Suposiciones y extensiones al enunciado adoptadas por el grupo

  • Se optó por no incluir en el diseño del modelo la problemática de senderos debido a la imposibilidad de encontrar una forma elegante de resolverlo. A raíz de esta consideración, tampoco se incluye la tecnología Ripio.
  • Por falta de tiempo no se desarrolló un sistema de puntuaciones ni de estadísticas.
  • Existen dos maneras de iniciar una partida: generar una nueva siguiendo el esquema planteado en el enunciado donde hay solo dos jugadores, uno controlado por el humano y otro por la inteligencia artificial, o cargarla a partir de un archivo XML.
  • El costo de entrenamiento de unidades y de investigación de tecnologías, se aplica a la civilización al inicio del proceso.
  • Por cuestiones de simplicidad y elegancia, la creación de unidades y la investigación de tecnologías se realiza dentro de las ciudades. Una ciudad podrá investigar una sola tecnología y/o entrenar una sola unidad a la vez.
  • Las ciudades se construyen instantaneamente (no requieren tiempo de construcción).

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

  • Se optó por adoptar el patrón de diseño MVC.
  • Se consideró una buena práctica comenzar inicializando la vista correspondiente al juego que comienza.
  • Internamente el juego es quién administra el modelo (resulta ser un Singleton) y la lista de jugadores. Esta administración es la que le permite guardar o cargar una partida mediante un archivo XML. Otra de las características importantes que se debe mencionar es que el juego es quién se encarga de asociar un jugador al controlador que corresponda.
  • Si bien no se logró una transparencia total con el manejo de los turnos, que el juego los administre resultó la mejor opción de las planteadas. La manera de resolverlo fue derivar la responsabilidad del avance de turnos a la vista mediante el botón “Siguiente turno”, logrando de esta manera que quien tenga acceso a la misma sea el encargado de darle continuidad a la partida.

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:

  • El juego se desarrolla con una cierta cantidad de jugadores y un mapa donde interactúan las civilizaciones que corresponden a cada uno de ellos.
  • Cada jugador vive dentro de su controlador y es este quien se encarga de administrar su comportamiento.
  • La secuencia de turnos se desarrolla siguiendo un ciclo, y el juego se considera terminado cuando solo queda una civilización con unidades o ciudades.
  • Cada jugador posee una civilización con la que juega. La misma tiene un nombre, una cantidad de oro, una lista de unidades, una lista de moldes, una lista de tecnologías y una lista de ciudades. Gracias a esto es trivial saber cuando una civilización esta derrotada.
  • Las listas que componen al jugador tienen ciertos atributos que permiten un mejor manejo de los detalles que el enunciado requiere. Se pueden citar entre ellos, la velocidad de investigación de las tecnologías, o el tiempo de creación de unidades.
  • Las unidades son objetos consistentes que permiten guardar su ubicación, su cantidad de vida, su fuerza de ataque, su rango o distancia de ataque, su avance, la civilización a la cual pertenece y el oro y cantidad de turnos que requiere su creación. En ciertos casos, una unidad específica puede tener ciertos atributos extras que le permitan cumplir un rol particular en su civilización (como por ejemplo el trabajador que extrae oro).
  • Las tecnologías son conocimientos que se comportan de igual manera para todos los jugadores de la partida. Esto significa que todos interactúan con las mismas instancias de ellas (por lo que son Singletons). Las características de las mismas particulares a cada civilización, son administradas por dicha civilización mediante sus ciudades.
  • Estas ciudades también son las encargadas de la administración de las unidades en creación. Esto es conveniente para tener una ubicación donde situarlas una vez que las mismas hayan terminado su entrenamiento.

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

materias/75/07/tp_2_cuat_2005_civilizalgo3_fontela.txt · Última modificación: 2006/09/29 00:39 por fhran
 
Excepto donde se indique lo contrario, el contenido de esta wiki se autoriza bajo la siguiente licencia: CC Attribution-Noncommercial-Share Alike 3.0 Unported


Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki