Browse Source

Working version, no walls, no tree

master
Christos Houtouridis 6 years ago
parent
commit
139286323c
7 changed files with 394 additions and 332 deletions
  1. +27
    -0
      GameLog.txt
  2. BIN
      bin/gr/auth/ee/dsproject/pacman/Creature.class
  3. +26
    -14
      src/gr/auth/ee/dsproject/node/Globals.java
  4. +267
    -240
      src/gr/auth/ee/dsproject/node/Node89978445.java
  5. +73
    -0
      src/gr/auth/ee/dsproject/node/Queue2D.java
  6. +0
    -76
      src/gr/auth/ee/dsproject/node/Vector.java
  7. +1
    -2
      src/gr/auth/ee/dsproject/pacman/Creature.java

+ 27
- 0
GameLog.txt View File

@@ -4,3 +4,30 @@ 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
Team 0.00 Mine 0 Team 0.00 Mine 1 25
Team 0.00 Mine 0 Team 0.00 Mine 1 44
Team 0.00 Mine 0 Team 0.00 Mine 1 44
Team 0.00 Mine 0 Team 0.00 Mine 1 36
Team 0.00 Mine 0 Team 0.00 Mine 1 36
Team 0.00 Mine 0 Team 0.00 Mine 1 71
Team 0.00 Mine 0 Team 0.00 Mine 1 71
Team 0.00 Mine 0 Team 0.00 Mine 1 165
Team 0.00 Mine 0 Team 0.00 Mine 1 165
Team 0.00 Mine 1 Team 0.00 Mine 0 105
Team 0.00 Mine 1 Team 0.00 Mine 0 88
Team 0.00 Mine 1 Team 0.00 Mine 0 88
Team 0.00 Mine 1 Team 0.00 Mine 0 73
Team 0.00 Mine 1 Team 0.00 Mine 0 73
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 140
Team 0.00 Mine 1 Team 0.00 Mine 0 140
Team 0.00 Mine 1 Team 0.00 Mine 0 140
Team 0.00 Mine 0 Team 0.00 Mine 1 62
Team 0.00 Mine 1 Team 0.00 Mine 0 83
Team 0.00 Mine 1 Team 0.00 Mine 0 67
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

BIN
bin/gr/auth/ee/dsproject/pacman/Creature.class View File


+ 26
- 14
src/gr/auth/ee/dsproject/node/Globals.java View File

@@ -33,25 +33,37 @@ public class Globals {
* Evaluation settings
*/
/**
* Mixing factor for the minimum distance for life algorithm
* Mixing factor for the minimum distance
*/
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;
public static final double EVAL_GHOSTDIST_MIN_FACTOR = 0.8;
public static final double EVAL_LGHOSTDIST_AVER_FACTOR = 1 - EVAL_GHOSTDIST_MIN_FACTOR;
/**
* Evaluation mixing factor representing how mutch of life will be
* in the final evaluation value
* Evaluation mixing factor representing how much the ghost distances will
* affect the final evaluation value
*/
public static final double EVAL_LIFE_FACTOR = 0.35;
public static final double EVAL_GHOSTDIST_FACTOR = 0.6;
/**
* 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
* Evaluation mixing factor representing how much the flag distances will
* affect the final evaluation value
*/
public static final double EVAL_FLAGDIST_FACTOR = 1 - EVAL_GHOSTDIST_FACTOR;
/*
* In order to find out when a ghost is inside a cavity we manualy
* define the box limits of the cavity boxes of the current maze here
* :)
*/
public static final double EVAL_GOAL_FACTOR = 1 - EVAL_LIFE_FACTOR;
public static final int BOXES[][][] = {
{ { 5, 5}, { 8, 8} },
{ { 5, 16}, { 8, 19} },
{ {11, 5}, {14, 8} },
{ {11, 16}, {14, 19} }
};
public static final int[] FALSE_POS = {-1, -1};
public static final int MAX_DISTANCE = 100;
}

+ 267
- 240
src/gr/auth/ee/dsproject/node/Node89978445.java View File

