Professional Documents
Culture Documents
INVESTIGACIN DE OPERACIONES II
INVESTIGACIN DE OPERACIONES
ALUMNOS:
-CUMPA QUESQUEN EDGARD
ILUSTRACIN 1 PACMAN EST ENFRENTE, LA RUTA CALCULADA TERMINA ATRS DE PINKY. ........................ 2
ILUSTRACIN 2 INKY DECIDIENDO HACIA CUL CELDA DEBE CALCULAR LA MEJOR RUTA. .............................. 3
ILUSTRACIN 3 IMAGEN DEL JUEGO ORIGINAL ................................................................................................. 4
PACMAN
Modo de Juego
El protagonista del videojuego Pacman es un crculo amarillo al que le falta un sector por lo
que parece tener boca. Aparece en laberintos donde debe comer puntos pequeos
(llamados Pacdots en ingls), puntos mayores y otros premios con forma de frutas y otros
objetos. El objetivo del personaje es comer todos los puntos de la pantalla, momento en
el que se pasa al siguiente nivel o pantalla. Sin embargo, cuatro fantasmas o monstruos,
Shadow (Blinky), Speedy (Pinky), Bashful (Inky) y Pokey (Clyde), recorren el laberinto para
intentar comerse a Pac-Man. Estos fantasmas son, respectivamente, de colores rojo, rosa,
cyan y naranja. Los fantasmas no son iguales, as mientras Blinky es muy rpido, y tiene la
habilidad de encontrar a Pacman en el escenario, Inky es muy lento y muchas veces evitar
el encuentro con Pacman.
Hay cuatro puntos ms grandes de lo normal situados cerca de las esquinas del laberinto
nombrados en ingls Power Pellets, y que proporcionan a Pac-Man la habilidad temporal
de comerse a los monstruos (todos ellos se vuelven azules mientras Pac-Man tiene esa
habilidad). Despus de haber sido tragados, los fantasmas se regeneran en "casa" (una caja
situada en el centro del laberinto). El tiempo en que los monstruos permanecen vulnerables
vara segn la pantalla, pero tiende a decrecer a medida que progresa el juego, y al cabo
de muchas pantallas los puntos especiales no tienen ningn efecto sobre los fantasmas.
Adems de comer los puntos, Pac-Man puede obtener puntuacin adicional si se come
alguno de los objetos que aparecen dos veces por pantalla justo debajo de la caja en el [1]
centro del laberinto de donde salen los monstruos. El objeto cambia cada pantalla o dos, y
su valor en puntos aumenta, de forma que dos cerezas (el premio de la primera pantalla)
valen 100 puntos, mientras que el ltimo objeto, la llave, vale 5.000.
Fantasmas
Cada uno posee una personalidad, la cual (ya hablando de forma tcnica) es la celda meta
que buscar cada fantasma. Esta caracterstica, junto a los modos de movimiento, logra una
aparente persecucin colaborativa, aunque en realidad no haya comunicacin entre los
fantasmas.
A. Fantasma rojo (Blinky)
Utiliza la forma ms bsica de persecucin, el de ruta ms corta y su meta objetivo es en s
la posicin actual de Pacman, utilizando el algoritmo de pathfinding de manera tradicional.
Ilustracin 2 Inky decidiendo hacia cul celda debe calcular la mejor ruta.
Premios
A lo largo del juego, Pac-Man puede encontrar diversos premios:
Si Pacman pierde una vida cuando aparece un premio, este desaparece a la vida siguiente.
[4]
Modos de movimiento
Modo Chase (persecucin): Normal, toma la posicin de Pacman como parmetro para su
persecucin.
Modo Scatter (dispersin): Se activa para cada fantasma en una esquina distinta del
escenario, se abandona el algoritmo normal de movimiento y recorre un camino ya
predefinido
Segn nos comenta Danilo Cuevas, en su informe final de proyecto de graduacin para optar al ttulo de
ingeniero civil en informtica: Anlisis de Algoritmos Pathfinding. Este algoritmo es una mejora del
algoritmo de Dijkstra y trabaja considerando el escenario como una rejilla con muchas celdas: tenemos
el punto de inicio dentro de una y nuestro punto objetivo en otra. El algoritmo consiste en calcular un
costo general para cada celda que rodee la casilla que se est analizando, se elige la celda de menor
costo general y luego esta misma se convertir en la celda de anlisis, teniendo como casilla padre
aqulla que acabamos de abandonar. Danilo nos aclara que en este algoritmo los valores de los costos
de movimiento pueden variar dependiendo de la situacin que se est simulando; pero es evidente que
un videojuego base Pacman no es necesario que se haga esta distincin, ya que es igualmente costoso
trasladarse de una celda a otra en todo el escenario.
G(N): Es el costo de movimiento al trasladarse de una celda a otra. Este se asigna cuando se est
implementando el algoritmo.
[5]
H(N): Es el costo de desplazamiento desde la celda analizada hasta la celda objetivo. Este valor se calcula
utilizando una heurstica especificada al implementar el algoritmo A*.
F(N): Aqu lo llamamos costo general y es la suma H(N) y G(N).
Nodo: instancia de una clase que expresa caractersticas de una celda: identificador, nodo
predecesor, fue analizada o no, G(N), H(N), F(N). En general para este algoritmo hablaremos de
nodos en lugar de celdas.
Lista abierta: una lista enlazada donde vamos agregando los nodos que debemos de analizar.
Lista cerrada: una lista enlazada donde estn agregados y se seguirn agregando nodos que ya no
debemos analizar. En este sentido el mejor camino se busca de esta manera:
Este resumen de algoritmo, es una adaptacin de la amplia explicacin que Danilo Cuevas Guzmn 4 nos
hace.
Aplicado a Pacman, el primer nodo de la ruta es la posicin del fantasma, el segundo nodo es la celda a
donde moverse.
[6]
PAQUETE TEST (MAIN)
1 package Test;
2 import javax.swing.JFrame;
3 import level.Board;
4 public class Pacman extends JFrame{
5 /**
Constructor. Inicializa los atributos correspondientes a JFrame
y aniade un objeto Board (hijo de JPanel).
6 */
7 public Pacman()
8 { add(new Board());
9 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
10 setSize(570, 676);
11 setLocationRelativeTo(null);
12 setTitle("Pacman");
13 setVisible(true);
14 }
15 public static void main(String [] args)
16 {
17 new Pacman();
18 }
19 }
PAQUETE ACTORS
CLASE GHOST
import graphics.AnimationManager;
import java.awt.Image;
import java.awt.Rectangle;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Date; [7]
import java.util.HashMap;
import java.util.Random;
import javax.swing.ImageIcon;
import actors.Movable;
/**
* Clase Ghost que maneja las instancias de los fantasmas. Hereda
* de la clase Movable que gestiona la accin en general del movimiento.
* En esta clase se gestiona la inteligencia artificial de los fantasmas
* en base a los parametros HvsV (Horizontal vs Vertical) y accuracy_threshold (lmite
* de eficacia).
*
* El ancho y el alto (width y height) son virtuales. No corresponden con el
* ancho y alto de la imagen del fantasma. De esta manera podemos permitir cierto
* solapamiento para dar la sensacin de que efectivamente han tocado al jugador ya que
* han invadido el espacio del mismo.
*
* Gracias al sistema de configuracin va JSON y al algoritmo de bsqueda mediante
* los parmetros anteriormente citados, no es necesario crear una clase
* especfica por cada fantasma.
*
*
* @see Movable
*
*/
/**
* Propiedades de la clase Ghost:
* has_collided - Utilizada para determinar si ha colisionado con otro
* fantasma, agilizar las busquedas de colisiones, y evitar
* problemas con dobles colisiones.
* start_dead_time - Hora en milisegundos a la que empez el estado DEAD
* state - Estado actual del fantasma.
* width - Ancho virtual del fantasma
* height - Altura virtual del fantasma
* HvsV - Preferencia a la hora de elegir buscar en horizontal o
* vertical. (A menor valor, es ms probable que elija horizontal
* y viceversa)
* accuracy_threshold - lmite o umbral de eficacia. Cuanto menor sea el valor menos
* se preferir buscar al jugador. De esta manera se evitan
* atascos del fantasma recalculando la prxima direccin. [8]
* id - Identificador del fantasma (red, blue, orange y pink)
* imageset - Set de imagenes del fantasma
* name - Nombre del fantasma (definido en el fichero JSON)
*/
/**
* Sistema de animacion
*/
private AnimationManager anim_manager;
/**
* Variables estticas para definir los estados del fantasma.
* CHASING - Persiguiendo
* SCARY - Asustado
* DEAD - Muerto
*/
/**
* Constructor.Inicializa los valores iniciales del fantasma. El ancho y alto
* se asignan automaticamente por el parametro size. Se reduce en un 90% el tamanio
* para dar la sensacion de solapamiento sobre el jugador u otros fantasmas.
*
*
* @param x Posicion X inicial del fantasma
* @param y Posicion Y inicial del fantasma
* @param size Tamanio virtual del fantasma. Se asigna a ancho y alto automaticamente
* transformandolo a un 90% del valor dado.
* @param id Identificador del fantasma
* @param imageset Set de imagenes
* @param HvsV Preferencia de horizontal vs vertical
* @param accuracy_threshold limite de precisin del fantasma.
*/
[9]
public Ghost(int x, int y, int size, String id, String imageset, int HvsV, int accuracy_threshold)
{
super(x, y);
state = CHASING;
this.id = id;
this.imageset = imageset;
this.HvsV = HvsV;
this.accuracy_threshold = accuracy_threshold;
this.width = (int)(((long) size) * 0.95);
this.height = (int)(((long) size) * 0.95);
this.has_collided = false;
this.collides_with = new ArrayList<String>();
loadImageSet();
}
/**
* Devuelve el identificador del fantasma.
* @return Un String con el id del fantasma
*/
/**
* Establece si el fantasma ha chocado o no.
* @param collided boolean que define si ha colisionado o ha dejado de colisionar
*/
/**
* Metodo para saber si esta colisionando con un fantasma en concreto
* @param id id del fantasma
* @return true si esta colisionando con el fantasma informado
*/
public boolean isCollidingWithGhost(String id){
return (collides_with.indexOf(id) != -1);
}
[10]
/**
* Metodo para quitar de la lista el fantasma con el que esta colisionando
* @param id identificador del fantasma a quitar la colision.
*/
public void removeGhostCollision(String id) {
int ghost_index = collides_with.indexOf(id);
if (ghost_index >= 0) {
collides_with.remove(ghost_index);
}
}
/**
* Aniadir a la lista de fantasmas colisionados
* @param id anaiade el id del fantasma a la lista de fantasmas colisionados
*/
public void addGhostCollision(String id) {
int ghost_index = collides_with.indexOf(id);
if (ghost_index < 0) {
collides_with.add(id);
}
}
/**
* Devuelve el numero de fantasmas con los que esta colisionando
* @return numero de fantasmas con el que esta colisionando
*/
/**
* Devuelve el estado del fantasma. Comparar con los atributos
* estticos de la clase.
*
* @return devuelve un entero con el estado del fantasma
* @see Movable
*
*/
/**
* Comprueba el tiempo que lleva en estado DEAD.
* En caso de llevar 5 segundos o ms, inicializa el valor
* de la hora a 0, y cambia el estado a CHASING.
*/
/**
* Getter para saber si el fantasma ya ha colisionado con otro fantasma
* previamente.
* @return Devuelve un valor booleano indicando si ha colisionado
* o no.
*/
int rn;
Random r = new Random();
// Cuanto mas bajo sea el numero aleatorio mas se preferira horizontal en base al
atributo HvsV
rn = r.nextInt(100);
boolean search_vertical = (HvsV < rn);
if (search_vertical) {
if (player_y > GetY()) {
setNextDirection(DOWN);
} else {
setNextDirection(UP);
}
} else {
if (player_x > GetX()) {
setNextDirection(RIGHT);
} else {
setNextDirection(LEFT);
}
} [13]
/**
* Carga las imgenes del fantasma
*
*/
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/**
* Funcion polimorfica: devuelve la ruta del set de imagenes del fantasma.
*
* @return Cadena de texto con la ruta de las imagenes.
*/
/**
* Devuelve la cadena de texto con la ruta de la imagen. Esta version
* fuerza a otro set de imagenes.
*
* @param other_imageset
* @return Cadena de texto con la ruta de la imagenes.
*/
case SCARY:
return anim_manager.getImage("scary");
case DEAD:
return anim_manager.getImage("dead");
}
}
/**
* Devuelve un objeto Bounds con la posicion actual y tamanio virtual
* del fantasma.
*
* @return objeto Bounds con la posicion y tamao del objeto.
* @see Rectangle
*/
/**
* Establece el nombre del fantasma
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* Devuelve el el nombre del fantasma.
* @return devuelve el nombre del fantasma.
*/
public String getName() {
return name;
}
}
[17]
[18]