DEV: A first semi-working version with tree

This commit is contained in:
Christos Houtouridis 2018-01-16 15:48:29 +02:00
parent 60118bf1a7
commit 27ad8b6f40
15 changed files with 251 additions and 268 deletions

0
.classpath Executable file → Normal file
View File

0
.project Executable file → Normal file
View File

0
.settings/org.eclipse.jdt.core.prefs Executable file → Normal file
View File

28
GameLog.txt Executable file → Normal file
View File

@ -80,3 +80,31 @@ 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 77
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 94 Team 0.00 Mine 1 Team 0.00 Mine 0 94
Team 0.00 Mine 0 Team 0.00 Mine 1 61
Team 0.00 Mine 0 Team 0.00 Mine 1 14
Team 0.00 Mine 0 Team 0.00 Mine 1 4
Team 0.00 Mine 0 Team 0.00 Mine 1 12
Team 0.00 Mine 1 Team 0.00 Mine 0 97
Team 0.00 Mine 1 Team 0.00 Mine 0 97
Team 0.00 Mine 0 Team 0.00 Mine 1 22
Team 0.00 Mine 0 Team 0.00 Mine 1 22
Team 0.00 Mine 1 Team 0.00 Mine 0 104
Team 0.00 Mine 0 Team 0.00 Mine 1 7
Team 0.00 Mine 0 Team 0.00 Mine 1 7
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 67
Team 0.00 Mine 1 Team 0.00 Mine 0 67
Team 0.00 Mine 1 Team 0.00 Mine 0 63
Team 0.00 Mine 1 Team 0.00 Mine 0 63
Team 0.00 Mine 1 Team 0.00 Mine 0 65
Team 0.00 Mine 1 Team 0.00 Mine 0 65
Team 0.00 Mine 1 Team 0.00 Mine 0 79
Team 0.00 Mine 1 Team 0.00 Mine 0 79
Team 0.00 Mine 1 Team 0.00 Mine 0 61
Team 0.00 Mine 1 Team 0.00 Mine 0 61
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 78
Team 0.00 Mine 1 Team 0.00 Mine 0 71
Team 0.00 Mine 1 Team 0.00 Mine 0 71

0
bin/.gitignore vendored Normal file → Executable file
View File

BIN
bin/gr/auth/ee/dsproject/pacman/Creature.class Normal file → Executable file

Binary file not shown.

0
ghosts.gif Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.5 KiB

0
lib/pacman.jar Executable file → Normal file
View File

0
pacman.gif Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

4
src/gr/auth/ee/dsproject/node/Globals.java Executable file → Normal file
View File

