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;
|
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);
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user