From 804ab0acef0f75aee4f921db95b26a65aec30eaf Mon Sep 17 00:00:00 2001 From: Chris Cromer Date: Fri, 11 Oct 2019 12:32:55 -0300 Subject: [PATCH] Separate the algorithm from the game Signed-off-by: Chris Cromer --- src/main/java/cl/cromer/azaraka/Scene.java | 4 +- src/main/java/cl/cromer/azaraka/ai/AI.java | 20 +--- .../cromer/azaraka/ai/BreadthFirstSearch.java | 95 +++++++------------ .../java/cl/cromer/azaraka/ai/PlayerAI.java | 57 +++++++++-- 4 files changed, 88 insertions(+), 88 deletions(-) diff --git a/src/main/java/cl/cromer/azaraka/Scene.java b/src/main/java/cl/cromer/azaraka/Scene.java index 2d494a3..d6cff8a 100644 --- a/src/main/java/cl/cromer/azaraka/Scene.java +++ b/src/main/java/cl/cromer/azaraka/Scene.java @@ -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); diff --git a/src/main/java/cl/cromer/azaraka/ai/AI.java b/src/main/java/cl/cromer/azaraka/ai/AI.java index 49be624..ab188d3 100644 --- a/src/main/java/cl/cromer/azaraka/ai/AI.java +++ b/src/main/java/cl/cromer/azaraka/ai/AI.java @@ -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() { } /** diff --git a/src/main/java/cl/cromer/azaraka/ai/BreadthFirstSearch.java b/src/main/java/cl/cromer/azaraka/ai/BreadthFirstSearch.java index 993565f..9281667 100644 --- a/src/main/java/cl/cromer/azaraka/ai/BreadthFirstSearch.java +++ b/src/main/java/cl/cromer/azaraka/ai/BreadthFirstSearch.java @@ -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 diff --git a/src/main/java/cl/cromer/azaraka/ai/PlayerAI.java b/src/main/java/cl/cromer/azaraka/ai/PlayerAI.java index f7989fa..540bf4c 100644 --- a/src/main/java/cl/cromer/azaraka/ai/PlayerAI.java +++ b/src/main/java/cl/cromer/azaraka/ai/PlayerAI.java @@ -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); + } + } } /**