Separate the algorithm from the game

Signed-off-by: Chris Cromer <chris@cromer.cl>
This commit is contained in:
Chris Cromer 2019-10-11 12:32:55 -03:00
parent 0d2d95f216
commit 804ab0acef
4 changed files with 88 additions and 88 deletions

View File

@ -15,7 +15,7 @@
package cl.cromer.azaraka; package cl.cromer.azaraka;
import cl.cromer.azaraka.ai.BreadthFirstSearch; import cl.cromer.azaraka.ai.PlayerAI;
import cl.cromer.azaraka.ai.State; import cl.cromer.azaraka.ai.State;
import cl.cromer.azaraka.json.Json; import cl.cromer.azaraka.json.Json;
import cl.cromer.azaraka.json.JsonCell; import cl.cromer.azaraka.json.JsonCell;
@ -240,7 +240,7 @@ public class Scene extends JComponent implements Constants {
* @return Returns true if valid or false otherwise * @return Returns true if valid or false otherwise
*/ */
private boolean pathInvalid(int x, int y) { private boolean pathInvalid(int x, int y) {
BreadthFirstSearch breadthFirstSearch = new BreadthFirstSearch(this); PlayerAI breadthFirstSearch = new PlayerAI(this, null);
State playerState = new State(2, 1, State.Type.START, null, 0); State playerState = new State(2, 1, State.Type.START, null, 0);
State objectiveState = new State(x, y, State.Type.EXIT, null, 0); State objectiveState = new State(x, y, State.Type.EXIT, null, 0);
return !breadthFirstSearch.search(playerState, objectiveState); return !breadthFirstSearch.search(playerState, objectiveState);

View File

@ -15,18 +15,12 @@
package cl.cromer.azaraka.ai; package cl.cromer.azaraka.ai;
import cl.cromer.azaraka.Scene;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
* AI algorithms extends this class * AI algorithms extends this class
*/ */
public class AI implements Runnable { public class AI implements Runnable {
/**
* The scene of the game
*/
private final Scene scene;
/** /**
* The logger * The logger
*/ */
@ -38,20 +32,8 @@ public class AI implements Runnable {
/** /**
* Initialize the AI * Initialize the AI
*
* @param scene The scene of the game
*/ */
protected AI(Scene scene) { protected AI() {
this.scene = scene;
}
/**
* Get teh scene
*
* @return Returns the scene
*/
protected Scene getScene() {
return scene;
} }
/** /**

View File

@ -15,16 +15,13 @@
package cl.cromer.azaraka.ai; package cl.cromer.azaraka.ai;
import cl.cromer.azaraka.Constants;
import cl.cromer.azaraka.Scene;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
* This is an implementation of the Breadth-First search algorithm with multiple objectives * This is an implementation of the Breadth-First search algorithm with multiple objectives
*/ */
public class BreadthFirstSearch extends AI implements Constants { public class BreadthFirstSearch extends AI {
/** /**
* The queued states to check * The queued states to check
*/ */
@ -56,12 +53,8 @@ public class BreadthFirstSearch extends AI implements Constants {
/** /**
* Initialize the algorithm * Initialize the algorithm
*
* @param scene The scene the AI is in
*/ */
public BreadthFirstSearch(Scene scene) { public BreadthFirstSearch() {
super(scene);
setLogger(getLogger(this.getClass(), LogLevel.AI));
} }
/** /**
@ -99,26 +92,20 @@ public class BreadthFirstSearch extends AI implements Constants {
} }
} }
// TODO: remove escenario from the algorithm
/** /**
* Move up if possible * Move up if possible
* *
* @param state The previous state * @param state The previous state
*/ */
private void moveUp(State state) { protected void moveUp(State state) {
if (state.getY() > 0) { State up = new State(state.getX(), state.getY() - 1, State.Type.UP, state, state.getImportance());
if (getScene().getCells()[state.getX()][state.getY() - 1].getObject() == null) { if (!history.contains(up)) {
State up = new State(state.getX(), state.getY() - 1, State.Type.UP, state, state.getImportance()); queuedStates.add(up);
if (!history.contains(up)) { history.add(up);
queuedStates.add(up);
history.add(up);
if (up.equals(searchObjective)) { if (up.equals(searchObjective)) {
searchObjective = up; searchObjective = up;
success = true; success = true;
}
}
} }
} }
} }
@ -128,19 +115,15 @@ public class BreadthFirstSearch extends AI implements Constants {
* *
* @param state The previous state * @param state The previous state
*/ */
private void moveDown(State state) { protected void moveDown(State state) {
if (state.getY() < VERTICAL_CELLS - 1) { State down = new State(state.getX(), state.getY() + 1, State.Type.DOWN, state, state.getImportance());
if (getScene().getCells()[state.getX()][state.getY() + 1].getObject() == null) { if (!history.contains(down)) {
State down = new State(state.getX(), state.getY() + 1, State.Type.DOWN, state, state.getImportance()); queuedStates.add(down);
if (!history.contains(down)) { history.add(down);
queuedStates.add(down);
history.add(down);
if (down.equals(searchObjective)) { if (down.equals(searchObjective)) {
searchObjective = down; searchObjective = down;
success = true; success = true;
}
}
} }
} }
} }
@ -150,19 +133,15 @@ public class BreadthFirstSearch extends AI implements Constants {
* *
* @param state The previous state * @param state The previous state
*/ */
private void moveLeft(State state) { protected void moveLeft(State state) {
if (state.getX() > 0) { State left = new State(state.getX() - 1, state.getY(), State.Type.LEFT, state, state.getImportance());
if (getScene().getCells()[state.getX() - 1][state.getY()].getObject() == null) { if (!history.contains(left)) {
State left = new State(state.getX() - 1, state.getY(), State.Type.LEFT, state, state.getImportance()); queuedStates.add(left);
if (!history.contains(left)) { history.add(left);
queuedStates.add(left);
history.add(left);
if (left.equals(searchObjective)) { if (left.equals(searchObjective)) {
searchObjective = left; searchObjective = left;
success = true; success = true;
}
}
} }
} }
} }
@ -172,19 +151,15 @@ public class BreadthFirstSearch extends AI implements Constants {
* *
* @param state The previous state * @param state The previous state
*/ */
private void moveRight(State state) { protected void moveRight(State state) {
if (state.getX() < HORIZONTAL_CELLS - 1) { State right = new State(state.getX() + 1, state.getY(), State.Type.RIGHT, state, state.getImportance());
if (getScene().getCells()[state.getX() + 1][state.getY()].getObject() == null) { if (!history.contains(right)) {
State right = new State(state.getX() + 1, state.getY(), State.Type.RIGHT, state, state.getImportance()); queuedStates.add(right);
if (!history.contains(right)) { history.add(right);
queuedStates.add(right);
history.add(right);
if (right.equals(searchObjective)) { if (right.equals(searchObjective)) {
searchObjective = right; searchObjective = right;
success = true; success = true;
}
}
} }
} }
} }
@ -214,7 +189,7 @@ public class BreadthFirstSearch extends AI implements Constants {
/** /**
* Sort the destinations by importance, if the importance is the same then sort them by distance * Sort the destinations by importance, if the importance is the same then sort them by distance
*/ */
protected void sortDestinations() { public void sortDestinations() {
destinations.sort((state1, state2) -> { destinations.sort((state1, state2) -> {
if (state1.getImportance() > state2.getImportance()) { if (state1.getImportance() > state2.getImportance()) {
// The first state is more important // The first state is more important

View File

@ -15,6 +15,7 @@
package cl.cromer.azaraka.ai; package cl.cromer.azaraka.ai;
import cl.cromer.azaraka.Constants;
import cl.cromer.azaraka.Scene; import cl.cromer.azaraka.Scene;
import cl.cromer.azaraka.object.Player; import cl.cromer.azaraka.object.Player;
import cl.cromer.azaraka.object.Portal; import cl.cromer.azaraka.object.Portal;
@ -25,11 +26,15 @@ import java.awt.event.KeyEvent;
/** /**
* This class handles player based interactions mixed with AI * This class handles player based interactions mixed with AI
*/ */
public class PlayerAI extends BreadthFirstSearch { public class PlayerAI extends BreadthFirstSearch implements Constants {
/** /**
* The player * The player
*/ */
private final Player player; private final Player player;
/**
* The scene the AI is in
*/
private final Scene scene;
/** /**
* Initialize the algorithm * Initialize the algorithm
@ -38,7 +43,9 @@ public class PlayerAI extends BreadthFirstSearch {
* @param player The player controlled by the AI * @param player The player controlled by the AI
*/ */
public PlayerAI(Scene scene, Player player) { public PlayerAI(Scene scene, Player player) {
super(scene); super();
setLogger(getLogger(this.getClass(), LogLevel.AI));
this.scene = scene;
this.player = player; this.player = player;
} }
@ -57,7 +64,7 @@ public class PlayerAI extends BreadthFirstSearch {
player.keyPressed(KeyEvent.VK_UP); player.keyPressed(KeyEvent.VK_UP);
} }
player.interact(); player.interact();
Portal portal = getScene().getCanvas().getPortal(); Portal portal = scene.getCanvas().getPortal();
if (portal.getState() == Portal.State.ACTIVE) { if (portal.getState() == Portal.State.ACTIVE) {
addDestination(new State(portal.getCell().getX(), portal.getCell().getY(), State.Type.PORTAL, null, 2)); addDestination(new State(portal.getCell().getX(), portal.getCell().getY(), State.Type.PORTAL, null, 2));
} }
@ -70,7 +77,7 @@ public class PlayerAI extends BreadthFirstSearch {
case KEY: case KEY:
return true; return true;
case PORTAL: case PORTAL:
if (player.hasTaintedGem() && getScene().getCanvas().getPortal().getState() == Portal.State.ACTIVE) { if (player.hasTaintedGem() && scene.getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
return true; return true;
} }
break; break;
@ -101,13 +108,13 @@ public class PlayerAI extends BreadthFirstSearch {
break; break;
case PORTAL: case PORTAL:
// If the portal is active head towards it // If the portal is active head towards it
if (player.hasTaintedGem() && getScene().getCanvas().getPortal().getState() == Portal.State.ACTIVE) { if (player.hasTaintedGem() && scene.getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
return true; return true;
} }
break; break;
case EXIT: case EXIT:
// If the door is open head to it // If the door is open head to it
if (getScene().isDoorOpen()) { if (scene.isDoorOpen()) {
return true; return true;
} }
break; break;
@ -137,7 +144,43 @@ public class PlayerAI extends BreadthFirstSearch {
} }
} }
getScene().getCanvas().repaint(); scene.getCanvas().repaint();
}
@Override
public void moveUp(State state) {
if (state.getY() > 0) {
if (scene.getCells()[state.getX()][state.getY() - 1].getObject() == null) {
super.moveUp(state);
}
}
}
@Override
public void moveDown(State state) {
if (state.getY() < VERTICAL_CELLS - 1) {
if (scene.getCells()[state.getX()][state.getY() + 1].getObject() == null) {
super.moveDown(state);
}
}
}
@Override
public void moveLeft(State state) {
if (state.getX() > 0) {
if (scene.getCells()[state.getX() - 1][state.getY()].getObject() == null) {
super.moveLeft(state);
}
}
}
@Override
public void moveRight(State state) {
if (state.getX() < HORIZONTAL_CELLS - 1) {
if (scene.getCells()[state.getX() + 1][state.getY()].getObject() == null) {
super.moveRight(state);
}
}
} }
/** /**