Coder Social home page Coder Social logo

hecoding / pac-man Goto Github PK

View Code? Open in Web Editor NEW
54.0 9.0 16.0 30.43 MB

Evolutionary Pac-Man bots using Grammatical Evolution and Multi-objective Optimization. Cool GUI included (Undergraduate Thesis)

Home Page: https://hecoding.github.io/Pac-Man/

License: GNU General Public License v3.0

Java 100.00%
pac-man pacman artificial-intelligence evolutionary-computation genetic-programming grammatical-evolution multi-objective-optimization decision-trees

pac-man's People

Contributors

hecoding avatar j-888 avatar jorjatorz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pac-man's Issues

Adaptar interfaz gráfica

From here

Cosas que van

De las opciones

  • Población
  • Generaciones
  • Prob cruce
  • Prob mutación

General

  • Visualización de Pacman jugando
  • Progress bar

Fix broken game functions, refactor some, delete some

  • getClosestJunction is currently broken -> new version: getClosestJunctionUpgraded
  • update all junction functions to use a fixed version of getClosestJunction, including testing
  • The _current functions have to be deleted since Pacman doesn't care which one was his last movement, he can turn anytime.

NullPointer al finalizar ejecución, probablemente de la GUI

Otput de la consola de Eclipse:

mar 13, 2017 11:39:35 AM jeco.core.algorithm.moge.GrammaticalEvolution execute
INFORMACIÓN: @ # Gen. 100, objective values:
Error: unknown selection clause
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at parser.nodes.NicerTree.pretty(NicerTree.java:33)
	at view.gui.swing.GeneralController.getBestProgramPretty(GeneralController.java:223)
	at view.gui.swing.CenterPanel$4.run(CenterPanel.java:196)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LE_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_15_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_15_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_15_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LT_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LT_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LE_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LT_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_15_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LE_40_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getClosestEdibleGhostDistanceToClosestJunctionUp_LE_40_){_getDirectionTowardsClosestPowerPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_20_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_15_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getClosestEdibleGhostDistanceToClosestJunctionUp_LE_40_){_getDirectionTowardsClosestPowerPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_20_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LE_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: 

mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Fitness =  [5.0]
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Average points = 5.0
mar 13, 2017 11:39:37 AM view.gui.swing.ProgramWorker exec
INFORMACIÓN: Phenotype = (if(_getDistanceToClosestEdibleGhost_LT_50_){_getDirectionTowardsClosestPill_}_else{_if(_getClosestNonEdibleGhostDistanceToClosestJunctionLeft_LE_10_){_getDirectionTowardsClosestPill_}_else{_if(_getDistanceToClosestNonEdibleGhost_LE_10_){_getDirectionTowardsClosestPowerPill_}_}_})
Updated log under: logs/Registro.csv

TreeParser work

Alta prioridad:

  • Wrapper condicional para solucionar el problema singleton de los enum: Las variables enum de nodos apuntan a la misma, así que todas son iguales a la última que se ha hecho.
  • Cambio de nombre de regla a los operadores numericos

Media prioridad:

  • Cambio de nombre de regla a los operadores logicos e implementacion funcional de estos

Baja prioridad:

  • El puntero al padre está a null en todos los nodos.
  • toString de ProgramTree hecho parcialmente, los else no salen.

GrammaticalAdapterControler flow bug

No se está gestionando correctamente el funcionamiento de los condicionales:
Por ejemplo no se incrementa el índice para saltar en caso de no tomar un condicional

Change mutation operator

Ahora sólo aplica la mutación a los individuos que salen de los cruces, cambiarla a que potencialmente todos los individuos de la población puedan ser afectados.

NicerTree game

A NicerTree debería pasársele un Game al construirlo o podemos hacerlo en el método execute? Ojo, construir un Game tarda un par de segundos.

Yo voto por pasárselo en execute.

GUI ideas

  • que haga la media de la línea de population average, o hacer la media de líneas best - average
  • Poner icono de programa (pacman, pero sin copyright)
  • log no va 1
  • Poner checkbox para activar logger
  • Pestaña acerca de con url a github
  • Ejecutar batería de pruebas (varias gramáticas mismos parámetros). Investigar la opción de exportar las gráficas
  • Revisar vista congelada con poblaciones grandes
  • autoplay
  • sacar una barrita con herramientas para el plot como el anterior
  • cambiar la rejilla a más grande (tickmark)
  • poner progress bar más arriba y más gorda, con el botón de cancelar cerca / hacer que se actualize la gráfica en tiempo real
  • meter pause/resume
  • Poner que un tab sean 4 espacios para los programas
  • Cambiar botón Run por Train
  • Al pulsar Run que se cambie a tab de fitness
  • Gráfica dinámica, quizá cada varias generaciones
  • Volver a revisar los parámetros por si alguno no se coge
  • ver numeros mutación y cruce
  • gráfica fitness poner eje x fijo
  • Cambiar título de pestañas a uno más descriptivo
  • selector de gramática

  • selector de controlador de fantasmas
  • selector de fitness multiobjetivo
  • Mostrar ETA (1º y 3º)
  • hacer un item en la leyenda que diga el diff
  • Poner algo para que el juego pueda correr más rapido en gamepanel (slider, los ticks)
  • élite (eliteselectoroperator wtf)
  • botón correr entrenado (sale al quitar el de parar. poner en la pestaña de pruebas y pisar lo que haya en el hueco del texto?)
  • botón para parar entrenamiento
  • Cambiar tamaño de tab en todos los paneles de texto
  • pintar superficie entre mejor y peor, en vez de dos líneas
  • arreglar parámetros el principio (poner un desplegable o algo). parámetros jugozos arriba en abstractproblemge
  • poner el número de repeticiones de un individuo por evaluación (porque los fantasmas son random)
  • quitar lo que están transparentes en la leyenda
  • hacer densidad de puntos (imposible coger todas las poblaciones en cada iteración)
  • tampoco vuelve a correr un draft de tab program
  • botón stop de tab program no va
  • enchufar parámetros de settings
  • gamepanel creandose en guiview retrasa la gui
  • no vuelve a correr al darle a Run (antes tampoco iba, pero ahora tiene también el stop a false en Algorithm)
  • quitar todas las ocurrencias de program worker en center panel y parecidos

Pacman runGame copy

  • Probar que no copie game cada vez que hace un maldito tick.
  • Medir resultados
  • Probar con tabla hash (circular, máximo 100 elementos), de string derivación a árbol parseado

Parser de log a archivo de datos para análisis

Una clase que lea del archivo de log de /log que se genera en cada ejecución y parsee los datos que se imprimen y los guarde en formato csv para así poder importarlos y hacer análisis de datos más fácilmente.

ParserTree / CleanTree bugs

  • Incomplete parse
    Este código saca incomplete parse por consola. En el último else he puesto un espacio antes de la llave. else {
if( ! isJunction ){ 
	if( getClosestNonEdibleGhostDistanceToClosestJunctionDown == 1 ){ 
		getDirectionTowardsClosestPill
	 }
	 else{ 
		getDirectionTowardsClosestEdibleGhost
	 }
 }
 else{ 
	if( getDistanceToClosestEdibleGhost >= 36 ){ 
		getDirectionTowardsClosestPowerPill
	 }
	 else { 
		getDirectionTowardsClosestEdibleGhost
	 }
 }
  • Boom
    Este código revienta. He puesto un espacio después del primer if, antes del paréntesis. if (
if ( ! isJunction ){ 
	if( getClosestNonEdibleGhostDistanceToClosestJunctionDown == 1 ){ 
		getDirectionTowardsClosestPill
	 }
	 else{ 
		getDirectionTowardsClosestEdibleGhost
	 }
 }
 else{ 
	if( getDistanceToClosestEdibleGhost >= 36 ){ 
		getDirectionTowardsClosestPowerPill
	 }
	 else{ 
		getDirectionTowardsClosestEdibleGhost
	 }
 }
  • Boom 2
    Esto peta as well. He puesto un espacio en el primer if, después del paréntesis de cierre y antes de la llave. ! isJunction ) {
if( ! isJunction ) { 
	getDirectionTowardsClosestPill
 }
 else{ 
	getDirectionTowardsClosestEdibleGhost
 }

dudas CustomExecutor

  • No entiendo por qué hay un parámetro fitness que al final se iguala a algo, cuando simplemente se puede quitar el void y hacer que devuelva es mismo fitness.

  • No entiendo que en el bucle se decremente el fitness para que al salir de él SE PISE CON EL MAXSCORE

  • No entiendo por qué se quiere coger la maxima puntuación en el bucle si el juego sólo se está ejecutando una vez

Hasta que no resolvamos todo esto no podemos hacer #1

PacmanGrammaticalEvolution

Pasar de parámetro controladores de ghost y pacman está muy bien, pero:

  • Entonces no hace falta pasar el fenotipo, si ya está asociado al pacman que pasas.
  • MAS IMPORTANTE: Lo estás pasando para nada porque luego lo inicializas a capón ignorando los parámetros que recibe.

ARREGLADO:

  • Si usas el mismo controlador en todas las ejecuciones, hay que resetearlo para no usar un fenotipo a medias.

GrammaticalAdapterController cleanup 2

  • Cambiar el nombre de la variable ghost a algo mas representativo. Si es mas cercano, "closestGhost". Evitar confusiones.
  • Obtener solo fantasmas y pildoras cercanas cuando sea necesario, según casos del switch e ifs.

No entiendo tus no entiendos

Si algo no se entiende, pregúntamelo, no hace falta que crees issues para cosas que no entiendes. @hecoding

Si están objetivamente mal y sabes por qué, ponlos como bug o para cleanup.

❤️

Add debug pacman & ghost traces

Add debug pacman and ghosts that show where are they going by painting a colored trace on the maze. The color of the trace may vary giving they're hunting, escaping, etc...

Using GameView.addPoints()
i.e: GameView.addPoints(game,Color.BLUE, game.getShortestPath(currentPos, nearestFood));

Implementation

For Ghosts we can create new Classes like StarterGhostsDebug and for our own controller we can simply add the lines to GrammaticalAdapterController conditioned by a debug boolean.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.