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;
import cl.cromer.azaraka.ai.BreadthFirstSearch;
import cl.cromer.azaraka.ai.PlayerAI;
import cl.cromer.azaraka.ai.State;
import cl.cromer.azaraka.json.Json;
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
*/
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 objectiveState = new State(x, y, State.Type.EXIT, null, 0);
return !breadthFirstSearch.search(playerState, objectiveState);

View File

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

View File

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

View File

@ -15,6 +15,7 @@
package cl.cromer.azaraka.ai;
import cl.cromer.azaraka.Constants;
import cl.cromer.azaraka.Scene;
import cl.cromer.azaraka.object.Player;
import cl.cromer.azaraka.object.Portal;
@ -25,11 +26,15 @@ import java.awt.event.KeyEvent;
/**
* This class handles player based interactions mixed with AI
*/
public class PlayerAI extends BreadthFirstSearch {
public class PlayerAI extends BreadthFirstSearch implements Constants {
/**
* The player
*/
private final Player player;
/**
* The scene the AI is in
*/
private final Scene scene;
/**
* Initialize the algorithm
@ -38,7 +43,9 @@ public class PlayerAI extends BreadthFirstSearch {
* @param player The player controlled by the AI
*/
public PlayerAI(Scene scene, Player player) {
super(scene);
super();
setLogger(getLogger(this.getClass(), LogLevel.AI));
this.scene = scene;
this.player = player;
}
@ -57,7 +64,7 @@ public class PlayerAI extends BreadthFirstSearch {
player.keyPressed(KeyEvent.VK_UP);
}
player.interact();
Portal portal = getScene().getCanvas().getPortal();
Portal portal = scene.getCanvas().getPortal();
if (portal.getState() == Portal.State.ACTIVE) {
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:
return true;
case PORTAL:
if (player.hasTaintedGem() && getScene().getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
if (player.hasTaintedGem() && scene.getCanvas().getPortal().getState() == Portal.State.ACTIVE) {
return true;
}
break;
@ -101,13 +108,13 @@ public class PlayerAI extends BreadthFirstSearch {
break;
case PORTAL:
// 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;
}
break;
case EXIT:
// If the door is open head to it
if (getScene().isDoorOpen()) {
if (scene.isDoorOpen()) {
return true;
}
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);
}
}
}
/**