@ -10,6 +10,8 @@
package gr.auth.ee.dsproject.node; package gr.auth.ee.dsproject.node;
import gr.auth.ee.dsproject.pacman.PacmanUtilities;
/** /**
* @class Globals * @class Globals
* @brief * @brief
@ -69,5 +71,5 @@ public class Globals {
public static final int[] FALSE_POS = {-1, -1}; public static final int[] FALSE_POS = {-1, -1};
public static final int MAX_DISTANCE = 100; public static final int MAX_DISTANCE = PacmanUtilities.numberOfRows + PacmanUtilities.numberOfColumns - 1;
} }

View File

@ -1,115 +0,0 @@
/**
* @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 static 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 static 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 static 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;
}
}

201
src/gr/auth/ee/dsproject/node/Node89978445.java Executable file → Normal file
View File

@ -25,18 +25,16 @@ import gr.auth.ee.dsproject.pacman.Room;
*/ */
public class Node89978445 public class Node89978445
{ {
double nodeEvaluation; /**< double nodeEvaluation; /*<
* 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[] nodeXY; // Pacman's current x,y coordinate int[] nodeXY; // Pacman's current x,y coordinate
int[][] currentGhostPos; // Array holding the Ghost (x,y) pairs int[][] curGhostPos; // Array holding the Ghost (x,y) pairs
int[][] flagPos; // Array holding the flag (x,y) pairs
boolean[] curFlagStatus; // Array holding the flag capture status
int[][] flagPos; // Array holding the flag (x,y) pairs Room[][] Maze; // copy of the current Maze
boolean[] currentFlagStatus; // Array holding the flag capture status
Room[][] Maze; // copy of the current Maze
/* /*
* Tree navigation references. These variables are handled by * Tree navigation references. These variables are handled by
@ -65,10 +63,10 @@ public class Node89978445
parent = null; parent = null;
// allocate objects // allocate objects
currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; curGhostPos = new int [PacmanUtilities.numberOfGhosts][2];
flagPos = new int [PacmanUtilities.numberOfFlags][2]; flagPos = new int [PacmanUtilities.numberOfFlags][2];
currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; curFlagStatus = new boolean[PacmanUtilities.numberOfFlags];
children = new ArrayList<Node89978445> (); children = new ArrayList<Node89978445> ();
} }
/** /**
@ -85,10 +83,18 @@ public class Node89978445
parent = null; parent = null;
// allocate objects // allocate objects
currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2]; curGhostPos = new int [PacmanUtilities.numberOfGhosts][2];
flagPos = new int [PacmanUtilities.numberOfFlags][2]; flagPos = new int [PacmanUtilities.numberOfFlags][2];
currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags]; curFlagStatus = new boolean[PacmanUtilities.numberOfFlags];
children = new ArrayList<Node89978445> (); children = new ArrayList<Node89978445> ();
// calculate helper arrays
curGhostPos = findGhosts ();
flagPos = findFlags ();
curFlagStatus = checkFlags ();
//Evaluate the position
nodeEvaluation = evaluate ();
} }
/* /*
@ -123,10 +129,15 @@ public class Node89978445
{ {
// If already evaluated do not re-evaluate the move // If already evaluated do not re-evaluate the move
if (nodeEvaluation == Globals.NO_EVAL) { if (nodeEvaluation == Globals.NO_EVAL) {
// Safety filters
if (Maze == null)
return Globals.NO_EVAL;
if (nodeXY == Globals.FALSE_POS)
return Globals.NO_EVAL;
// calculate helper arrays // calculate helper arrays
currentGhostPos = findGhosts (); curGhostPos = findGhosts ();
flagPos = findFlags (); flagPos = findFlags ();
currentFlagStatus = checkFlags (); curFlagStatus = checkFlags ();
return nodeEvaluation = evaluate (); return nodeEvaluation = evaluate ();
} }
@ -134,16 +145,30 @@ public class Node89978445
return nodeEvaluation; return nodeEvaluation;
} }
public int[] getCurentPacmanPos () { public int[] getCurrentPacmanPos () {
return nodeXY; return nodeXY;
} }
public int[][] getCurrentGhostPos () { public int[][] getCurrentGhostPos () {
return currentGhostPos; return curGhostPos;
}
public int getDepth () {
return depth;
} }
/* /*
* ============= Helper API ============ * ============= Helper API ============
*/ */
public static int moveConv (int[] nextPos, int[] curPos)
{
int dx = nextPos[0] - curPos[0];
int dy = nextPos[1] - curPos[1];
if (dx < 0) return Room.NORTH;
else if (dx > 0) return Room.SOUTH;
else if (dy < 0) return Room.WEST;
else return Room.EAST;
}
/** /**
* @param creature creature's (x,y) * @param creature creature's (x,y)
* @return * @return
@ -273,9 +298,17 @@ public class Node89978445
} }
/* /*
* ============ evaluation helper methods ============== * ============ private evaluation helper methods ==============
*/ */
private enum Creature {
GHOST, PACMAN
}
/**
* @brief
* Check if the requested ghost move is valid
*/
private int[] ghostValidMove (int[] ghost, int move) private int[] ghostValidMove (int[] ghost, int move)
{ {
int[] newPos = new int[2]; int[] newPos = new int[2];
@ -299,7 +332,7 @@ public class Node89978445
/** /**
* @brief * @brief
* Check if the requested move is valid * Check if the requested pacman move is valid
*/ */
private int[] pacmanValidMove (int[] pacman, int move) private int[] pacmanValidMove (int[] pacman, int move)
{ {
@ -328,12 +361,14 @@ public class Node89978445
/** /**
* @brief * @brief
* A Breadth-first search to find the shortest path distance * A Breadth-first search to find the shortest path distance
* from a ghost to a point in the maze * from an origin point to another point in the maze as if a
* @param ghost Ghost (x, y) * a creature could walk through
* @param xy The x, y coordinate in Maze * @param origin origin (x, y)
* @return * @param xy The x, y coordinate in Maze
* @param creature The type of creature for whom the path is for
* @return The number of steps from origin to xy
*/ */
private int ghostMoveDist (int[] ghost, int[] xy) private int moveDist (int[] origin, int[] xy, Creature creature)
{ {
int move; int move;
int steps, qStepItems; // distance and group counters int steps, qStepItems; // distance and group counters
@ -342,10 +377,10 @@ public class Node89978445
int c = PacmanUtilities.numberOfColumns; // helper for shorting names int c = PacmanUtilities.numberOfColumns; // helper for shorting names
int[] xyItem = new int [2]; // Coordinates of the current position of the algo int[] xyItem = new int [2]; // Coordinates of the current position of the algo
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 (Globals.MAX_DISTANCE - 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 origin to each square of the maze
*/ */
// If target square is inside a box abort with max distance // If target square is inside a box abort with max distance
@ -362,8 +397,8 @@ public class Node89978445
} }
} }
// loop data // loop data
dist [ghost[0]][ghost[1]] = 0; //starting point is the ghost position dist [origin[0]][origin[1]] = 0; //starting point is the origin position
q.insert (ghost); // feed first loop data q.insert (origin); // feed first loop data
qStepItems = 1; // init counters qStepItems = 1; // init counters
steps = 1; steps = 1;
/* /*
@ -380,94 +415,12 @@ public class Node89978445
--qStepItems; // mark the removal of the item --qStepItems; // mark the removal of the item
for (move=0 ; move<4 ; ++move) { for (move=0 ; move<4 ; ++move) {
// loop every valid next position for the current position // loop every valid next position for the current position
if ((xyNext = ghostValidMove (xyItem, move)) != Globals.FALSE_POS) { switch (creature) {
if (dist[xyNext[0]][xyNext[1]] == -1) { case GHOST: xyNext = ghostValidMove (xyItem, move); break;
// If we haven't been there case PACMAN: xyNext = pacmanValidMove (xyItem, move); break;
dist[xyNext[0]][xyNext[1]] = steps; // mark the distance default: xyNext = Globals.FALSE_POS;
if ((xyNext[0] == xy[0]) && (xyNext[1] == xy[1])) {
/*
* first match:
* The first time we reach destination we have count the
* distance. No need any other try
*/
done = true;
break;
}
else {
// If we are not there yet, feed queue with another position
q.insert (xyNext);
}
}
} }
} if (xyNext != Globals.FALSE_POS) {
}
else {
// We are done with group, mark how many are for the next one
if ((qStepItems = q.size()) <= 0)
return dist[xy[0]][xy[1]]; // fail safe return
++steps; // Update distance counter
}
}
return dist[xy[0]][xy[1]];
}
/**
* @brief
* A Breadth-first search to find the shortest path distance
* from the pacman to a point in the maze. The point will normaly
* represent a flag
* @param pacman Pacman's (x, y)
* @param xy The x, y coordinate in Maze
* @return
*/
private int pacmanMoveDist (int[] pacman, int[] xy)
{
int move;
int steps, qStepItems; // distance and group counters
boolean done = false; // algo ending flag
int r = PacmanUtilities.numberOfRows; // helper for shorting names
int c = PacmanUtilities.numberOfColumns; // helper for shorting names
int[] xyItem = new int [2]; // Coordinates of the current 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
int [][] dist = new int [r][c];
/*
* 2D array holding all the distances from pacman to each square of the maze
*/
// If target square is inside a box abort with max distance
if (isInsideBox (xy))
return Globals.MAX_DISTANCE;
/*
* init data for algorithm
*/
for (int i=0 ; i<r ; ++i) {
for (int j=0 ; j<c ; ++j) {
dist[i][j] = -1;
// dist array starts with -1
}
}
// loop data
dist [pacman[0]][pacman[1]] = 0; //starting point is the pacman position
q.insert (pacman); // feed first loop data
qStepItems = 1; // init counters
steps = 1;
/*
* Main loop of the algorithm
*
* For every position we check the valid moves, we apply to them
* the step number and we push them to queue. We group the items in
* queue with their step number by measuring how many we push them for
* the current steps variable value.
*/
while (done == false) {
if (qStepItems>0) { // Have we any item on the current group?
xyItem = q.remove (); //load an item of the current group
--qStepItems; // mark the removal of the item
for (move=0 ; move<4 ; ++move) {
// loop every valid next position for the current position
if ((xyNext = pacmanValidMove (xyItem, move)) != Globals.FALSE_POS) {
if (dist[xyNext[0]][xyNext[1]] == -1) { if (dist[xyNext[0]][xyNext[1]] == -1) {
// If we haven't been there // If we haven't been there
dist[xyNext[0]][xyNext[1]] = steps; // mark the distance dist[xyNext[0]][xyNext[1]] = steps; // mark the distance
@ -515,7 +468,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], nodeXY); ghostDist [i] = moveDist (curGhostPos[i], nodeXY, Creature.GHOST);
averGhostDist += ghostDist [i]; averGhostDist += ghostDist [i];
if (minGhostDist > ghostDist[i]) if (minGhostDist > ghostDist[i])
minGhostDist = ghostDist[i]; minGhostDist = ghostDist[i];
@ -528,8 +481,8 @@ 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 (curFlagStatus[i] == false) {
flagDist[i] = pacmanMoveDist (nodeXY, flagPos[i]); flagDist[i] = moveDist (nodeXY, flagPos[i], Creature.PACMAN);
if (minFlagDist > flagDist[i]) if (minFlagDist > flagDist[i])
minFlagDist = flagDist[i]; minFlagDist = flagDist[i];
} }

0
src/gr/auth/ee/dsproject/node/Queue2D.java Executable file → Normal file
View File

View File

@ -0,0 +1,100 @@
/**
* @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 Tree
{
/*
* ============ Constructor ==============
*/
/**
* @brief
* The simple constructor. Do nothing (this is a static class)
*/
public Tree () { }
/*
* ========== private helpers ==============
*/
private static double min (double x, double y) {
return (x < y) ? x : y;
}
private static double max (double x, double y) {
return (x > y) ? x : y;
}
/*
* ========== Tree-like public 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 static Node89978445 grow (Node89978445 node, Node89978445 parent) {
if (parent.children.add (node)) {
node.parent = parent;
node.depth = parent.depth + 1;
return node;
}
else
return null;
}
public static Node89978445 minmaxAB (Node89978445 node, int depth, double a, double b, boolean maxingPlayer)
{
double v, ev;
Node89978445 vNode = null;
if ((depth == 0) || (node.children.isEmpty()))
return node;
if (maxingPlayer) {
v = Globals.EVAL_MIN - 1;
for (int i=0 ; i<node.children.size() ; ++i) {
ev = minmaxAB (node.children.get (i), depth-1, a, b, false).getEvaluation();
if (ev > v) {
v = ev;
vNode = node.children.get (i);
}
a = max (v, a);
if (b <= a)
break;
}
return vNode;
}
else {
v = Globals.EVAL_MAX + 1;
for (int i=0 ; i<node.children.size() ; ++i) {
ev = minmaxAB(node.children.get (i), depth-1, a, b, true).getEvaluation();
if (ev < v) {
v = ev;
vNode = node.children.get (i);
}
b = min (v, b);
if (b <= a)
break;
}
return vNode;
}
}
}

69
src/gr/auth/ee/dsproject/pacman/Creature.java Executable file → Normal file
View File

@ -3,7 +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.Tree;
import gr.auth.ee.dsproject.node.Node89978445; import gr.auth.ee.dsproject.node.Node89978445;
/** /**
@ -38,33 +38,42 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
private int step = 1; private int step = 1;
private boolean amPrey; private boolean amPrey;
public Creature (boolean isPrey) public Creature (boolean isPrey) {
{
amPrey = isPrey; amPrey = isPrey;
} }
/** /**
* @brief *
* Create node for each one of the possible moves (0, 1, 2, 3) and
* evaluate these moves.
*/ */
public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition) public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition)
{ {
Node89978445 cur = new Node89978445 (Maze, currPosition); int [] bestPos = {-1, -1}; // Best position in maze to play
MinMaxTree mmTree = new MinMaxTree (cur); /*< Node89978445 bestNode; // The node with the best evaluation
* Plant a tree with dummy root Node89978445 cur = new Node89978445 (Maze, currPosition); // The node with the current position
* Null parent and no evaluation
*/
createSubTreePacman (0, cur, Maze, currPosition); //make the tree //make the tree
// min-max createSubTreePacman (cur.getDepth (), cur, Maze, currPosition);
return 0;
// min-max to find best node and consequently the best position
bestNode = Tree.minmaxAB (cur, Globals.MINMAXTREE_MAX_DEPTH-1, Globals.EVAL_MIN - 1, Globals.EVAL_MAX + 1, true);
bestPos = bestNode.getCurrentPacmanPos();
// convert back to move encoding
return Node89978445.moveConv (bestPos, currPosition);
} }
/**
*
*/
void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] curPacmanPosition) void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] curPacmanPosition)
{ {
if (++depth > Globals.MINMAXTREE_MAX_DEPTH) if (depth >= Globals.MINMAXTREE_MAX_DEPTH-1)
/*<
* As the depth starts from 0 and MINMAXTREE_MAX_DEPTH
* is strictly even, with this comparison we accept that there
* is no need for a max-depth layer of ghosts-evaluation based nodes.
* As soon as we accept the depth-1 layers max evaluated node.
*/
return; return;
else { else {
Node89978445 newNode; Node89978445 newNode;
@ -76,23 +85,31 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
if ((nextPosition = Node89978445.pacmanValidMove (parent, move)) != Globals.FALSE_POS) { if ((nextPosition = Node89978445.pacmanValidMove (parent, move)) != Globals.FALSE_POS) {
// Make a copy of the maze in order to simulate next move and move Pacman // Make a copy of the maze in order to simulate next move and move Pacman
newMaze = PacmanUtilities.copy (Maze); newMaze = PacmanUtilities.copy (Maze);
PacmanUtilities.movePacman (newMaze, parent.getCurentPacmanPos(), nextPosition); PacmanUtilities.movePacman (newMaze, parent.getCurrentPacmanPos(), nextPosition);
// Create a node for the move in the new stated game maze // Create a node for the move in the new stated game maze
newNode = new Node89978445 (newMaze, nextPosition); newNode = new Node89978445 (newMaze, nextPosition);
newNode.getEvaluation(); Tree.grow (newNode, parent); // add node to the min-max tree
MinMaxTree.insert (newNode, parent); // add node to the min-max tree
// call the recursive ranch creator // call the recursive ranch creator
createSubTreeGhosts (depth, newNode, newMaze, newNode.getCurrentGhostPos()); createSubTreeGhosts (newNode.getDepth (), newNode, newMaze, newNode.getCurrentGhostPos());
} }
} }
} }
} }
/**
*
*/
void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition) void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition)
{ {
if (++depth > Globals.MINMAXTREE_MAX_DEPTH) if (depth >= Globals.MINMAXTREE_MAX_DEPTH-1)
/*<
* As the depth starts from 0 and MINMAXTREE_MAX_DEPTH
* is strictly even, with this comparison we accept that there
* is no need for a max-depth layer of ghosts-evaluation based nodes.
* As soon as we accept the depth-1 layers max evaluated node.
*/
return; return;
else { else {
Node89978445 newNode; Node89978445 newNode;
@ -103,19 +120,17 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
ghostMoves = PacmanUtilities.allGhostMoves(Maze, currGhostsPosition); ghostMoves = PacmanUtilities.allGhostMoves(Maze, currGhostsPosition);
// loop all ghost moves // loop all ghost moves
int s = ghostMoves.size(); for (int i=0 ; i<ghostMoves.size() ; ++i) {
for (int i=0 ; i<s ; ++i) {
// Make a copy of the maze in order to simulate next move and move ghosts // Make a copy of the maze in order to simulate next move and move ghosts
newMaze = PacmanUtilities.copy (Maze); newMaze = PacmanUtilities.copy (Maze);
PacmanUtilities.moveGhosts(newMaze, currGhostsPosition, ghostMoves.get(i)); PacmanUtilities.moveGhosts(newMaze, currGhostsPosition, ghostMoves.get(i));
// Create a node for the move in the new stated game maze // Create a node for the move in the new stated game maze
newNode = new Node89978445 (newMaze, parent.getCurentPacmanPos()); newNode = new Node89978445 (newMaze, parent.getCurrentPacmanPos());
newNode.getEvaluation(); Tree.grow (newNode, parent); // add node to the min-max tree
MinMaxTree.insert (newNode, parent); // add node to the min-max tree
//recursive call for the rest of the tree //recursive call for the rest of the tree
//createSubTreePacman (depth, newNode, newMaze, parent.getCurentPacmanPos()); createSubTreePacman (newNode.getDepth (), newNode, newMaze, parent.getCurrentPacmanPos());
} }
} }
} }