Browse Source

DEV: Not working, work in progres

master
Christos Houtouridis 6 years ago
parent
commit
f38254d1ee
8 changed files with 344 additions and 107 deletions
  1. +49
    -0
      GameLog.txt
  2. +0
    -0
      bin/.gitignore
  3. BIN
      bin/gr/auth/ee/dsproject/pacman/Creature.class
  4. +4
    -0
      src/gr/auth/ee/dsproject/node/Globals.java
  5. +115
    -0
      src/gr/auth/ee/dsproject/node/MinMaxTree.java
  6. +77
    -64
      src/gr/auth/ee/dsproject/node/Node89978445.java
  7. +70
    -19
      src/gr/auth/ee/dsproject/node/Queue2D.java
  8. +29
    -24
      src/gr/auth/ee/dsproject/pacman/Creature.java

+ 49
- 0
GameLog.txt View File

@@ -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 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

+ 0
- 0
bin/.gitignore View File


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


+ 4
- 0
src/gr/auth/ee/dsproject/node/Globals.java View File

@@ -50,6 +50,10 @@ public class Globals {
*/
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


+ 115
- 0
src/gr/auth/ee/dsproject/node/MinMaxTree.java View File

@@ -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;
}
}

+ 77
- 64
src/gr/auth/ee/dsproject/node/Node89978445.java View File

@@ -10,6 +10,8 @@
package gr.auth.ee.dsproject.node;
import java.util.ArrayList;
//import java.awt.image.PackedColorModel;
import gr.auth.ee.dsproject.pacman.PacmanUtilities;
import gr.auth.ee.dsproject.pacman.Room;
@@ -27,9 +29,7 @@ public class Node89978445
* Pacman's current move evaluation
* 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[] newXY; // Pacman's new x,y coordinate
int[][] currentGhostPos; // Array holding the Ghost (x,y) pairs
@@ -38,6 +38,13 @@ public class Node89978445
boolean[] currentFlagStatus; // Array holding the flag capture status
Room[][] Maze; // copy of the current Maze
/*
* Tree navigation references. These variables are handled by
* PacTree
*/
Node89978445 parent;
ArrayList<Node89978445> children;
int depth;
/*
* ============ Constructors ==============
@@ -52,15 +59,16 @@ public class Node89978445
public Node89978445 ()
{
// Fill members
nodeXY = newXY = Globals.FALSE_POS;
nodeMove = Globals.INVALID_MOVE;
this.Maze = null;
nodeXY = Globals.FALSE_POS;
nodeEvaluation = Globals.NO_EVAL;
parent = null;
// allocate objects
currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2];
flagPos = new int [PacmanUtilities.numberOfFlags][2];
currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags];
ArrayList<Node89978445> children = new ArrayList<Node89978445> ();
}
/**
@@ -68,23 +76,19 @@ public class Node89978445
* Constructor for the Node89978445
* @param Maze The current maze object
* @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
nodeXY = newXY = curXY;
nodeMove = move;
nodeXY = curXY;
nodeEvaluation = Globals.NO_EVAL;
//calculate members
newXY = pacmanValidMove (nodeXY, move);
parent = null;
// allocate objects
currentGhostPos = new int [PacmanUtilities.numberOfGhosts][2];
flagPos = new int [PacmanUtilities.numberOfFlags][2];
currentFlagStatus = new boolean[PacmanUtilities.numberOfFlags];
ArrayList<Node89978445> children = new ArrayList<Node89978445> ();
}
/*
@@ -104,18 +108,6 @@ public class Node89978445
*/
public void setPosition (int[] 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
* @note We assume the current position was a valid position
* @return The evaluation result
*/
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
* 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 =============
@@ -239,23 +269,6 @@ public class Node89978445
* ============ 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)
{
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
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
*/
@@ -495,7 +508,7 @@ public class Node89978445
// Find ghost distances, min and average
for (i=0, averGhostDist=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
ghostDist [i] = ghostMoveDist (currentGhostPos[i], newXY);
ghostDist [i] = ghostMoveDist (currentGhostPos[i], nodeXY);
averGhostDist += ghostDist [i];
if (minGhostDist > ghostDist[i])
minGhostDist = ghostDist[i];
@@ -509,7 +522,7 @@ public class Node89978445
// Find flag distances and min
for (i=0 ; i<PacmanUtilities.numberOfFlags ; ++i) {
if (currentFlagStatus[i] == false) {
flagDist[i] = pacmanMoveDist (newXY, flagPos[i]);
flagDist[i] = pacmanMoveDist (nodeXY, flagPos[i]);
if (minFlagDist > flagDist[i])
minFlagDist = flagDist[i];
}


+ 70
- 19
src/gr/auth/ee/dsproject/node/Queue2D.java View File

@@ -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;
/**
@@ -6,11 +15,21 @@ package gr.auth.ee.dsproject.node;
*/
public class Queue2D
{
int [][] q;
int [][] q; //!< The queue array
//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 () {
//f = 0;
r = 0;
@@ -18,18 +37,37 @@ public class Queue2D
q = null;
}
/**
* @brief
* Constructor with buffer size
* @param size The size of buffer to allocate
*/
public Queue2D (int size) {
//f = 0;
r = -1;
r = -1; // Init the rear value
nItem = 0;
this.size = size;
q = new int[size][2];
}
/**
* @return The "waiting" items in queue
*/
public int size () { return nItem; }
/**
* @return True if queue is empty
*/
public boolean isEmpty () { return (nItem == 0) ? true : false; }
/**
* @return True if queue is full
*/
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 () {
int [] none = {-1, -1};
if (!isEmpty ()) {
@@ -38,26 +76,18 @@ public class Queue2D
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;
}
/**
* @return
* The first item waiting in queue and removes it
* If the queue is empty return {-1, -1}
*/
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];
// shift the buffered items
for (int i=0 ; i<r ; ++i) {
q[i][0] = q[i+1][0];
q[i][1] = q[i+1][1];
@@ -70,4 +100,25 @@ public class Queue2D
else
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;
}
}

+ 29
- 24
src/gr/auth/ee/dsproject/pacman/Creature.java View File

@@ -3,6 +3,7 @@ package gr.auth.ee.dsproject.pacman;
import java.util.ArrayList;
import gr.auth.ee.dsproject.node.Globals;
import gr.auth.ee.dsproject.node.MinMaxTree;
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
* 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)
{
Node89978445 mv;
Node89978445 cur = new Node89978445 (Maze, currPosition);
Node89978445 moveNode;
//ArrayList<Node89978445> moveNodes = new ArrayList<Node89978445> ();
double ev, max = Globals.NO_EVAL;
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) {
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)


Loading…
Cancel
Save