@@ -13,10 +13,10 @@ 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
* @class Node89978445
* @brief
* This class holds each move of the current round and it's evaluation
*
@@ -28,43 +28,16 @@ public class Node89978445
* 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[] 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[][] flagPos; // Array holding the flag (x,y) pairs
boolean[] currentFlagStatus; // Array holding the flag captuder status
boolean[] currentFlagStatus; // Array holding the flag capture 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 ==============
@@ -74,62 +47,44 @@ public class Node89978445
* 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
* and setMove manually after the creation of the Node89978445 object
*/
public Node89978445 ()
{
// Fill members
nodeX = newX = Globals.NO_PLACE;
nodeY = newY = Globals.NO_PLACE;
nodeXY = newXY = Globals.FALSE_POS;
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
* Constructor for the Node89978445
* @param Maze The current maze object
* @param curX The current pacman's x position
* @param curY The current pacman's y position
* @param curXY The current pacman's (x, y) position
* @param move The move under inspection
*/
public Node89978445 (Room[][] Maze, int curX, int curY, int move)
public Node89978445 (Room[][] Maze, int[] curXY, int move)
{
this.Maze = Maze; // Fill members
nodeX = newX = curX;
nodeY = newY = curY;
nodeXY = newXY = curXY;
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;
newXY = pacmanValidMove (nodeXY, move);
// 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];
}
/*
@@ -145,12 +100,12 @@ public class Node89978445
/**
* @brief Set pacman's position
* @param curX Pacman's current X position
* @param curY Pacman's current Y position
* @param curXY Pacman's current X, Y position
*/
public void setPosition (int curX, int curY) {
nodeX = curX;
nodeY = curY;
public void setPosition (int[] curXY) {
nodeXY = curXY;
//update members
newXY = pacmanValidMove (curXY, nodeMove);
}
/**
@@ -159,12 +114,8 @@ public class Node89978445
*/
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;
newXY = pacmanValidMove (nodeXY, move);
}
/*
@@ -183,7 +134,7 @@ public class Node89978445
currentFlagStatus = checkFlags ();
// validation and evaluate move
if (isValidMove ()) {
if (newXY != Globals.FALSE_POS) {
// If already evaluated do not re-evaluate the move
if (nodeEvaluation == Globals.NO_EVAL)
nodeEvaluation = evaluate ();
@@ -196,7 +147,7 @@ public class Node89978445
/**
* @return
* The current move of the Nodexxxxxxx
* The current move of the Node89978445
*/
public int getMove () {
return nodeMove;
@@ -284,216 +235,292 @@ public class Node89978445
return ret;
}
/**
* @brief
* Check if the requested move is valid
*/
private boolean isValidMove ()
{
boolean status = true; //have faith
// filters for the move
if (Maze[nodeX][nodeY].walls[nodeMove] == 0)
status = false;
// keep filling the filters [if any]
return status;
}
/*
* ============ evaluation helper methods ==============
*/
/**
* @brief
* return the average valued of the array
* @param x The array to calculate
* @param size The size of the array
* @return The average value
* @param creature creature's (x,y)
* @return
* Return true if the creature is inside the maze boxes
*/
private double aver (double [] x, int size)
private boolean isInsideBox (int[] creature)
{
double acc = 0; // accumulator
for (int i=0 ; i<size ; ++i) {
acc += x[i];
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 acc/size;
return ret;
}
/**
* @brief
* return the minimum valued item of the array
* @param x The array to filter
* @param size The size of the array
* @return The minimum value
*/
private double min (double [] x, int size)
private int[] ghostValidMove (int[] ghost, int move)
{
double ret = 0;
for (int i=0 ; i<size ; ++i) {
if (i==0 || ret > x[i])
ret = x[i];
}
return ret;
int[] newPos = new int[2];
// find hypothetical new position
newPos[0] = ghost[0];
newPos[1] = ghost[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;
// Valid filters
if (!((newPos[0] >= 0 && newPos[0] < PacmanUtilities.numberOfRows) &&
(newPos[1] >= 0 && newPos[1] < PacmanUtilities.numberOfColumns)))
return Globals.FALSE_POS;
if (!isInsideBox(ghost) && (Maze[ghost[0]][ghost[1]].walls[move] == 0))
return Globals.FALSE_POS;
return newPos;
}
/**
* @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
* Check if the requested move is valid
*/
private double max (double [] x, int size) {
double ret = 0;
for (int i=0 ; i<size ; ++i) {
if (i==0 || ret<x[i])
ret = x[i];
}
return ret;
private int[] pacmanValidMove (int[] pacman, int move)
{
int[] newPos = new int[2];
// find hypothetical new position
newPos[0] = pacman[0];
newPos[1] = pacman[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(pacman) && (Maze[pacman[0]][pacman[1]].walls[move] == 0))
return Globals.FALSE_POS;
return newPos;
}
/**
* @brief
* return the best flag index which is the minimum
* valued item of the array
* @param x The array to filter
* @param size The size of the array
* @return The minimum value
* A Breadth-first search to find the shortest path distance
* from a ghost to a point in the maze
* @param ghost Ghost (x, y)
* @param xy The x, y coordinate in Maze
* @return
*/
private int bestFlagPosition (double [] x, int size) {
int pos = 0;
double min = 9999999; // Start large enough
for (int i=0 ; i<size ; ++i) {
if ((min > 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;
private int ghostMoveDist (int[] ghost, 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 the ghost 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
}
}
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<PacmanUtilities.numberOfFlags ; ++i) {
if (currentFlagStatus[i] == true)
ret[i] = new Vector (); // eliminate the capture vectors
else
ret[i] = new Vector (nodeX, nodeY, flagPos[i][0], flagPos[i][1]);
// loop data
dist [ghost[0]][ghost[1]] = 0; //starting point is the ghost position
q.insert (ghost); // 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 = ghostValidMove (xyItem, move)) != Globals.FALSE_POS) {
if (dist[xyNext[0]][xyNext[1]] == -1) {
// If we haven't been there
dist[xyNext[0]][xyNext[1]] = steps; // mark the distance
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);
}
}
}
}
}
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 ret;
return dist[xy[0]][xy[1]];
}
/**
* @brief
* Creates the @ref ghostCurVectors
* these vectors are free vectors from current Pacman's position
* to ghosts
* @return the array holding the vectors
* 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 Vector[] makeGhostCurVectors () {
Vector [] ret = new Vector[PacmanUtilities.numberOfGhosts];
for (int i=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
ret[i] = new Vector (nodeX, nodeY, currentGhostPos[i][0], currentGhostPos[i][1]);
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
}
}
return ret;
}
/**
* @brief
* Creates the @ref ghostNextVectors
* these vectors are free vectors from next Pacman's position
* to ghosts. This next position is the one is been evaluated.
* @return the array holding the vectors
*/
private Vector[] makeghostNextVectors () {
Vector [] ret = new Vector[PacmanUtilities.numberOfGhosts];
for (int i=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
ret[i] = new Vector (newX, newY, currentGhostPos[i][0], currentGhostPos[i][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 we haven't been there
dist[xyNext[0]][xyNext[1]] = steps; // mark the distance
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);
}
}
}
}
}
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 ret;
return dist[xy[0]][xy[1]];
}
/**
* @brief
* Evaluate the current move
*
* The evaluation is made is two faces.
* 1) We measure distances between Pacman's next position and
* ghosts and we extract a value we call life
* 2) We consider the dot products of flag and ghost vector compinations in
* order to find which flag has the clearest path to it. This path represent
* our goal direction. So we measure the direction from pacman's next move to this
* flag and from this distance we extract a value we call goal
*/
private double evaluate ()
{
double l=0, g=0; // life and goal helpers
int bestFlag = 0; // best flag index in flagPos array
double [] M = new double[PacmanUtilities.numberOfFlags];
//< Array holding the max normalized dot product for each of the flags
Vector candidate; // the distance from Pacman's net position to goal flag
// Create the vectors
flagCurVectors = makeFlagCurVectors ();
ghostCurVectors = makeGhostCurVectors ();
ghostNextVectors = makeghostNextVectors ();
/*
* life part
*/
for (int i=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
ghostNorms[i] = ghostNextVectors[i].norm ();
// fill the norm array
double ghostEval=0, gd=0;
double flagEval=0;
int i;
int[] flagDist = new int[PacmanUtilities.numberOfFlags];
int[] ghostDist = new int[PacmanUtilities.numberOfGhosts];
int minGhostDist=Globals.MAX_DISTANCE+1;
int averGhostDist; // cast to integer
int minFlagDist=Globals.MAX_DISTANCE+1;
// Find ghost distances, min and average
for (i=0, averGhostDist=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
ghostDist [i] = ghostMoveDist (currentGhostPos[i], newXY);
averGhostDist += ghostDist [i];
if (minGhostDist > ghostDist[i])
minGhostDist = ghostDist[i];
}
// extract the life as a combination of the minimum distance and the average
l = Globals.EVAL_LIFE_MIN_FACTOR * min (ghostNorms, ghostNorms.length)
+ Globals.EVAL_LIFE_AVER_FACTOR * aver (ghostNorms, ghostNorms.length);
// normalize the life to our interval
life = (-1.0 / (1+l)) * (Globals.EVAL_MAX - Globals.EVAL_MIN) + (Globals.EVAL_MAX - Globals.EVAL_MIN)/2;
/*
* goal part
*/
for (int i=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
for (int j=0 ; j<PacmanUtilities.numberOfGhosts ; ++j) {
flagDots[i][j] = Vector.dot (flagCurVectors[i], ghostCurVectors[j]) / ghostCurVectors[j].norm();
// fill the dot product array
averGhostDist /= PacmanUtilities.numberOfGhosts;
// extract the ghostEval as a combination of the minimum distance and the average
gd = Globals.EVAL_GHOSTDIST_MIN_FACTOR * minGhostDist + Globals.EVAL_GHOSTDIST_MIN_FACTOR * averGhostDist;
// normalize the ghostEval to our interval
ghostEval = (-1.0 / (1+gd)) * (Globals.EVAL_MAX - Globals.EVAL_MIN) + (Globals.EVAL_MAX - Globals.EVAL_MIN)/2;
// Find flag distances and min
for (i=0 ; i<PacmanUtilities.numberOfFlags ; ++i) {
if (currentFlagStatus[i] == false) {
flagDist[i] = pacmanMoveDist (newXY, flagPos[i]);
if (minFlagDist > flagDist[i])
minFlagDist = flagDist[i];
}
M[i] = max (flagDots[i], flagDots[i].length); // take the max dot product for each flag
}
bestFlag = bestFlagPosition (M, M.length); // select the best flag
// create a vector from pacman's next position to best flag
candidate = new Vector (newX, newY, flagPos [bestFlag][0], flagPos [bestFlag][1]);
// normalize the flagEval to our interval
flagEval = (1.0 / (1+minFlagDist)) * (Globals.EVAL_MAX - Globals.EVAL_MIN) - (Globals.EVAL_MAX - Globals.EVAL_MIN)/2;
g = candidate.norm(); // take the candidate length
// normalize the length to our interval
goal = (1.0 / (1+g)) * (Globals.EVAL_MAX - Globals.EVAL_MIN) - (Globals.EVAL_MAX - Globals.EVAL_MIN)/2;
// mix the life and goal to output
return life * Globals.EVAL_LIFE_FACTOR
+ goal * Globals.EVAL_GOAL_FACTOR;
return ghostEval * Globals.EVAL_GHOSTDIST_FACTOR
+ flagEval * Globals.EVAL_FLAGDIST_FACTOR;
}
}

+ 73
- 0
src/gr/auth/ee/dsproject/node/Queue2D.java View File

@@ -0,0 +1,73 @@
package gr.auth.ee.dsproject.node;
/**
* @brief
* A queue implementation for (x, y) coordinates
*/
public class Queue2D
{
int [][] q;
//int f;
int r;
int size, nItem;
public Queue2D () {
//f = 0;
r = 0;
size = nItem = 0;
q = null;
}
public Queue2D (int size) {
//f = 0;
r = -1;
nItem = 0;
this.size = size;
q = new int[size][2];
}
public int size () { return nItem; }
public boolean isEmpty () { return (nItem == 0) ? true : false; }
public boolean isFull () { return (nItem >= size) ? true : false; }
public int [] peek () {
int [] none = {-1, -1};
if (!isEmpty ()) {
return q[0]; //return q[f];
}
else
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;
}
public int [] remove () {
int [] ret = {-1, -1};
if (!isEmpty ()) {
ret[0] = q[0][0]; //ret[0] = q[f][0];
ret[1] = q[0][1]; //ret[1] = q[f][1];
for (int i=0 ; i<r ; ++i) {
q[i][0] = q[i+1][0];
q[i][1] = q[i+1][1];
}
//++f;
--r;
--nItem;
return ret;
}
else
return ret;
}
}

+ 0
- 76
src/gr/auth/ee/dsproject/node/Vector.java View File

@@ -1,76 +0,0 @@
/**
* @file Vector.java
* @brief
* File containing the Vector 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 Vector
* @brief
* A helper class to represent vectors in the Maze
*/
public class Vector {
public int x, y; // the coordinate alternative to vector representation
/**
* @brief the plain constructor makes a zero vector
*/
public Vector () {
x = y = 0;
}
/**
* @brief
* Makes a vector from x,y coordinates of two points in Maze
* @param p1x Point 1 x coordinate
* @param p1y Point 1 y coordinate
* @param p2x Point 2 x coordinate
* @param p2y Point 2 y coordinate
*/
public Vector (int p1x, int p1y, int p2x, int p2y) {
x = p2x - p1x;
y = p2y - p1y;
}
/*
* ========== setters =========
*/
public int setX (int x) { return (this.x = x); } // set x
public int setY (int y) { return (this.y = y); } // set y
/**
* @brief
* The Euclidean norm of the vector
* @return the norm
*/
public double norm () {
return Math.sqrt (x*x + y*y);
}
/**
* @brief
* The dot product of the vector with another vector
* @param a The 2nd vector of the product
* @return the dot product value
*/
public double dot (Vector a) {
return (a.x*this.x + a.y*this.y);
}
/**
* @brief
* A static version of dot product of 2 vectors
* @param a Vector a
* @param b Vector b
* @return The dot product of a and b
*/
public static double dot (Vector a, Vector b) {
return (a.x*b.x + a.y*b.y);
}
}

+ 1
- 2
src/gr/auth/ee/dsproject/pacman/Creature.java View File

@@ -4,7 +4,6 @@ import java.util.ArrayList;
import gr.auth.ee.dsproject.node.Globals;
import gr.auth.ee.dsproject.node.Node89978445;
import gr.auth.ee.dsproject.node.Node89978445;
/**
* <p>
@@ -60,7 +59,7 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
// 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);
mv = new Node89978445 (Maze, currPosition, i);
if (mv.getEvaluation() > Globals.NO_EVAL)
moves.add (mv);
/*


Loading…
Cancel
Save