diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/cl/cromer/azaraka/Constantes.java b/src/main/java/cl/cromer/azaraka/Constantes.java
index 64c4443..df80dcd 100644
--- a/src/main/java/cl/cromer/azaraka/Constantes.java
+++ b/src/main/java/cl/cromer/azaraka/Constantes.java
@@ -34,6 +34,10 @@ public interface Constantes {
* The name of the game
*/
String TITLE = "La Aventura de Azaraka";
+ /**
+ * Whether or not the player should be controlled by AI
+ */
+ boolean PLAYER_AI = true;
/**
* Use a global log if true or individual logs if false
*/
@@ -203,7 +207,7 @@ public interface Constantes {
/**
* The global log level is used if the individual log levels are not
*/
- GLOBAL(Level.SEVERE),
+ GLOBAL(Level.ALL),
/**
* The main log level
*/
@@ -260,6 +264,10 @@ public interface Constantes {
* The gem log level
*/
GEM(Level.INFO),
+ /**
+ * The AI log level
+ */
+ AI(Level.INFO),
/**
* The portal log level
*/
diff --git a/src/main/java/cl/cromer/azaraka/Escenario.java b/src/main/java/cl/cromer/azaraka/Escenario.java
index 0ff8e0d..ab46e68 100644
--- a/src/main/java/cl/cromer/azaraka/Escenario.java
+++ b/src/main/java/cl/cromer/azaraka/Escenario.java
@@ -170,8 +170,6 @@ public class Escenario extends JComponent implements Constantes {
celdas[2][1].setObject(new Player(this, celdas[2][1]));
objectArrayList.add(celdas[2][1].getObject());
- final Lock lock = new ReentrantLock(true);
-
for (int i = 0; i < obstacles; i++) {
random = randomCoordinates();
celdas[random[0]][random[1]].setObject(new Obstacle(this, celdas[random[0]][random[1]]));
@@ -183,6 +181,7 @@ public class Escenario extends JComponent implements Constantes {
}
}
+ final Lock lock = new ReentrantLock(false);
for (int i = 0; i < ENEMIES; i++) {
random = randomCoordinates();
celdas[random[0]][random[1]].setObject(new Enemy(this, celdas[random[0]][random[1]], lock));
diff --git a/src/main/java/cl/cromer/azaraka/Lienzo.java b/src/main/java/cl/cromer/azaraka/Lienzo.java
index 2d6a7d4..79f5cd9 100644
--- a/src/main/java/cl/cromer/azaraka/Lienzo.java
+++ b/src/main/java/cl/cromer/azaraka/Lienzo.java
@@ -15,6 +15,7 @@
package cl.cromer.azaraka;
+import cl.cromer.azaraka.ai.AI;
import cl.cromer.azaraka.object.Object;
import cl.cromer.azaraka.object.*;
import cl.cromer.azaraka.sound.Sound;
@@ -112,6 +113,10 @@ public class Lienzo extends Canvas implements Constantes {
* The current volume
*/
private float volume = (float) DEFAULT_VOLUME / 100;
+ /**
+ * The threads that control AI
+ */
+ private final HashMap aiThreads = new HashMap<>();
/**
* Initialize the canvas
@@ -203,16 +208,84 @@ public class Lienzo extends Canvas implements Constantes {
thread.start();
}
- addKeyListener(new KeyAdapter() {
- @Override
- public void keyPressed(KeyEvent event) {
- super.keyPressed(event);
- if (!gameOver) {
- player.keyPressed(event);
- repaint();
+ if (PLAYER_AI) {
+ playerAiLauncher();
+ }
+ else {
+ addKeyListener(new KeyAdapter() {
+ @Override
+ public void keyPressed(KeyEvent event) {
+ super.keyPressed(event);
+ if (!gameOver) {
+ player.keyPressed(event);
+ repaint();
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Launch a new player AI task
+ */
+ public void playerAiLauncher() {
+ player.resetAi();
+ Thread aiThread = aiThreads.get(player.getAi());
+ if (aiThread != null) {
+ if (aiThread.isAlive()) {
+ aiThread.interrupt();
+ }
+ try {
+ aiThread.join();
+ }
+ catch (InterruptedException e) {
+ logger.info(e.getMessage());
+ }
+ }
+ if (!player.hasKey()) {
+ for (Key key : keys) {
+ if (key.getState() == Key.State.UNUSED) {
+ player.getAi().search(player.getCelda().getX(), player.getCelda().getY(), key.getCelda().getX(), key.getCelda().getY());
+ player.getAi().calculateRoute();
+ Thread thread = new Thread(player.getAi());
+ thread.start();
+ aiThreads.put(player.getAi(), thread);
+ return;
}
}
- });
+ }
+
+ if (portal.getState() == Portal.State.ACTIVE) {
+ player.getAi().search(player.getCelda().getX(), player.getCelda().getY(), portal.getCelda().getX(), portal.getCelda().getY());
+ player.getAi().calculateRoute();
+ Thread thread = new Thread(player.getAi());
+ thread.start();
+ aiThreads.put(player.getAi(), thread);
+ return;
+ }
+
+ for (Chest chest : chests) {
+ if (chest.getState() == Chest.State.CLOSED) {
+ player.getAi().search(player.getCelda().getX(), player.getCelda().getY(), chest.getCelda().getX(), chest.getCelda().getY() + 1);
+ player.getAi().calculateRoute();
+ player.getAi().setInteract(true);
+ Thread thread = new Thread(player.getAi());
+ thread.start();
+ aiThreads.put(player.getAi(), thread);
+ return;
+ }
+ }
+
+ if (!escenario.isDoorClosed()) {
+ if (player.getCelda().getX() == 2 && player.getCelda().getY() == 0) {
+ player.keyPressed(KeyEvent.VK_UP);
+ }
+ player.getAi().search(player.getCelda().getX(), player.getCelda().getY(), 2, 0);
+ player.getAi().calculateRoute();
+ Thread thread = new Thread(player.getAi());
+ thread.start();
+ aiThreads.put(player.getAi(), thread);
+ }
}
/**
@@ -352,6 +425,7 @@ public class Lienzo extends Canvas implements Constantes {
* Stop all active threads
*/
private void stopThreads() {
+ // Stop normal threads
for (Map.Entry