@@ -31,3 +31,52 @@ Team 0.00 Mine 1 Team 0.00 Mine 0 75 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 75 | Team 0.00 Mine 1 Team 0.00 Mine 0 75 | ||||
Team 0.00 Mine 1 Team 0.00 Mine 0 75 | Team 0.00 Mine 1 Team 0.00 Mine 0 75 | ||||
Team 0.00 Mine 1 Team 0.00 Mine 0 75 | Team 0.00 Mine 1 Team 0.00 Mine 0 75 | ||||
Team 0.00 Mine 1 Team 0.00 Mine 0 78 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 78 | |||||
Team 2 Mine 1 Team 1 Mine 0 78 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 76 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 76 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 98 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 98 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 97 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 54 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 67 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 67 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 85 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 85 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 80 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 80 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 70 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 70 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 70 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 94 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 94 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 85 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 85 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 82 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 82 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 64 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 64 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 129 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 129 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 127 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 127 | |||||
Team 0.00 Mine 0 Team 0.00 Mine 1 79 | |||||
Team 0.00 Mine 0 Team 0.00 Mine 1 79 | |||||
Team 0.00 Mine 0 Team 0.00 Mine 1 27 | |||||
Team 0.00 Mine 0 Team 0.00 Mine 1 27 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 106 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 106 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 74 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 74 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 62 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 62 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 159 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 159 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 65 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 59 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 59 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 77 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 77 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 94 | |||||
Team 0.00 Mine 1 Team 0.00 Mine 0 94 |
@@ -50,6 +50,10 @@ public class Globals { | |||||
*/ | */ | ||||
public static final double EVAL_FLAGDIST_FACTOR = 1 - EVAL_GHOSTDIST_FACTOR; | public static final double EVAL_FLAGDIST_FACTOR = 1 - EVAL_GHOSTDIST_FACTOR; | ||||
/* | |||||
* Tree settings | |||||
*/ | |||||
public static final int MINMAXTREE_MAX_DEPTH = 2; | |||||
/* | /* | ||||
* In order to find out when a ghost is inside a cavity we manualy | * In order to find out when a ghost is inside a cavity we manualy | ||||
@@ -0,0 +1,115 @@ | |||||
/** | |||||
* @file MinMaxTree.java | |||||
* @brief | |||||
* File containing the Pacman Min-Max Tree class. | |||||
* | |||||
* @author Christos Choutouridis 8997 cchoutou@ece.auth.gr | |||||
* @author Konstantina Tsechelidou 8445 konstsec@ece.auth.gr | |||||
*/ | |||||
package gr.auth.ee.dsproject.node; | |||||
/** | |||||
* @brief | |||||
* A tree-like data structure containing move nodes to apply the min-max | |||||
* algorithm. | |||||
* @note | |||||
* This is NOT a real tree. We do not insert node based on a key etc... | |||||
*/ | |||||
public class MinMaxTree | |||||
{ | |||||
private Node89978445 root; | |||||
/* | |||||
* ============ Constructors ============== | |||||
*/ | |||||
/** | |||||
* @brief | |||||
* The simple constructor. Just initialize the root to null | |||||
*/ | |||||
public MinMaxTree () { | |||||
root = null; // No root yet | |||||
} | |||||
/** | |||||
* @brief | |||||
* A constructor with root | |||||
*/ | |||||
public MinMaxTree (Node89978445 root) { | |||||
setRoot (root); | |||||
} | |||||
/* | |||||
* ========= setter ============ | |||||
*/ | |||||
/** Set root */ | |||||
public Node89978445 setRoot (Node89978445 root) { | |||||
return this.root = root; | |||||
} | |||||
/* | |||||
* ========== Tree-like methods ============= | |||||
*/ | |||||
/** | |||||
* @brief | |||||
* Insert a node to a parent directly. | |||||
* This is NOT a real tree. We do not insert node based on a key | |||||
* @param node Node to insert | |||||
* @param parent The parent in witch to insert | |||||
* @return Reference to inserted node | |||||
* If insert fail, returns null | |||||
*/ | |||||
public Node89978445 insert (Node89978445 node, Node89978445 parent) { | |||||
if (parent.children.add (node)) { | |||||
node.parent = parent; | |||||
return node; | |||||
} | |||||
else | |||||
return null; | |||||
} | |||||
/** | |||||
* @brief | |||||
* Find the child with the minimum evaluation value of a | |||||
* specific parent and return a reference to it | |||||
* @param parent The parent of children we scan | |||||
* @return Reference to the child with the minimum evaluation value | |||||
* If parent has no children null. | |||||
*/ | |||||
public Node89978445 minChild (Node89978445 parent) | |||||
{ | |||||
Node89978445 node = null; | |||||
double ev, min = Globals.EVAL_MAX+1; | |||||
for (int i=0 ; i<parent.children.size() ; ++i) { | |||||
if ((ev = parent.children.get(i).getEvaluation()) < min) { | |||||
min = ev; | |||||
node = parent.children.get (i); | |||||
} | |||||
} | |||||
return node; | |||||
} | |||||
/** | |||||
* @brief | |||||
* Find the child with the maximum evaluation value of a | |||||
* specific parent and return a reference to it | |||||
* @param parent The parent of children we scan | |||||
* @return Reference to the child with the maximum evaluation value | |||||
* If parent has no children null. | |||||
*/ | |||||
public Node89978445 maxChild (Node89978445 parent) | |||||
{ | |||||
Node89978445 node = null; | |||||
double ev, max = Globals.EVAL_MIN-1; | |||||
for (int i=0 ; i<parent.children.size() ; ++i) { | |||||
if ((ev = parent.children.get(i).getEvaluation()) > max) { | |||||
max = ev; | |||||
node = parent.children.get (i); | |||||
} | |||||
} | |||||
return node; | |||||
} | |||||
} |
@@ -10,6 +10,8 @@ | |||||
package gr.auth.ee.dsproject.node; | package gr.auth.ee.dsproject.node; | ||||
import java.util.ArrayList; | |||||
//import java.awt.image.PackedColorModel; | //import java.awt.image.PackedColorModel; | ||||
import gr.auth.ee.dsproject.pacman.PacmanUtilities; | import gr.auth.ee.dsproject.pacman.PacmanUtilities; | ||||
import gr.auth.ee.dsproject.pacman.Room; | import gr.auth.ee.dsproject.pacman.Room; | ||||
@@ -27,9 +29,7 @@ public class Node89978445 | |||||
* Pacman's current move evaluation | * Pacman's current move evaluation | ||||
* This is used also as the "return status" of the object | * This is used also as the "return status" of the object | ||||
*/ | */ | ||||
int nodeMove; // Pacman's current move | |||||
int[] nodeXY; // Pacman's current x,y coordinate | int[] nodeXY; // Pacman's current x,y coordinate | ||||
int[] newXY; // Pacman's new x,y coordinate | |||||
int[][] currentGhostPos; // Array holding the Ghost (x,y) pairs | int[][] currentGhostPos; // Array holding the Ghost (x,y) pairs | ||||
@@ -38,6 +38,13 @@ public class Node89978445 | |||||
boolean[] currentFlagStatus; // Array holding the flag capture status | boolean[] currentFlagStatus; // Array holding the flag capture status | ||||
Room[][] Maze; // copy of the current Maze | Room[][] Maze; // copy of the current Maze | ||||
/* | |||||
* Tree navigation references. These variables are handled by | |||||
* PacTree | |||||
*/ | |||||
Node89978445 parent; | |||||
ArrayList<Node89978445> children; | |||||
int depth; | |||||
/* | /* | ||||
* ============ Constructors ============== | * ============ Constructors ============== | ||||
@@ -52,15 +59,16 @@ public class Node89978445 | |||||
public Node89978445 () | public Node89978445 () | ||||
{ | { | ||||
// Fill members | // Fill members | ||||
nodeXY = newXY = Globals.FALSE_POS; | |||||
nodeMove = Globals.INVALID_MOVE; | |||||
this.Maze = null; | |||||
nodeXY = Globals.FALSE_POS; | |||||
nodeEvaluation = Globals.NO_EVAL; | nodeEvaluation = Globals.NO_EVAL; | ||||
parent = null; | |||||
// allocate objects | // allocate objects | ||||
currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; | currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; | ||||
flagPos = new int [PacmanUtilities.numberOfFlags][2]; | flagPos = new int [PacmanUtilities.numberOfFlags][2]; | ||||
currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; | currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; | ||||
ArrayList<Node89978445> children = new ArrayList<Node89978445> (); | |||||
} | } | ||||
/** | /** | ||||
@@ -68,23 +76,19 @@ public class Node89978445 | |||||
* Constructor for the Node89978445 | * Constructor for the Node89978445 | ||||
* @param Maze The current maze object | * @param Maze The current maze object | ||||
* @param curXY The current pacman's (x, y) position | * @param curXY The current pacman's (x, y) position | ||||
* @param move The move under inspection | |||||
*/ | */ | ||||
public Node89978445 (Room[][] Maze, int[] curXY, int move) | |||||
public Node89978445 (Room[][] Maze, int[] curXY) | |||||
{ | { | ||||
this.Maze = Maze; // Fill members | this.Maze = Maze; // Fill members | ||||
nodeXY = newXY = curXY; | |||||
nodeMove = move; | |||||
nodeXY = curXY; | |||||
nodeEvaluation = Globals.NO_EVAL; | nodeEvaluation = Globals.NO_EVAL; | ||||
//calculate members | |||||
newXY = pacmanValidMove (nodeXY, move); | |||||
parent = null; | |||||
// allocate objects | // allocate objects | ||||
currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; | currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; | ||||
flagPos = new int [PacmanUtilities.numberOfFlags][2]; | flagPos = new int [PacmanUtilities.numberOfFlags][2]; | ||||
currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; | currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; | ||||
ArrayList<Node89978445> children = new ArrayList<Node89978445> (); | |||||
} | } | ||||
/* | /* | ||||
@@ -104,18 +108,6 @@ public class Node89978445 | |||||
*/ | */ | ||||
public void setPosition (int[] curXY) { | public void setPosition (int[] curXY) { | ||||
nodeXY = curXY; | nodeXY = curXY; | ||||
//update members | |||||
newXY = pacmanValidMove (curXY, nodeMove); | |||||
} | |||||
/** | |||||
* @brief Set the move to Node object | |||||
* @param move The move under inspection | |||||
*/ | |||||
public void setMove (int move) { | |||||
nodeMove = move; | |||||
//update members | |||||
newXY = pacmanValidMove (nodeXY, move); | |||||
} | } | ||||
/* | /* | ||||
@@ -124,34 +116,72 @@ public class Node89978445 | |||||
/** | /** | ||||
* @brief If not done runs the evaluation algorithm and returns the result | * @brief If not done runs the evaluation algorithm and returns the result | ||||
* @note We assume the current position was a valid position | |||||
* @return The evaluation result | * @return The evaluation result | ||||
*/ | */ | ||||
public double getEvaluation () | public double getEvaluation () | ||||
{ | { | ||||
// calculate helper arrays | |||||
currentGhostPos = findGhosts (); | |||||
flagPos = findFlags (); | |||||
currentFlagStatus = checkFlags (); | |||||
// validation and evaluate move | |||||
if (newXY != Globals.FALSE_POS) { | |||||
// If already evaluated do not re-evaluate the move | |||||
if (nodeEvaluation == Globals.NO_EVAL) | |||||
nodeEvaluation = evaluate (); | |||||
} | |||||
else { | |||||
nodeEvaluation = Globals.NO_EVAL; | |||||
} | |||||
return nodeEvaluation; | |||||
} | |||||
// If already evaluated do not re-evaluate the move | |||||
if (nodeEvaluation == Globals.NO_EVAL) { | |||||
// calculate helper arrays | |||||
currentGhostPos = findGhosts (); | |||||
flagPos = findFlags (); | |||||
currentFlagStatus = checkFlags (); | |||||
return nodeEvaluation = evaluate (); | |||||
} | |||||
else | |||||
return nodeEvaluation; | |||||
} | |||||
/* | |||||
* ============= Helper API ============ | |||||
*/ | |||||
/** | /** | ||||
* @param creature creature's (x,y) | |||||
* @return | * @return | ||||
* The current move of the Node89978445 | |||||
* Return true if the creature is inside the maze boxes | |||||
*/ | */ | ||||
public int getMove () { | |||||
return nodeMove; | |||||
public static boolean isInsideBox (int[] creature) | |||||
{ | |||||
boolean ret = false; //have faith | |||||
for (int i=0 ; i<4 ; ++i) { | |||||
if ((creature[0]>=Globals.BOXES[i][0][0] && creature[0]<=Globals.BOXES[i][1][0]) && | |||||
(creature[1]>=Globals.BOXES[i][0][1] && creature[1]<=Globals.BOXES[i][1][1])) | |||||
ret = true; | |||||
} | |||||
return ret; | |||||
} | } | ||||
/** | |||||
* @brief | |||||
* Static version of move validation | |||||
* Check if the requested move for a node is valid | |||||
*/ | |||||
public static int[] pacmanValidMove (Node89978445 node, int move) | |||||
{ | |||||
int[] newPos = new int[2]; | |||||
// find hypothetical new position | |||||
newPos[0] = node.nodeXY[0]; | |||||
newPos[1] = node.nodeXY[1]; | |||||
newPos[0] += (move == Room.SOUTH) ? 1:0; | |||||
newPos[0] -= (move == Room.NORTH) ? 1:0; | |||||
newPos[1] += (move == Room.EAST) ? 1:0; | |||||
newPos[1] -= (move == Room.WEST) ? 1:0; | |||||
// Pacman curves Maze plane to a Torus | |||||
if (newPos[0] < 0) newPos[0] = PacmanUtilities.numberOfRows; | |||||
if (newPos[0] >= PacmanUtilities.numberOfRows ) newPos[0] = 0; | |||||
if (newPos[1] < 0) newPos[1] = PacmanUtilities.numberOfColumns; | |||||
if (newPos[1] >= PacmanUtilities.numberOfColumns ) newPos[1] = 0; | |||||
// Valid filters | |||||
if (!isInsideBox(node.nodeXY) && | |||||
(node.Maze[node.nodeXY[0]][node.nodeXY[1]].walls[move] == 0)) | |||||
return Globals.FALSE_POS; | |||||
return newPos; | |||||
} | |||||
/* | /* | ||||
* ============= Node's private methods ============= | * ============= Node's private methods ============= | ||||
@@ -239,23 +269,6 @@ public class Node89978445 | |||||
* ============ evaluation helper methods ============== | * ============ evaluation helper methods ============== | ||||
*/ | */ | ||||
/** | |||||
* @param creature creature's (x,y) | |||||
* @return | |||||
* Return true if the creature is inside the maze boxes | |||||
*/ | |||||
private boolean isInsideBox (int[] creature) | |||||
{ | |||||
boolean ret = false; //have faith | |||||
for (int i=0 ; i<4 ; ++i) { | |||||
if ((creature[0]>=Globals.BOXES[i][0][0] && creature[0]<=Globals.BOXES[i][1][0]) && | |||||
(creature[1]>=Globals.BOXES[i][0][1] && creature[1]<=Globals.BOXES[i][1][1])) | |||||
ret = true; | |||||
} | |||||
return ret; | |||||
} | |||||
private int[] ghostValidMove (int[] ghost, int move) | private int[] ghostValidMove (int[] ghost, int move) | ||||
{ | { | ||||
int[] newPos = new int[2]; | int[] newPos = new int[2]; | ||||
@@ -324,7 +337,7 @@ public class Node89978445 | |||||
int[] xyNext = new int [2]; // Coordinates of the next valid position of the algo | int[] xyNext = new int [2]; // Coordinates of the next valid position of the algo | ||||
Queue2D q = new Queue2D (r+c - 1); // Queue to feed with possible position | Queue2D q = new Queue2D (r+c - 1); // Queue to feed with possible position | ||||
int [][] dist = new int [r][c]; | int [][] dist = new int [r][c]; | ||||
/* | |||||
/*< | |||||
* 2D array holding all the distances from the ghost to each square of the maze | * 2D array holding all the distances from the ghost to each square of the maze | ||||
*/ | */ | ||||
@@ -495,7 +508,7 @@ public class Node89978445 | |||||
// Find ghost distances, min and average | // Find ghost distances, min and average | ||||
for (i=0, averGhostDist=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) { | for (i=0, averGhostDist=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) { | ||||
ghostDist [i] = ghostMoveDist (currentGhostPos[i], newXY); | |||||
ghostDist [i] = ghostMoveDist (currentGhostPos[i], nodeXY); | |||||
averGhostDist += ghostDist [i]; | averGhostDist += ghostDist [i]; | ||||
if (minGhostDist > ghostDist[i]) | if (minGhostDist > ghostDist[i]) | ||||
minGhostDist = ghostDist[i]; | minGhostDist = ghostDist[i]; | ||||
@@ -509,7 +522,7 @@ public class Node89978445 | |||||
// Find flag distances and min | // Find flag distances and min | ||||
for (i=0 ; i<PacmanUtilities.numberOfFlags ; ++i) { | for (i=0 ; i<PacmanUtilities.numberOfFlags ; ++i) { | ||||
if (currentFlagStatus[i] == false) { | if (currentFlagStatus[i] == false) { | ||||
flagDist[i] = pacmanMoveDist (newXY, flagPos[i]); | |||||
flagDist[i] = pacmanMoveDist (nodeXY, flagPos[i]); | |||||
if (minFlagDist > flagDist[i]) | if (minFlagDist > flagDist[i]) | ||||
minFlagDist = flagDist[i]; | minFlagDist = flagDist[i]; | ||||
} | } | ||||
@@ -1,3 +1,12 @@ | |||||
/** | |||||
* @file Queue2D.java | |||||
* @brief | |||||
* File containing the Queue2D class. A queue for x,y coordinate | |||||
* pairs | |||||
* | |||||
* @author Christos Choutouridis 8997 cchoutou@ece.auth.gr | |||||
* @author Konstantina Tsechelidou 8445 konstsec@ece.auth.gr | |||||
*/ | |||||
package gr.auth.ee.dsproject.node; | package gr.auth.ee.dsproject.node; | ||||
/** | /** | ||||
@@ -6,11 +15,21 @@ package gr.auth.ee.dsproject.node; | |||||
*/ | */ | ||||
public class Queue2D | public class Queue2D | ||||
{ | { | ||||
int [][] q; | |||||
int [][] q; //!< The queue array | |||||
//int f; | //int f; | ||||
int r; | |||||
int size, nItem; | |||||
int r; // Rear pointer | |||||
int size, nItem; // Queue helper size and queued items | |||||
/* | |||||
* ============ Constructors ============== | |||||
*/ | |||||
/** | |||||
* @brief | |||||
* Simple constructor. Initialize all to zero | |||||
* @note | |||||
* As long as there is no Setter for buffer and read pointer | |||||
* this constructor is useless. | |||||
*/ | |||||
public Queue2D () { | public Queue2D () { | ||||
//f = 0; | //f = 0; | ||||
r = 0; | r = 0; | ||||
@@ -18,18 +37,37 @@ public class Queue2D | |||||
q = null; | q = null; | ||||
} | } | ||||
/** | |||||
* @brief | |||||
* Constructor with buffer size | |||||
* @param size The size of buffer to allocate | |||||
*/ | |||||
public Queue2D (int size) { | public Queue2D (int size) { | ||||
//f = 0; | //f = 0; | ||||
r = -1; | |||||
r = -1; // Init the rear value | |||||
nItem = 0; | nItem = 0; | ||||
this.size = size; | this.size = size; | ||||
q = new int[size][2]; | q = new int[size][2]; | ||||
} | } | ||||
/** | |||||
* @return The "waiting" items in queue | |||||
*/ | |||||
public int size () { return nItem; } | public int size () { return nItem; } | ||||
/** | |||||
* @return True if queue is empty | |||||
*/ | |||||
public boolean isEmpty () { return (nItem == 0) ? true : false; } | public boolean isEmpty () { return (nItem == 0) ? true : false; } | ||||
/** | |||||
* @return True if queue is full | |||||
*/ | |||||
public boolean isFull () { return (nItem >= size) ? true : false; } | public boolean isFull () { return (nItem >= size) ? true : false; } | ||||
/** | |||||
* @return | |||||
* The first item waiting in queue, without removing it | |||||
* If the queue is empty return {-1, -1} | |||||
*/ | |||||
public int [] peek () { | public int [] peek () { | ||||
int [] none = {-1, -1}; | int [] none = {-1, -1}; | ||||
if (!isEmpty ()) { | if (!isEmpty ()) { | ||||
@@ -38,26 +76,18 @@ public class Queue2D | |||||
else | else | ||||
return none; | return none; | ||||
} | } | ||||
public int [] insert (int [] it) { | |||||
int [] none = {-1, -1}; | |||||
if (!isFull ()) { | |||||
++r; | |||||
q[r][0] = it[0]; | |||||
q[r][1] = it[1]; | |||||
++nItem; | |||||
return it; | |||||
} | |||||
else | |||||
return none; | |||||
} | |||||
/** | |||||
* @return | |||||
* The first item waiting in queue and removes it | |||||
* If the queue is empty return {-1, -1} | |||||
*/ | |||||
public int [] remove () { | public int [] remove () { | ||||
int [] ret = {-1, -1}; | int [] ret = {-1, -1}; | ||||
if (!isEmpty ()) { | if (!isEmpty ()) { | ||||
ret[0] = q[0][0]; //ret[0] = q[f][0]; | ret[0] = q[0][0]; //ret[0] = q[f][0]; | ||||
ret[1] = q[0][1]; //ret[1] = q[f][1]; | ret[1] = q[0][1]; //ret[1] = q[f][1]; | ||||
// shift the buffered items | |||||
for (int i=0 ; i<r ; ++i) { | for (int i=0 ; i<r ; ++i) { | ||||
q[i][0] = q[i+1][0]; | q[i][0] = q[i+1][0]; | ||||
q[i][1] = q[i+1][1]; | q[i][1] = q[i+1][1]; | ||||
@@ -70,4 +100,25 @@ public class Queue2D | |||||
else | else | ||||
return ret; | return ret; | ||||
} | } | ||||
/** | |||||
* @brief | |||||
* Insert an item to the queue | |||||
* @param it Reference to item to insert | |||||
* @return The inserted item | |||||
* If the queue is full return {-1, -1} | |||||
*/ | |||||
public int [] insert (int [] it) { | |||||
int [] none = {-1, -1}; | |||||
if (!isFull ()) { | |||||
++r; | |||||
q[r][0] = it[0]; | |||||
q[r][1] = it[1]; | |||||
++nItem; | |||||
return it; | |||||
} | |||||
else | |||||
return none; | |||||
} | |||||
} | } |
@@ -3,6 +3,7 @@ package gr.auth.ee.dsproject.pacman; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import gr.auth.ee.dsproject.node.Globals; | import gr.auth.ee.dsproject.node.Globals; | ||||
import gr.auth.ee.dsproject.node.MinMaxTree; | |||||
import gr.auth.ee.dsproject.node.Node89978445; | import gr.auth.ee.dsproject.node.Node89978445; | ||||
/** | /** | ||||
@@ -49,38 +50,42 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature | |||||
* evaluate these moves. After that feeds the valid ones to an ArrayList | * evaluate these moves. After that feeds the valid ones to an ArrayList | ||||
* and select the best of them to return | * and select the best of them to return | ||||
*/ | */ | ||||
// public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition) | |||||
// { | |||||
// Node89978445 node = new Node89978445 (); // make a dummy node | |||||
// MinMaxTree rt = new MinMaxTree (node); /*< | |||||
// * Plant a tree with dummy root | |||||
// * Null parent and no evaluation | |||||
// */ | |||||
// | |||||
// createSubTreePacman (0,node, Maze, currPosition); | |||||
// return 0; | |||||
// } | |||||
public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition) | public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition) | ||||
{ | { | ||||
Node89978445 mv; | |||||
Node89978445 cur = new Node89978445 (Maze, currPosition); | |||||
Node89978445 moveNode; | |||||
//ArrayList<Node89978445> moveNodes = new ArrayList<Node89978445> (); | |||||
double ev, max = Globals.NO_EVAL; | double ev, max = Globals.NO_EVAL; | ||||
int decision = -1; | int decision = -1; | ||||
ArrayList<Node89978445> moves = new ArrayList<Node89978445> (); | |||||
// loop the possible moves and fill them to list | |||||
int[] nextPosition = {-1, -1}; | |||||
/* | |||||
* loop the possible moves and fill them to list | |||||
* mark the move with the maximum evaluation value | |||||
*/ | |||||
for (int i=0 ; i<4 ; ++i) { | for (int i=0 ; i<4 ; ++i) { | ||||
mv = new Node89978445 (Maze, currPosition, 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<moves.size() ; ++i) { | |||||
if ((ev = moves.get(i).getEvaluation()) >= max) { | |||||
max = ev; | |||||
decision = i; | |||||
if ((nextPosition = Node89978445.pacmanValidMove(cur, i)) != Globals.FALSE_POS) { | |||||
moveNode = new Node89978445 (Maze, nextPosition); | |||||
ev = moveNode.getEvaluation(); | |||||
if (ev > max) { | |||||
max = ev; | |||||
decision = i; | |||||
} | |||||
} | } | ||||
} | } | ||||
return moves.get (decision).getMove(); | |||||
/* | |||||
* The stock version of function: | |||||
* | |||||
* int moveToReturn = (int) (4 * Math.random()); | |||||
* return moveToReturn; | |||||
*/ | |||||
return decision; | |||||
} | } | ||||
void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] currPacmanPosition) | void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] currPacmanPosition) | ||||