Separate the algorithm from the game
Signed-off-by: Chris Cromer <chris@cromer.cl>
This commit is contained in:
parent
0d2d95f216
commit
804ab0acef
@ -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);
|
||||
|
@ -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() {
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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,16 +92,12 @@ 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) {
|
||||
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);
|
||||
@ -120,17 +109,13 @@ public class BreadthFirstSearch extends AI implements Constants {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move down if possible
|
||||
*
|
||||
* @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) {
|
||||
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);
|
||||
@ -142,17 +127,13 @@ public class BreadthFirstSearch extends AI implements Constants {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move left if possible
|
||||
*
|
||||
* @param state The previous state
|
||||
*/
|
||||
private void moveLeft(State state) {
|
||||
if (state.getX() > 0) {
|
||||
if (getScene().getCells()[state.getX() - 1][state.getY()].getObject() == null) {
|
||||
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);
|
||||
@ -164,17 +145,13 @@ public class BreadthFirstSearch extends AI implements Constants {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move right if possible
|
||||
*
|
||||
* @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) {
|
||||
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);
|
||||
@ -186,8 +163,6 @@ public class BreadthFirstSearch extends AI implements Constants {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the route to the object
|
||||
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user