diff --git a/GameLog.txt b/GameLog.txt index 6250f3a..0083b23 100755 --- a/GameLog.txt +++ b/GameLog.txt @@ -3,3 +3,4 @@ Team 0.00 Mine 0 Team 0.00 Mine 1 4 Team 0.00 Mine 0 Team 0.00 Mine 1 25 Team 0.00 Mine 0 Team 0.00 Mine 1 25 Team 0.00 Mine 0 Team 0.00 Mine 1 11 +Team 0.00 Mine 1 Team 0.00 Mine 0 131 diff --git a/bin/gr/auth/ee/dsproject/node/Node.class b/bin/gr/auth/ee/dsproject/node/Node.class deleted file mode 100755 index fbfa939..0000000 Binary files a/bin/gr/auth/ee/dsproject/node/Node.class and /dev/null differ diff --git a/bin/gr/auth/ee/dsproject/pacman/Creature.class b/bin/gr/auth/ee/dsproject/pacman/Creature.class index e5eb292..41afca3 100755 Binary files a/bin/gr/auth/ee/dsproject/pacman/Creature.class and b/bin/gr/auth/ee/dsproject/pacman/Creature.class differ diff --git a/src/gr/auth/ee/dsproject/node/Globals.java b/src/gr/auth/ee/dsproject/node/Globals.java new file mode 100755 index 0000000..9efd544 --- /dev/null +++ b/src/gr/auth/ee/dsproject/node/Globals.java @@ -0,0 +1,57 @@ +/** + * @file Globals.java + * @brief + * File containing the Globals class, a helper class for the + * vector based evaluation system + * + * @author Christos Choutouridis 8997 cchoutou@ece.auth.gr + * @author Konstantina Tsechelidou 8445 konstsec@ece.auth.gr + */ + +package gr.auth.ee.dsproject.node; + +/** + * @class Globals + * @brief + * Contains constants and factors to trick + * the Node evaluation algorithm + */ +public class Globals { + /* + * Global constants + */ + public static final int NO_PLACE = -1; // out of region square + //public static final int NO_MOVE = -1; + public static final int INVALID_MOVE = -1; // invalid move marker + + public static final int EVAL_MAX = 100; // out max evaluation value + public static final int EVAL_MIN = -100; // our minimum evaluation value + public static final int NO_EVAL = EVAL_MIN-1; // mark the invalid move or no evaluation + + + /* + * Evaluation settings + */ + /** + * Mixing factor for the minimum distance for life algorithm + */ + public static final double EVAL_LIFE_MIN_FACTOR = 0.8; + /** + * mixing factor for the average distances for live algorithm + * @note the factor is the complementary of the EVAL_LIFE_MIN_FACTOR + */ + public static final double EVAL_LIFE_AVER_FACTOR = 1 - EVAL_LIFE_MIN_FACTOR; + + + /** + * Evaluation mixing factor representing how mutch of life will be + * in the final evaluation value + */ + public static final double EVAL_LIFE_FACTOR = 0.35; + /** + * Evaluation mixing factor representing how mutch of goal will be + * in the final evaluation value + * @note the factor is the complementary of the EVAL_LIFE_FACTOR + */ + public static final double EVAL_GOAL_FACTOR = 1 - EVAL_LIFE_FACTOR; +} diff --git a/src/gr/auth/ee/dsproject/node/Node.java b/src/gr/auth/ee/dsproject/node/Node.java deleted file mode 100755 index f415e8c..0000000 --- a/src/gr/auth/ee/dsproject/node/Node.java +++ /dev/null @@ -1,52 +0,0 @@ -package gr.auth.ee.dsproject.node; - -import gr.auth.ee.dsproject.pacman.Room; - -import java.util.ArrayList; - -public class Node -{ - - int nodeX; - int nodeY; - int depth; - int nodeMove; - double nodeEvaluation; - int[][] currentGhostPos; - int[][] flagPos; - boolean[] currentFlagStatus; - - Node parent; - ArrayList children = new ArrayList(); - - // Constructor - public Node () - { - // TODO Fill This - } - - private int[][] findGhosts (Room[][] Maze) - { - // TODO Fill This - } - - private int[][] findFlags (Room[][] Maze) - { - // TODO Fill This - } - - private boolean[] checkFlags (Room[][] Maze) - { - - // TODO Fill This - } - - private double evaluate () - { - - double evaluation = (200 * Math.random()) - 100; - return evaluation; - - } - -} diff --git a/src/gr/auth/ee/dsproject/node/Node89978445.java b/src/gr/auth/ee/dsproject/node/Node89978445.java new file mode 100755 index 0000000..7ab4f26 --- /dev/null +++ b/src/gr/auth/ee/dsproject/node/Node89978445.java @@ -0,0 +1,499 @@ +/** + * @file Node89978445.java + * @brief + * File containing the Node class witch represents + * the moves of Pacman + * + * @author Christos Choutouridis 8997 cchoutou@ece.auth.gr + * @author Konstantina Tsechelidou 8445 konstsec@ece.auth.gr + */ + +package gr.auth.ee.dsproject.node; + +//import java.awt.image.PackedColorModel; +import gr.auth.ee.dsproject.pacman.PacmanUtilities; +import gr.auth.ee.dsproject.pacman.Room; +import gr.auth.ee.dsproject.node.Vector; + +/** + * @class Node + * @brief + * This class holds each move of the current round and it's evaluation + * + */ +public class Node89978445 +{ + double nodeEvaluation; /**< + * Pacman's current move evaluation + * This is used also as the "return status" of the object + */ + int nodeMove; // Pacman's current move + int nodeX; // Pacman's current x coordinate + int nodeY; // Pacman's current y coordinate + int newX; // Pacman's new x coordinate + int newY; // Pacman's new y coordinate + int[][] currentGhostPos; // Array holding the Ghost (x,y) pairs + + + + int[][] flagPos; // Array holding the flag (x,y) pairs + boolean[] currentFlagStatus; // Array holding the flag captuder status + Room[][] Maze; // copy of the current Maze + + /* + * ======== evaluation data =========== + */ + Vector[] flagCurVectors; /**< + * Array holding the free vectors from current Pacman's position + * to Flags + * @note + * in case of captured flag the corresponding vector is [0, 0] + */ + Vector[] ghostCurVectors; /**< + * Array holding the free vectors from current Pacman's position + * to ghosts + */ + Vector[] ghostNextVectors; /**< + * Array holding the free vectors from next Pacman's position + * to ghosts. This next position is the one is been evaluated. + */ + double [] ghostNorms; //*< Helping array holding the norms of the ghostNextVectors vectors + double [][] flagDots; /**< + * 2d array holding the normalized dot products of all the compinations + * in flagCurVectors and ghostCurVectors vectors + * rows represent the flags and columns the ghosts + */ + + double goal, life; // evaluation factors + + /* + * ============ Constructors ============== + */ + /** + * @brief + * The simple constructor. Just initialize the data + * @note + * Using this constructor means that the user MUST call setMaze(), setPosition() + * and setMove manually after the creation of the Nodexxxx object + */ + public Node89978445 () + { + // Fill members + nodeX = newX = Globals.NO_PLACE; + nodeY = newY = Globals.NO_PLACE; + nodeMove = Globals.INVALID_MOVE; + nodeEvaluation = Globals.NO_EVAL; + + //calculate members + //newX += (nodeMove == Room.SOUTH) ? 1:0; + //newX -= (nodeMove == Room.NORTH) ? 1:0; + //newY += (nodeMove == Room.EAST) ? 1:0; + //newY -= (nodeMove == Room.WEST) ? 1:0; + + // allocate objects + currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; + flagPos = new int [PacmanUtilities.numberOfFlags][2]; + currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; + + //evaluation data init + ghostNorms = new double [PacmanUtilities.numberOfGhosts]; + flagDots = new double [PacmanUtilities.numberOfFlags][PacmanUtilities.numberOfGhosts]; + } + + /** + * @brief + * Constructor for the node + * @param Maze The current maze object + * @param curX The current pacman's x position + * @param curY The current pacman's y position + * @param move The move under inspection + */ + public Node89978445 (Room[][] Maze, int curX, int curY, int move) + { + this.Maze = Maze; // Fill members + nodeX = newX = curX; + nodeY = newY = curY; + nodeMove = move; + nodeEvaluation = Globals.NO_EVAL; + + //calculate members + newX += (nodeMove == Room.SOUTH) ? 1:0; + newX -= (nodeMove == Room.NORTH) ? 1:0; + newY += (nodeMove == Room.EAST) ? 1:0; + newY -= (nodeMove == Room.WEST) ? 1:0; + + // allocate objects + currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; + flagPos = new int [PacmanUtilities.numberOfFlags][2]; + currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; + + //evaluation data init + ghostNorms = new double [PacmanUtilities.numberOfGhosts]; + flagDots = new double [PacmanUtilities.numberOfFlags][PacmanUtilities.numberOfGhosts]; + } + + /* + * ============== Setters =============== + */ + /** + * @brief SetMaze (Room) to Node object + * @param maze The room to set + */ + public void setMaze (Room[][] maze) { + this.Maze = maze; + } + + /** + * @brief Set pacman's position + * @param curX Pacman's current X position + * @param curY Pacman's current Y position + */ + public void setPosition (int curX, int curY) { + nodeX = curX; + nodeY = curY; + } + + /** + * @brief Set the move to Node object + * @param move The move under inspection + */ + public void setMove (int move) { + nodeMove = move; + + //update members + newX += (nodeMove == Room.SOUTH) ? 1:0; + newX -= (nodeMove == Room.NORTH) ? 1:0; + newY += (nodeMove == Room.EAST) ? 1:0; + newY -= (nodeMove == Room.WEST) ? 1:0; + } + + /* + * ============== getters ================= + */ + + /** + * @brief If not done runs the evaluation algorithm and returns the result + * @return The evaluation result + */ + public double getEvaluation () + { + // calculate helper arrays + currentGhostPos = findGhosts (); + flagPos = findFlags (); + currentFlagStatus = checkFlags (); + + // validation and evaluate move + if (isValidMove ()) { + // If already evaluated do not re-evaluate the move + if (nodeEvaluation == Globals.NO_EVAL) + nodeEvaluation = evaluate (); + } + else { + nodeEvaluation = Globals.NO_EVAL; + } + return nodeEvaluation; + } + + /** + * @return + * The current move of the Nodexxxxxxx + */ + public int getMove () { + return nodeMove; + } + + /* + * ============= Node's private methods ============= + */ + /** + * @brief + * Loop entire maze and return an object that holds Ghost positions + * @param none + * @return Object with Ghost position + * The first dimension holds the number of the ghost + * The 2nd dimension holds the (x, y) coordinates of the ghost + */ + private int[][] findGhosts () + { + int [][] ret = new int [PacmanUtilities.numberOfGhosts][2]; // Make an object to return + int g = 0; // Ghost index + boolean keepGoing = true; // Boundary check helper variable + + // Loop entire Maze (i, j) + for (int x=0 ; keepGoing && x PacmanUtilities.numberOfGhosts) + keepGoing = false; + } + } + } + return ret; + } + + /** + * @brief + * Loop entire maze and return an object that holds flags positions + * @param none + * @return Object with flag positions + * The first dimension holds the number of the flag + * The 2nd dimension holds the (x, y) coordinates of the flag + */ + private int[][] findFlags () + { + int [][] ret = new int [PacmanUtilities.numberOfFlags][2]; // Make an object to return + int g = 0; // Flag index + boolean keepGoing = true; // Boundary check helper variable + + // Loop entire Maze (i, j) + for (int x=0 ; keepGoing && x PacmanUtilities.numberOfFlags) + keepGoing = false; + } + } + } + return ret; + } + + /** + * @brief + * Loop through flags and check their status + * @param none + * @return Object with flag status + */ + private boolean[] checkFlags () + { + boolean[] ret = new boolean [PacmanUtilities.numberOfFlags]; + int x, y; + + for (int i=0 ; i x[i]) + ret = x[i]; + } + return ret; + } + + /** + * @brief + * return the maximum valued item of the array + * @param x The array to filter + * @param size The size of the array + * @return The maximum value + */ + private double max (double [] x, int size) { + double ret = 0; + + for (int i=0 ; i x[i]) && (x[i] != 0)) { + /*< + * here we exclude the zero vectors from been candidates + * as these vectors represent the captured flags + */ + min = x[i]; + pos = i; + } + } + return pos; + } + + /** + * @brief + * Creates the @ref flagCurVectors + * these vectors are free vectors from current Pacman's position + * to Flags + * @note + * in case of captured flag the corresponding vector is [0, 0] + * @return the array holding the vectors + */ + private Vector[] makeFlagCurVectors () { + Vector[] ret = new Vector[PacmanUtilities.numberOfFlags]; + + for (int i=0 ; i @@ -40,24 +44,54 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature } + /** + * @brief + * Create node for each one of the possible moves (0, 1, 2, 3) and + * evaluate these moves. After that feeds the valid ones to an ArrayList + * and select the best of them to return + */ public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition) { - // TODO Fill This - + Node89978445 mv; + double ev, max = Globals.NO_EVAL; + int decision = -1; - - - return 0; + ArrayList moves = new ArrayList (); + + // loop the possible moves and fill them to list + for (int i=0 ; i<4 ; ++i) { + mv = new Node89978445 (Maze, currPosition[0], currPosition[1], i); + if (mv.getEvaluation() > Globals.NO_EVAL) + moves.add (mv); + /* + * how can i rant for not to have a "stay still" move? + */ + } + + // Find the best of the moves in list + for (int i=0 ; i= max) { + max = ev; + decision = i; + } + } + return moves.get (decision).getMove(); + /* + * The stock version of function: + * + * int moveToReturn = (int) (4 * Math.random()); + * return moveToReturn; + */ } - void createSubTreePacman (int depth, Node parent, Room[][] Maze, int[] currPacmanPosition) + void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] currPacmanPosition) { // TODO Fill This } - void createSubTreeGhosts (int depth, Node parent, Room[][] Maze, int[][] currGhostsPosition) + void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition) { // TODO Fill This }