DEV: A --maybe-- version
This commit is contained in:
parent
27ad8b6f40
commit
e9f6751355
0
.classpath
Normal file → Executable file
0
.classpath
Normal file → Executable file
0
.settings/org.eclipse.jdt.core.prefs
Normal file → Executable file
0
.settings/org.eclipse.jdt.core.prefs
Normal file → Executable file
230
GameLog.txt
Normal file → Executable file
230
GameLog.txt
Normal file → Executable file
@ -108,3 +108,233 @@ 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 78
|
||||||
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
||||||
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 11
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 11
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 65
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 69
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 69
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 72
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 72
|
||||||
|
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 70
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 70
|
||||||
|
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 64
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 64
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 66
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 66
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 5
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 5
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 5
|
||||||
|
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 63
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 63
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
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 0 Team 0.00 Mine 1 28
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 28
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 28
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 11
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 11
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 52
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 52
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 69
|
||||||
|
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 56
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 56
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
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 64
|
||||||
|
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 64
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 98
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 28
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 35
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 15
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 15
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 59
|
||||||
|
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 73
|
||||||
|
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 76
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 76
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 122
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 122
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 78
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 96
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 96
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 17
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 17
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 20
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 68
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 68
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 26
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 26
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 26
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 12
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 31
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 31
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 42
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 42
|
||||||
|
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 131
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 131
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 72
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 72
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 114
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 16
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 16
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 65
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 71
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 32
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 32
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 16
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 15
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 65
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 65
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 118
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 118
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 17
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 17
|
||||||
|
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 63
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 63
|
||||||
|
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 0 Team 0.00 Mine 1 330
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 60
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 60
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 129
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 129
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 158
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 78
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 78
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 75
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 5
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 5
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
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 70
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 70
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 19
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 160
|
||||||
|
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 79
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 56
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 56
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 60
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 60
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 52
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 52
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 110
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 110
|
||||||
|
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 73
|
||||||
|
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 71
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 62
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 68
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 68
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 68
|
||||||
|
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 65
|
||||||
|
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 98
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 98
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 86
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 86
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 93
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 93
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 72
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 72
|
||||||
|
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 88
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 88
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 83
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 83
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 57
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 57
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 17
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 17
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 83
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 83
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 66
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 66
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 77
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 6
|
||||||
|
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 84
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 67
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 18
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 58
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 81
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 81
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 21
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 133
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 133
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 109
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 109
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 83
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 83
|
||||||
|
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 70
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 70
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 71
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 60
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 89
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 89
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 55
|
||||||
|
Team 0.00 Mine 0 Team 0.00 Mine 1 55
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 65
|
||||||
|
Team 0.00 Mine 1 Team 0.00 Mine 0 65
|
||||||
|
Binary file not shown.
0
ghosts.gif
Normal file → Executable file
0
ghosts.gif
Normal file → Executable file
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
0
lib/pacman.jar
Normal file → Executable file
0
lib/pacman.jar
Normal file → Executable file
0
pacman.gif
Normal file → Executable file
0
pacman.gif
Normal file → Executable file
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
86
src/gr/auth/ee/dsproject/node/Globals.java
Normal file → Executable file
86
src/gr/auth/ee/dsproject/node/Globals.java
Normal file → Executable file
@ -19,16 +19,6 @@ import gr.auth.ee.dsproject.pacman.PacmanUtilities;
|
|||||||
* the Node evaluation algorithm
|
* the Node evaluation algorithm
|
||||||
*/
|
*/
|
||||||
public class Globals {
|
public class Globals {
|
||||||
/*
|
|
||||||
* Global constants
|
|
||||||
*/
|
|
||||||
public static final int NO_PLACE = -1; // out of region square
|
|
||||||
//public static final int NO_MOVE = -1;
|
|
||||||
public static final int INVALID_MOVE = -1; // invalid move marker
|
|
||||||
|
|
||||||
public static final int EVAL_MAX = 100; // out max evaluation value
|
|
||||||
public static final int EVAL_MIN = -100; // our minimum evaluation value
|
|
||||||
public static final int NO_EVAL = EVAL_MIN-1; // mark the invalid move or no evaluation
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -37,28 +27,47 @@ public class Globals {
|
|||||||
/**
|
/**
|
||||||
* Mixing factor for the minimum distance
|
* Mixing factor for the minimum distance
|
||||||
*/
|
*/
|
||||||
public static final double EVAL_GHOSTDIST_MIN_FACTOR = 0.8;
|
// ghosts
|
||||||
public static final double EVAL_LGHOSTDIST_AVER_FACTOR = 1 - EVAL_GHOSTDIST_MIN_FACTOR;
|
public static final double EVAL_GHOSTDIST_MIN_FACTOR = 0.85;
|
||||||
|
public static final double EVAL_GHOSTDIST_AVER_FACTOR = 1 - EVAL_GHOSTDIST_MIN_FACTOR;
|
||||||
|
public static final double EVAL_GHOSTMINDIST_ISOLATION = 1;
|
||||||
|
|
||||||
|
public static final int EVAL_GHOST_BOOST = 2;
|
||||||
|
public static final int EVAL_GHOSTBOOST_OFFSET = -25;
|
||||||
|
public static final int EVAL_GHOST_TERRITORY = 6;
|
||||||
|
public static final int EVAL_GHOSTTERRITORY_OFFSET = -50;
|
||||||
|
// flags
|
||||||
|
public static final int EVAL_FLAG_BOOST = 2;
|
||||||
|
public static final int EVAL_FLAGBOOST_OFFSET = 25;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluation mixing factor representing how much the ghost distances will
|
* Evaluation mixing factor representing how much the individual
|
||||||
* affect the final evaluation value
|
* evaluation values(host, flag, torus) affect the final evaluation of the position
|
||||||
*/
|
*/
|
||||||
public static final double EVAL_GHOSTDIST_FACTOR = 0.6;
|
public static final double EVAL_GHOSTDIST_FACTOR = 0.65;
|
||||||
/**
|
public static final double EVAL_FLAGDIST_FACTOR = 0.40;
|
||||||
* Evaluation mixing factor representing how much the flag distances will
|
public static final double EVAL_TORUSDIST_FACTOR = 0.04;
|
||||||
* affect the final evaluation value
|
|
||||||
*/
|
|
||||||
public static final double EVAL_FLAGDIST_FACTOR = 1 - EVAL_GHOSTDIST_FACTOR;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tree settings
|
* Tree settings
|
||||||
*/
|
*/
|
||||||
public static final int MINMAXTREE_MAX_DEPTH = 2; // MUST be multiple of 2
|
public static final int MINMAXTREE_MAX_DEPTH = 2; // MUST be multiple of 2
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In order to find out when a ghost is inside a cavity we manualy
|
* Maze setting
|
||||||
|
*/
|
||||||
|
public static final int[] POSITION_FALSE = {-1, -1};
|
||||||
|
|
||||||
|
public static final int DISTANCE_MAX = PacmanUtilities.numberOfRows + PacmanUtilities.numberOfColumns - 1;
|
||||||
|
public static final int DISTANCE_FALSE = -1;
|
||||||
|
|
||||||
|
public static final int FLAGDIST_MAX = 26; // add some for safety (lowers the gain)
|
||||||
|
public static final int BORDERDIST_MAX = 12; // add some for safety (lowers the gain)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In order to find out when a creature is inside a cavity we manually
|
||||||
* define the box limits of the cavity boxes of the current maze here
|
* define the box limits of the cavity boxes of the current maze here
|
||||||
* :)
|
* :)
|
||||||
*/
|
*/
|
||||||
@ -69,7 +78,38 @@ public class Globals {
|
|||||||
{ {11, 16}, {14, 19} }
|
{ {11, 16}, {14, 19} }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final int[] FALSE_POS = {-1, -1};
|
/**
|
||||||
|
* Torus borders are the squares in the outer limits of the maze where
|
||||||
|
* there are no walls. Pacman'a gravity can curve the maze plane to
|
||||||
|
* a torus through these squares. This function check if a box is
|
||||||
|
* a torus border box
|
||||||
|
*/
|
||||||
|
public static final int TORUS_BORDERS[][] = {
|
||||||
|
{0, 11},
|
||||||
|
{0, 12},
|
||||||
|
{0, 13},
|
||||||
|
{9, 0},
|
||||||
|
{9, 24},
|
||||||
|
{10, 0},
|
||||||
|
{10, 24},
|
||||||
|
{19, 11},
|
||||||
|
{19, 12},
|
||||||
|
{19, 13},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* General algorithm constants
|
||||||
|
*/
|
||||||
|
public static final int NO_PLACE = -1; // out of region square
|
||||||
|
public static final int INVALID_MOVE = -1; // invalid move marker
|
||||||
|
|
||||||
|
public static final int EVAL_MAX = 100; // out max evaluation value
|
||||||
|
public static final int EVAL_MIN = 0; // our minimum evaluation value
|
||||||
|
|
||||||
|
public static final int EVAL_FINAL_MAX = 100;
|
||||||
|
public static final int EVAL_FINAL_MIN = -100;
|
||||||
|
|
||||||
|
public static final int NO_EVAL = EVAL_FINAL_MIN-1; // mark the invalid on no evaluation
|
||||||
|
|
||||||
public static final int MAX_DISTANCE = PacmanUtilities.numberOfRows + PacmanUtilities.numberOfColumns - 1;
|
|
||||||
}
|
}
|
||||||
|
364
src/gr/auth/ee/dsproject/node/Node89978445.java
Normal file → Executable file
364
src/gr/auth/ee/dsproject/node/Node89978445.java
Normal file → Executable file
@ -12,7 +12,6 @@ package gr.auth.ee.dsproject.node;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
//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;
|
||||||
|
|
||||||
@ -25,9 +24,12 @@ 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 as return value of evaluation ()
|
||||||
* This is used also as the "return status" of the object
|
* This is used also as the "return status" of the object
|
||||||
|
* @note
|
||||||
|
* The variable is initialized to Globals.NO_EVAL and calculated only
|
||||||
|
* after the getEvaluation () call
|
||||||
*/
|
*/
|
||||||
int[] nodeXY; // Pacman's current x,y coordinate
|
int[] nodeXY; // Pacman's current x,y coordinate
|
||||||
int[][] curGhostPos; // Array holding the Ghost (x,y) pairs
|
int[][] curGhostPos; // Array holding the Ghost (x,y) pairs
|
||||||
@ -40,9 +42,9 @@ public class Node89978445
|
|||||||
* Tree navigation references. These variables are handled by
|
* Tree navigation references. These variables are handled by
|
||||||
* PacTree
|
* PacTree
|
||||||
*/
|
*/
|
||||||
Node89978445 parent;
|
Node89978445 parent; // reference to parent node in search tree
|
||||||
ArrayList<Node89978445> children;
|
ArrayList<Node89978445> children; // references to children nodes in search tree
|
||||||
int depth;
|
int depth; // the depth of the node in search tree
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ============ Constructors ==============
|
* ============ Constructors ==============
|
||||||
@ -51,14 +53,13 @@ public class Node89978445
|
|||||||
* @brief
|
* @brief
|
||||||
* The simple constructor. Just initialize the data
|
* The simple constructor. Just initialize the data
|
||||||
* @note
|
* @note
|
||||||
* Using this constructor means that the user MUST call setMaze(), setPosition()
|
* Using this constructor means that the user MUST call setMaze()
|
||||||
* and setMove manually after the creation of the Node89978445 object
|
* and setPosition() manually after the creation of the Node89978445 object
|
||||||
*/
|
*/
|
||||||
public Node89978445 ()
|
public Node89978445 ()
|
||||||
{
|
{
|
||||||
// Fill members
|
this.Maze = null; // Fill members
|
||||||
this.Maze = null;
|
nodeXY = Globals.POSITION_FALSE;
|
||||||
nodeXY = Globals.FALSE_POS;
|
|
||||||
nodeEvaluation = Globals.NO_EVAL;
|
nodeEvaluation = Globals.NO_EVAL;
|
||||||
parent = null;
|
parent = null;
|
||||||
|
|
||||||
@ -87,21 +88,14 @@ public class Node89978445
|
|||||||
flagPos = new int [PacmanUtilities.numberOfFlags][2];
|
flagPos = new int [PacmanUtilities.numberOfFlags][2];
|
||||||
curFlagStatus = 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 ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ============== Setters ===============
|
* ============== Setters ===============
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @brief SetMaze (Room) to Node object
|
* @brief
|
||||||
|
* SetMaze (Room) to Node object
|
||||||
* @param maze The room to set
|
* @param maze The room to set
|
||||||
*/
|
*/
|
||||||
public void setMaze (Room[][] maze) {
|
public void setMaze (Room[][] maze) {
|
||||||
@ -109,7 +103,8 @@ public class Node89978445
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set pacman's position
|
* @brief
|
||||||
|
* Set pacman's position
|
||||||
* @param curXY Pacman's current X, Y position
|
* @param curXY Pacman's current X, Y position
|
||||||
*/
|
*/
|
||||||
public void setPosition (int[] curXY) {
|
public void setPosition (int[] curXY) {
|
||||||
@ -121,9 +116,12 @@ public class Node89978445
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief If not done runs the evaluation algorithm and returns the result
|
* @brief
|
||||||
* @note We assume the current position was a valid position
|
* If not done calls the evaluation algorithm and returns the result
|
||||||
* @return The evaluation result
|
* @return The evaluation result (also stored inside object)
|
||||||
|
* @note
|
||||||
|
* We assume the current position was a valid position.
|
||||||
|
* This routine is not called upon creation of the class
|
||||||
*/
|
*/
|
||||||
public double getEvaluation ()
|
public double getEvaluation ()
|
||||||
{
|
{
|
||||||
@ -132,7 +130,7 @@ public class Node89978445
|
|||||||
// Safety filters
|
// Safety filters
|
||||||
if (Maze == null)
|
if (Maze == null)
|
||||||
return Globals.NO_EVAL;
|
return Globals.NO_EVAL;
|
||||||
if (nodeXY == Globals.FALSE_POS)
|
if (nodeXY == Globals.POSITION_FALSE)
|
||||||
return Globals.NO_EVAL;
|
return Globals.NO_EVAL;
|
||||||
// calculate helper arrays
|
// calculate helper arrays
|
||||||
curGhostPos = findGhosts ();
|
curGhostPos = findGhosts ();
|
||||||
@ -145,12 +143,21 @@ public class Node89978445
|
|||||||
return nodeEvaluation;
|
return nodeEvaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Nodes position in maze
|
||||||
|
*/
|
||||||
public int[] getCurrentPacmanPos () {
|
public int[] getCurrentPacmanPos () {
|
||||||
return nodeXY;
|
return nodeXY;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return Current ghost position ina maze
|
||||||
|
*/
|
||||||
public int[][] getCurrentGhostPos () {
|
public int[][] getCurrentGhostPos () {
|
||||||
return curGhostPos;
|
return curGhostPos;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @return The depth of the node tin the min-max tree
|
||||||
|
*/
|
||||||
public int getDepth () {
|
public int getDepth () {
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
@ -158,15 +165,32 @@ public class Node89978445
|
|||||||
/*
|
/*
|
||||||
* ============= Helper API ============
|
* ============= Helper API ============
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Convert back a maze position to Room's direction format
|
||||||
|
* @param nextPos The intention (x, y) coordinates
|
||||||
|
* @param curPos The current coordinates
|
||||||
|
* @return The direction
|
||||||
|
* @arg Room.NORTH (x decreases)
|
||||||
|
* @arg Room.SOUTH (x increases)
|
||||||
|
* @arg Room.WEST (y decreases)
|
||||||
|
* @arg Room.EAST (y increases)
|
||||||
|
*/
|
||||||
public static int moveConv (int[] nextPos, int[] curPos)
|
public static int moveConv (int[] nextPos, int[] curPos)
|
||||||
{
|
{
|
||||||
int dx = nextPos[0] - curPos[0];
|
int dx = nextPos[0] - curPos[0];
|
||||||
int dy = nextPos[1] - curPos[1];
|
int dy = nextPos[1] - curPos[1];
|
||||||
|
|
||||||
if (dx < 0) return Room.NORTH;
|
if (dx == -1 || dx == PacmanUtilities.numberOfRows-1)
|
||||||
else if (dx > 0) return Room.SOUTH;
|
return Room.NORTH;
|
||||||
else if (dy < 0) return Room.WEST;
|
else if (dx == 1 || dx == -PacmanUtilities.numberOfRows+1)
|
||||||
else return Room.EAST;
|
return Room.SOUTH;
|
||||||
|
else if (dy == -1 || dy == PacmanUtilities.numberOfColumns-1)
|
||||||
|
return Room.WEST;
|
||||||
|
else if (dy == 1 || dy == -PacmanUtilities.numberOfColumns+1)
|
||||||
|
return Room.EAST;
|
||||||
|
else
|
||||||
|
return Globals.INVALID_MOVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -184,34 +208,35 @@ public class Node89978445
|
|||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Static version of move validation
|
* Torus borders are the squares in the outer limits of the maze where
|
||||||
|
* there are no walls. Pacman's gravity can curve the maze plane to
|
||||||
|
* a torus through these squares. This function check if a position is
|
||||||
|
* a torus border position
|
||||||
|
* @param creature creature's (x,y)
|
||||||
|
* @return
|
||||||
|
* Return true if the creature is in a border position.
|
||||||
|
*/
|
||||||
|
public static boolean isTorusSquare (int[] creature)
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<Globals.TORUS_BORDERS.length ; ++i) {
|
||||||
|
if (creature[0] == Globals.TORUS_BORDERS[i][0] &&
|
||||||
|
creature[1] == Globals.TORUS_BORDERS[i][1]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Static version of move validation to use outside of the class
|
||||||
* Check if the requested move for a node is valid
|
* Check if the requested move for a node is valid
|
||||||
*/
|
*/
|
||||||
public static int[] pacmanValidMove (Node89978445 node, int move)
|
public static int[] pacmanValidMove (Node89978445 node, int move) {
|
||||||
{
|
return node.pacmanValidMove (node.nodeXY, 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -240,7 +265,7 @@ public class Node89978445
|
|||||||
ret[g][0] = x;
|
ret[g][0] = x;
|
||||||
ret[g][1] = y;
|
ret[g][1] = y;
|
||||||
// boundary check
|
// boundary check
|
||||||
if (++g > PacmanUtilities.numberOfGhosts)
|
if (++g >= PacmanUtilities.numberOfGhosts)
|
||||||
keepGoing = false;
|
keepGoing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,7 +284,7 @@ public class Node89978445
|
|||||||
private int[][] findFlags ()
|
private int[][] findFlags ()
|
||||||
{
|
{
|
||||||
int [][] ret = new int [PacmanUtilities.numberOfFlags][2]; // Make an object to return
|
int [][] ret = new int [PacmanUtilities.numberOfFlags][2]; // Make an object to return
|
||||||
int g = 0; // Flag index
|
int f = 0; // Flag index
|
||||||
boolean keepGoing = true; // Boundary check helper variable
|
boolean keepGoing = true; // Boundary check helper variable
|
||||||
|
|
||||||
// Loop entire Maze (i, j)
|
// Loop entire Maze (i, j)
|
||||||
@ -267,10 +292,10 @@ public class Node89978445
|
|||||||
for (int y=0 ; keepGoing && y<PacmanUtilities.numberOfColumns ; ++y) {
|
for (int y=0 ; keepGoing && y<PacmanUtilities.numberOfColumns ; ++y) {
|
||||||
if (Maze[x][y].isFlag()) {
|
if (Maze[x][y].isFlag()) {
|
||||||
// In case of a Ghost save its position to return object
|
// In case of a Ghost save its position to return object
|
||||||
ret[g][0] = x;
|
ret[f][0] = x;
|
||||||
ret[g][1] = y;
|
ret[f][1] = y;
|
||||||
// boundary check
|
// boundary check
|
||||||
if (++g > PacmanUtilities.numberOfFlags)
|
if (++f >= PacmanUtilities.numberOfFlags)
|
||||||
keepGoing = false;
|
keepGoing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -281,7 +306,6 @@ public class Node89978445
|
|||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Loop through flags and check their status
|
* Loop through flags and check their status
|
||||||
* @param none
|
|
||||||
* @return Object with flag status
|
* @return Object with flag status
|
||||||
*/
|
*/
|
||||||
private boolean[] checkFlags ()
|
private boolean[] checkFlags ()
|
||||||
@ -301,6 +325,10 @@ public class Node89978445
|
|||||||
* ============ private evaluation helper methods ==============
|
* ============ private evaluation helper methods ==============
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper enumerator to make a function pointer like trick
|
||||||
|
* inside @ref moveDist()
|
||||||
|
*/
|
||||||
private enum Creature {
|
private enum Creature {
|
||||||
GHOST, PACMAN
|
GHOST, PACMAN
|
||||||
}
|
}
|
||||||
@ -308,6 +336,11 @@ public class Node89978445
|
|||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Check if the requested ghost move is valid
|
* Check if the requested ghost move is valid
|
||||||
|
* @param ghost ghost coordinates to check the move validation
|
||||||
|
* @param move the move to check
|
||||||
|
* @return
|
||||||
|
* @arg The resulting position in maze if the move is valid.
|
||||||
|
* @arg If it is not valid return Globals.POSITION_FALSE
|
||||||
*/
|
*/
|
||||||
private int[] ghostValidMove (int[] ghost, int move)
|
private int[] ghostValidMove (int[] ghost, int move)
|
||||||
{
|
{
|
||||||
@ -324,15 +357,30 @@ public class Node89978445
|
|||||||
// Valid filters
|
// Valid filters
|
||||||
if (!((newPos[0] >= 0 && newPos[0] < PacmanUtilities.numberOfRows) &&
|
if (!((newPos[0] >= 0 && newPos[0] < PacmanUtilities.numberOfRows) &&
|
||||||
(newPos[1] >= 0 && newPos[1] < PacmanUtilities.numberOfColumns)))
|
(newPos[1] >= 0 && newPos[1] < PacmanUtilities.numberOfColumns)))
|
||||||
return Globals.FALSE_POS;
|
return Globals.POSITION_FALSE;
|
||||||
if (!isInsideBox(ghost) && (Maze[ghost[0]][ghost[1]].walls[move] == 0))
|
/*
|
||||||
return Globals.FALSE_POS;
|
* else if (Maze[newPos[0]][newPos[1]].isFlag ())
|
||||||
|
* return Globals.POSITION_FALSE;
|
||||||
|
* @note
|
||||||
|
* We comment out the flag part...
|
||||||
|
* This incorrect behavior help evaluation routine to stop treat
|
||||||
|
* flag position as asylum. In other words we remove the discontinuity
|
||||||
|
* of shortestMoveDist() for ghost function.
|
||||||
|
*/
|
||||||
|
else if (!isInsideBox(ghost) && (Maze[ghost[0]][ghost[1]].walls[move] == 0))
|
||||||
|
return Globals.POSITION_FALSE;
|
||||||
|
else
|
||||||
return newPos;
|
return newPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Check if the requested pacman move is valid
|
* Check if the requested pacman move is valid
|
||||||
|
* @param pacman pacman coordinates to check the move validation
|
||||||
|
* @param move the move to check
|
||||||
|
* @return
|
||||||
|
* @arg The resulting position in maze if the move is valid.
|
||||||
|
* @arg If it is not valid return Globals.POSITION_FALSE
|
||||||
*/
|
*/
|
||||||
private int[] pacmanValidMove (int[] pacman, int move)
|
private int[] pacmanValidMove (int[] pacman, int move)
|
||||||
{
|
{
|
||||||
@ -347,88 +395,98 @@ public class Node89978445
|
|||||||
newPos[1] -= (move == Room.WEST) ? 1:0;
|
newPos[1] -= (move == Room.WEST) ? 1:0;
|
||||||
|
|
||||||
// Pacman curves Maze plane to a Torus
|
// Pacman curves Maze plane to a Torus
|
||||||
if (newPos[0] < 0) newPos[0] = PacmanUtilities.numberOfRows;
|
if (newPos[0] < 0) newPos[0] = PacmanUtilities.numberOfRows-1;
|
||||||
if (newPos[0] >= PacmanUtilities.numberOfRows ) newPos[0] = 0;
|
if (newPos[0] >= PacmanUtilities.numberOfRows ) newPos[0] = 0;
|
||||||
if (newPos[1] < 0) newPos[1] = PacmanUtilities.numberOfColumns;
|
if (newPos[1] < 0) newPos[1] = PacmanUtilities.numberOfColumns-1;
|
||||||
if (newPos[1] >= PacmanUtilities.numberOfColumns ) newPos[1] = 0;
|
if (newPos[1] >= PacmanUtilities.numberOfColumns ) newPos[1] = 0;
|
||||||
|
|
||||||
// Valid filters
|
// Valid filters
|
||||||
if (!isInsideBox(pacman) && (Maze[pacman[0]][pacman[1]].walls[move] == 0))
|
if (Maze[pacman[0]][pacman[1]].walls[move] == 0)
|
||||||
return Globals.FALSE_POS;
|
return Globals.POSITION_FALSE;
|
||||||
|
else if (Maze[newPos[0]][newPos[1]].isGhost ())
|
||||||
|
return Globals.POSITION_FALSE;
|
||||||
|
else
|
||||||
return newPos;
|
return newPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* A Breadth-first search to find the shortest path distance
|
* A Breadth-first search to find the shortest path distance
|
||||||
* from an origin point to another point in the maze as if a
|
* from an origin point to another point in the maze as if
|
||||||
* a creature could walk through
|
* a creature could walk through origin to xy
|
||||||
* @param origin origin (x, y)
|
* @param origin origin's x, y (starting point)
|
||||||
* @param xy The x, y coordinate in Maze
|
* @param xy destination's x, y
|
||||||
* @param creature The type of creature for whom the path is for
|
* @param creature The type of creature for whom the path is for.
|
||||||
|
* This helper variable let us decide which validation
|
||||||
|
* function should call.
|
||||||
* @return The number of steps from origin to xy
|
* @return The number of steps from origin to xy
|
||||||
|
* @note
|
||||||
|
* As long as Java have not function pointers. I prefer this
|
||||||
|
* as a work around over interfaces and lambdas.
|
||||||
*/
|
*/
|
||||||
private int moveDist (int[] origin, int[] xy, Creature creature)
|
private int shortestMoveDist (int[] origin, int[] xy, Creature creature)
|
||||||
{
|
{
|
||||||
int move;
|
int move; // move direction
|
||||||
int steps, qStepItems; // distance and group counters
|
int steps, qStepItems; // distance and group counters
|
||||||
boolean done = false; // algo ending flag
|
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[] 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 (Globals.MAX_DISTANCE - 1); // Queue to feed with possible position
|
// Queue to feed with possible position
|
||||||
int [][] dist = new int [r][c];
|
Queue2D q = new Queue2D (Globals.DISTANCE_MAX - 1);
|
||||||
/*<
|
// 2D array holding all the distances from the origin to each square of the maze
|
||||||
* 2D array holding all the distances from the origin to each square of the maze
|
int[][] dist = new int [PacmanUtilities.numberOfRows][PacmanUtilities.numberOfColumns];
|
||||||
*/
|
|
||||||
|
|
||||||
// If target square is inside a box abort with max distance
|
|
||||||
if (isInsideBox(xy))
|
|
||||||
return Globals.MAX_DISTANCE;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* init data for algorithm
|
* If target square is inside a box abort with max DISTANCE_FALSE
|
||||||
|
* This is for speeding thing up, as the algorithm would return
|
||||||
|
* the same thing anyway.
|
||||||
*/
|
*/
|
||||||
for (int i=0 ; i<r ; ++i) {
|
if (isInsideBox(xy))
|
||||||
for (int j=0 ; j<c ; ++j) {
|
return Globals.DISTANCE_FALSE;
|
||||||
dist[i][j] = -1;
|
|
||||||
// dist array starts with -1
|
/*
|
||||||
}
|
* initialize data for algorithm
|
||||||
}
|
*/
|
||||||
// loop data
|
for (int i=0 ; i<PacmanUtilities.numberOfRows ; ++i)
|
||||||
|
for (int j=0 ; j<PacmanUtilities.numberOfColumns ; ++j)
|
||||||
|
dist[i][j] = Globals.DISTANCE_FALSE; // dist array starts with -1
|
||||||
dist [origin[0]][origin[1]] = 0; //starting point is the origin position
|
dist [origin[0]][origin[1]] = 0; //starting point is the origin position
|
||||||
q.insert (origin); // feed first loop data
|
q.insert (origin); // feed first loop data
|
||||||
qStepItems = 1; // init counters
|
qStepItems = 1; // init counters
|
||||||
steps = 1;
|
steps = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main loop of the algorithm
|
* Main loop of the algorithm.
|
||||||
*
|
* For every position pulled from queue with the same "steps" value:
|
||||||
* For every position we check the valid moves, we apply to them
|
* - check all the valid moves around current's position
|
||||||
* the step number and we push them to queue. We group the items in
|
* - mark them with the current "steps" value in dist[][] array
|
||||||
* queue with their step number by measuring how many we push them for
|
* - push them to queue
|
||||||
* the current steps variable value.
|
* - count the pushed position with the same "steps" value in queue
|
||||||
|
* If no other queued position with the current "steps" value remained
|
||||||
|
* increase "steps" value and continue.
|
||||||
*/
|
*/
|
||||||
while (done == false) {
|
while (done == false) {
|
||||||
if (qStepItems>0) { // Have we any item on the current group?
|
if (qStepItems>0) { // Have we any item on the current group?
|
||||||
xyItem = q.remove (); //load an item of the current group
|
xyItem = q.remove (); //load an item of the current group
|
||||||
--qStepItems; // mark the removal of the item
|
--qStepItems; // mark the removal of the item
|
||||||
for (move=0 ; move<4 ; ++move) {
|
|
||||||
// loop every valid next position for the current position
|
// loop every valid next position for the current position
|
||||||
|
for (move=0 ; move<4 ; ++move) {
|
||||||
switch (creature) {
|
switch (creature) {
|
||||||
case GHOST: xyNext = ghostValidMove (xyItem, move); break;
|
case GHOST: xyNext = ghostValidMove (xyItem, move); break;
|
||||||
case PACMAN: xyNext = pacmanValidMove (xyItem, move); break;
|
case PACMAN: xyNext = pacmanValidMove (xyItem, move); break;
|
||||||
default: xyNext = Globals.FALSE_POS;
|
default: xyNext = Globals.POSITION_FALSE;
|
||||||
|
/*
|
||||||
|
* Function pointer - like behavior
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
if (xyNext != Globals.FALSE_POS) {
|
if (xyNext != Globals.POSITION_FALSE) {
|
||||||
if (dist[xyNext[0]][xyNext[1]] == -1) {
|
if (dist[xyNext[0]][xyNext[1]] == Globals.DISTANCE_FALSE) {
|
||||||
// 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
|
||||||
if ((xyNext[0] == xy[0]) && (xyNext[1] == xy[1])) {
|
if ((xyNext[0] == xy[0]) && (xyNext[1] == xy[1])) {
|
||||||
/*
|
/*
|
||||||
* first match:
|
* first match: The first time we reach destination we
|
||||||
* The first time we reach destination we have count the
|
* have measured the distance. No need any other try
|
||||||
* distance. No need any other try
|
|
||||||
*/
|
*/
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
@ -444,7 +502,7 @@ public class Node89978445
|
|||||||
else {
|
else {
|
||||||
// We are done with group, mark how many are for the next one
|
// We are done with group, mark how many are for the next one
|
||||||
if ((qStepItems = q.size()) <= 0)
|
if ((qStepItems = q.size()) <= 0)
|
||||||
return dist[xy[0]][xy[1]]; // fail safe return
|
done = true; // There is no path to destination, abort
|
||||||
++steps; // Update distance counter
|
++steps; // Update distance counter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -453,47 +511,103 @@ public class Node89978445
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief
|
||||||
* Evaluate the current move
|
* Normalize a distance to our evaluation interval.
|
||||||
|
* @param v The value to normalize
|
||||||
|
* @param max The maximum input limit value
|
||||||
|
* @param out_min The minimum output limit value
|
||||||
|
* @param out_max The maximum output limit value
|
||||||
|
*/
|
||||||
|
private double normalize (double v, double max, double out_min, double out_max) {
|
||||||
|
return (v / max) * (out_max - out_min) + out_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Evaluate the current move.
|
||||||
|
* The position evaluation is based on shortestMoveDist() results.
|
||||||
|
* We measure the move distance of:
|
||||||
|
* 1) Ghosts to current position, as a ghost path, which represent the minimum steps
|
||||||
|
* needed by a ghost in order to reach the current position avoiding all obstacles
|
||||||
|
* 2) Pacman to all the flags, which represent the minimum steps needed by pacman
|
||||||
|
* in order to reach the flags avoiding all obstacles including the curving
|
||||||
|
* of the plane in the borders
|
||||||
|
* 3) Pacman to all the torus border squares, which represent the minimum steps needed
|
||||||
|
* by pacman in order to reach the torus border squares. @ref Globals.TORUS_BORDERS
|
||||||
|
*
|
||||||
|
* We mix these values in order to produce the final evaluation value
|
||||||
*/
|
*/
|
||||||
private double evaluate ()
|
private double evaluate ()
|
||||||
{
|
{
|
||||||
double ghostEval=0, gd=0;
|
double eval = 0; // mixed evaluation value
|
||||||
double flagEval=0;
|
double ghostEval = 0, gd; // ghost evaluation value
|
||||||
int i;
|
double flagEval = 0; // flag evaluation value
|
||||||
int[] flagDist = new int[PacmanUtilities.numberOfFlags];
|
double torusEval = 0; // torus evaluation value
|
||||||
int[] ghostDist = new int[PacmanUtilities.numberOfGhosts];
|
int[] ghostDist = new int[PacmanUtilities.numberOfGhosts]; // hold the ghost distances
|
||||||
int minGhostDist=Globals.MAX_DISTANCE+1;
|
int[] flagDist = new int[PacmanUtilities.numberOfFlags]; // hold the flag distances
|
||||||
int averGhostDist; // cast to integer
|
int[] torusDist = new int[Globals.TORUS_BORDERS.length]; // hold the torus square distances
|
||||||
int minFlagDist=Globals.MAX_DISTANCE+1;
|
int minGhostDist = Globals.DISTANCE_MAX+1; // hold the minimum ghost distance
|
||||||
|
int averGhostDist = Globals.DISTANCE_MAX; // hold the average ghost distance
|
||||||
|
int minFlagDist = Globals.DISTANCE_MAX+1; // hold the minimum flag distance
|
||||||
|
int minTorusDist = Globals.DISTANCE_MAX+1; // hold the minimum torus square distance
|
||||||
|
int i; // loop counter
|
||||||
|
|
||||||
// Find ghost distances, min and average
|
/*
|
||||||
|
* === Ghost distances part ===
|
||||||
|
*/
|
||||||
for (i=0, averGhostDist=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
|
for (i=0, averGhostDist=0 ; i<PacmanUtilities.numberOfGhosts ; ++i) {
|
||||||
ghostDist [i] = moveDist (curGhostPos[i], nodeXY, Creature.GHOST);
|
if ((ghostDist [i] = shortestMoveDist (curGhostPos[i], nodeXY, Creature.GHOST)) >= 1) {
|
||||||
averGhostDist += ghostDist [i];
|
averGhostDist += ghostDist [i];
|
||||||
if (minGhostDist > ghostDist[i])
|
if (minGhostDist > ghostDist[i])
|
||||||
minGhostDist = ghostDist[i];
|
minGhostDist = ghostDist[i];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
averGhostDist /= PacmanUtilities.numberOfGhosts;
|
averGhostDist /= PacmanUtilities.numberOfGhosts;
|
||||||
// extract the ghostEval as a combination of the minimum distance and the average
|
// 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;
|
gd = Globals.EVAL_GHOSTDIST_MIN_FACTOR * minGhostDist + Globals.EVAL_GHOSTDIST_AVER_FACTOR * averGhostDist;
|
||||||
// normalize the ghostEval to our interval
|
// normalize the ghostEval to our interval
|
||||||
ghostEval = (-1.0 / (1+gd)) * (Globals.EVAL_MAX - Globals.EVAL_MIN) + (Globals.EVAL_MAX - Globals.EVAL_MIN)/2;
|
if (minGhostDist <= Globals.EVAL_GHOST_BOOST)
|
||||||
|
ghostEval = normalize (gd, Globals.DISTANCE_MAX ,Globals.EVAL_MIN+Globals.EVAL_GHOSTBOOST_OFFSET, Globals.EVAL_MAX);
|
||||||
|
else if (minGhostDist <= Globals.EVAL_GHOST_TERRITORY)
|
||||||
|
ghostEval = normalize (gd, Globals.DISTANCE_MAX, Globals.EVAL_MIN, Globals.EVAL_MAX - Globals.EVAL_GHOSTTERRITORY_OFFSET);
|
||||||
|
else
|
||||||
|
ghostEval = normalize (gd, Globals.DISTANCE_MAX, Globals.EVAL_MIN, Globals.EVAL_MAX);
|
||||||
|
|
||||||
// Find flag distances and min
|
/*
|
||||||
|
* === Flag distances part ===
|
||||||
|
*/
|
||||||
for (i=0 ; i<PacmanUtilities.numberOfFlags ; ++i) {
|
for (i=0 ; i<PacmanUtilities.numberOfFlags ; ++i) {
|
||||||
if (curFlagStatus[i] == false) {
|
if (curFlagStatus[i] == false) {
|
||||||
flagDist[i] = moveDist (nodeXY, flagPos[i], Creature.PACMAN);
|
if ((flagDist[i] = shortestMoveDist (nodeXY, flagPos[i], Creature.PACMAN)) >= 0) {
|
||||||
if (minFlagDist > flagDist[i])
|
if (minFlagDist > flagDist[i])
|
||||||
minFlagDist = flagDist[i];
|
minFlagDist = flagDist[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// normalize the flagEval to our interval
|
// normalize the flagEval to our interval
|
||||||
flagEval = (1.0 / (1+minFlagDist)) * (Globals.EVAL_MAX - Globals.EVAL_MIN) - (Globals.EVAL_MAX - Globals.EVAL_MIN)/2;
|
if (minFlagDist <= Globals.EVAL_FLAG_BOOST)
|
||||||
|
flagEval = normalize ((double)Globals.FLAGDIST_MAX - minFlagDist, Globals.FLAGDIST_MAX, Globals.EVAL_MIN, Globals.EVAL_MAX+Globals.EVAL_FLAGBOOST_OFFSET);
|
||||||
|
else
|
||||||
|
flagEval = normalize ((double)Globals.FLAGDIST_MAX - minFlagDist, Globals.FLAGDIST_MAX, Globals.EVAL_MIN, Globals.EVAL_MAX);
|
||||||
|
|
||||||
// mix the life and goal to output
|
/*
|
||||||
return ghostEval * Globals.EVAL_GHOSTDIST_FACTOR
|
* === Torus borders distances part ===
|
||||||
+ flagEval * Globals.EVAL_FLAGDIST_FACTOR;
|
*/
|
||||||
|
for (i=0 ; i<Globals.TORUS_BORDERS.length ; ++i) {
|
||||||
|
if ((torusDist[i] = shortestMoveDist (nodeXY, Globals.TORUS_BORDERS[i], Creature.PACMAN)) >= 0) {
|
||||||
|
if (minTorusDist > torusDist[i])
|
||||||
|
minTorusDist = torusDist[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// normalize the flagEval to our interval
|
||||||
|
torusEval = normalize (Globals.BORDERDIST_MAX-minTorusDist, Globals.BORDERDIST_MAX, Globals.EVAL_MIN, Globals.EVAL_MAX);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* === Mix up the values and return the normalized value back to caller ===
|
||||||
|
*/
|
||||||
|
eval = ghostEval * Globals.EVAL_GHOSTDIST_FACTOR
|
||||||
|
+ flagEval * Globals.EVAL_FLAGDIST_FACTOR
|
||||||
|
+ torusEval * Globals.EVAL_TORUSDIST_FACTOR;
|
||||||
|
return normalize (eval, Globals.EVAL_FINAL_MAX, Globals.EVAL_FINAL_MIN, Globals.EVAL_FINAL_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
0
src/gr/auth/ee/dsproject/node/Queue2D.java
Normal file → Executable file
0
src/gr/auth/ee/dsproject/node/Queue2D.java
Normal file → Executable file
41
src/gr/auth/ee/dsproject/node/Tree.java
Normal file → Executable file
41
src/gr/auth/ee/dsproject/node/Tree.java
Normal file → Executable file
@ -1,7 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* @file MinMaxTree.java
|
* @file MinMaxTree.java
|
||||||
* @brief
|
* @brief
|
||||||
* File containing the Pacman Min-Max Tree class.
|
* File containing the Pacman Min-Max Tree class. A collection
|
||||||
|
* of static routines to build a search tree and execute
|
||||||
|
* a alpha-beta pruning algorithm to it
|
||||||
*
|
*
|
||||||
* @author Christos Choutouridis 8997 cchoutou@ece.auth.gr
|
* @author Christos Choutouridis 8997 cchoutou@ece.auth.gr
|
||||||
* @author Konstantina Tsechelidou 8445 konstsec@ece.auth.gr
|
* @author Konstantina Tsechelidou 8445 konstsec@ece.auth.gr
|
||||||
@ -30,9 +32,11 @@ public class Tree
|
|||||||
/*
|
/*
|
||||||
* ========== private helpers ==============
|
* ========== private helpers ==============
|
||||||
*/
|
*/
|
||||||
|
/** @return the minimum of x and y */
|
||||||
private static double min (double x, double y) {
|
private static double min (double x, double y) {
|
||||||
return (x < y) ? x : y;
|
return (x < y) ? x : y;
|
||||||
}
|
}
|
||||||
|
/** return the maximum of x and y */
|
||||||
private static double max (double x, double y) {
|
private static double max (double x, double y) {
|
||||||
return (x > y) ? x : y;
|
return (x > y) ? x : y;
|
||||||
}
|
}
|
||||||
@ -59,38 +63,59 @@ public class Tree
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* A recursive implementation of an alpha-beta pruning algorithm.
|
||||||
|
* Alpha–beta pruning is a search algorithm that seeks to decrease
|
||||||
|
* the number of nodes that are evaluated by the minimax algorithm in its search tree.
|
||||||
|
* It stops completely evaluating a move when at least one possibility has
|
||||||
|
* been found that proves the move to be worse than a previously examined move.
|
||||||
|
* Such moves need not be evaluated further.
|
||||||
|
* @param node current node of the tree. In the initial call is the root node
|
||||||
|
* @param depth the maximum depth to investigate
|
||||||
|
* @param a alpha (start -infinity)
|
||||||
|
* @param b beta (start +infinity)
|
||||||
|
* @param maxingPlayer helper variable to switch between min-max behavior
|
||||||
|
* @return
|
||||||
|
* reference to node with the maximum evaluation resulting path.
|
||||||
|
*/
|
||||||
public static Node89978445 minmaxAB (Node89978445 node, int depth, double a, double b, boolean maxingPlayer)
|
public static Node89978445 minmaxAB (Node89978445 node, int depth, double a, double b, boolean maxingPlayer)
|
||||||
{
|
{
|
||||||
double v, ev;
|
double v, ev;
|
||||||
Node89978445 vNode = null;
|
Node89978445 vNode = null;
|
||||||
|
|
||||||
if ((depth == 0) || (node.children.isEmpty()))
|
if ((depth == 0) || (node.children.isEmpty())) // Escape
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
if (maxingPlayer) {
|
if (maxingPlayer) {
|
||||||
v = Globals.EVAL_MIN - 1;
|
// maximizing player part
|
||||||
|
v = Integer.MIN_VALUE; // start small for max algorithm to work
|
||||||
|
// recursively call alpha-beta for every child, reducing depth and toggling between min and max
|
||||||
for (int i=0 ; i<node.children.size() ; ++i) {
|
for (int i=0 ; i<node.children.size() ; ++i) {
|
||||||
ev = minmaxAB (node.children.get (i), depth-1, a, b, false).getEvaluation();
|
ev = minmaxAB (node.children.get (i), depth-1, a, b, false).getEvaluation();
|
||||||
|
// select the maximum output node
|
||||||
if (ev > v) {
|
if (ev > v) {
|
||||||
v = ev;
|
v = ev;
|
||||||
vNode = node.children.get (i);
|
vNode = node.children.get (i);
|
||||||
}
|
}
|
||||||
a = max (v, a);
|
a = max (v, a); // mark alpha
|
||||||
if (b <= a)
|
if (b <= a) // cut-off alpha
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return vNode;
|
return vNode;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v = Globals.EVAL_MAX + 1;
|
// minimizing player part
|
||||||
|
v = Integer.MAX_VALUE; // start big for min algorithm to work
|
||||||
|
// recursively call alpha-beta for every child, reducing depth and toggling between min and max
|
||||||
for (int i=0 ; i<node.children.size() ; ++i) {
|
for (int i=0 ; i<node.children.size() ; ++i) {
|
||||||
ev = minmaxAB(node.children.get (i), depth-1, a, b, true).getEvaluation();
|
ev = minmaxAB(node.children.get (i), depth-1, a, b, true).getEvaluation();
|
||||||
if (ev < v) {
|
if (ev < v) {
|
||||||
v = ev;
|
v = ev;
|
||||||
vNode = node.children.get (i);
|
vNode = node.children.get (i);
|
||||||
}
|
}
|
||||||
b = min (v, b);
|
b = min (v, b); // mark beta
|
||||||
if (b <= a)
|
if (b <= a) // cut-off beta
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return vNode;
|
return vNode;
|
||||||
|
38
src/gr/auth/ee/dsproject/pacman/Creature.java
Normal file → Executable file
38
src/gr/auth/ee/dsproject/pacman/Creature.java
Normal file → Executable file
@ -30,8 +30,7 @@ import gr.auth.ee.dsproject.node.Node89978445;
|
|||||||
public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
||||||
{
|
{
|
||||||
|
|
||||||
public String getName ()
|
public String getName () {
|
||||||
{
|
|
||||||
return "Mine";
|
return "Mine";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,11 +42,16 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @brief
|
||||||
|
* For any current position creates a tree for minmax alpha-beta pruning algorithm
|
||||||
|
* apply the min-max algo and return the move representing by resulting node
|
||||||
|
* @return
|
||||||
|
* the move of pacman to play
|
||||||
*/
|
*/
|
||||||
public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition)
|
public int calculateNextPacmanPosition (Room[][] Maze, int[] currPosition)
|
||||||
{
|
{
|
||||||
int [] bestPos = {-1, -1}; // Best position in maze to play
|
int [] bestPos = {-1, -1}; // Best position in maze to play
|
||||||
|
int bestMove = 0;
|
||||||
Node89978445 bestNode; // The node with the best evaluation
|
Node89978445 bestNode; // The node with the best evaluation
|
||||||
Node89978445 cur = new Node89978445 (Maze, currPosition); // The node with the current position
|
Node89978445 cur = new Node89978445 (Maze, currPosition); // The node with the current position
|
||||||
|
|
||||||
@ -55,15 +59,23 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
|||||||
createSubTreePacman (cur.getDepth (), cur, Maze, currPosition);
|
createSubTreePacman (cur.getDepth (), cur, Maze, currPosition);
|
||||||
|
|
||||||
// min-max to find best node and consequently the best position
|
// 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);
|
bestNode = Tree.minmaxAB (cur, Globals.MINMAXTREE_MAX_DEPTH-1, Integer.MIN_VALUE, Integer.MAX_VALUE, true);
|
||||||
bestPos = bestNode.getCurrentPacmanPos();
|
bestPos = bestNode.getCurrentPacmanPos();
|
||||||
|
|
||||||
// convert back to move encoding
|
// convert back to move encoding
|
||||||
return Node89978445.moveConv (bestPos, currPosition);
|
if ((bestMove = Node89978445.moveConv (bestPos, currPosition)) != Globals.INVALID_MOVE)
|
||||||
|
return bestMove;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @brief
|
||||||
|
* For any ghost (or root) parent node, create all child nodes representing
|
||||||
|
* pacman's valid moves.
|
||||||
|
* @note
|
||||||
|
* This routine calls createSubTreeGhosts() called back from it recursively.
|
||||||
|
* The recursion ends when the right depth is reached.
|
||||||
*/
|
*/
|
||||||
void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] curPacmanPosition)
|
void createSubTreePacman (int depth, Node89978445 parent, Room[][] Maze, int[] curPacmanPosition)
|
||||||
{
|
{
|
||||||
@ -82,16 +94,16 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
|||||||
|
|
||||||
// scan possible valid moves
|
// scan possible valid moves
|
||||||
for (int move=0 ; move<4 ; ++move) {
|
for (int move=0 ; move<4 ; ++move) {
|
||||||
if ((nextPosition = Node89978445.pacmanValidMove (parent, move)) != Globals.FALSE_POS) {
|
if ((nextPosition = Node89978445.pacmanValidMove (parent, move)) != Globals.POSITION_FALSE) {
|
||||||
// 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.getCurrentPacmanPos(), 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);
|
||||||
Tree.grow (newNode, parent); // add node to the min-max tree
|
Tree.grow (newNode, parent); // add node to the min-max search tree
|
||||||
|
|
||||||
// call the recursive ranch creator
|
// call the recursive branch creator
|
||||||
createSubTreeGhosts (newNode.getDepth (), newNode, newMaze, newNode.getCurrentGhostPos());
|
createSubTreeGhosts (newNode.getDepth (), newNode, newMaze, newNode.getCurrentGhostPos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,7 +111,11 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @brief
|
||||||
|
* For any parent node, create all child node representing ghosts valid moves.
|
||||||
|
* @note
|
||||||
|
* This routine recursively call createSubTreePacman().
|
||||||
|
* The recursion ends when the right depth is reached.
|
||||||
*/
|
*/
|
||||||
void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition)
|
void createSubTreeGhosts (int depth, Node89978445 parent, Room[][] Maze, int[][] currGhostsPosition)
|
||||||
{
|
{
|
||||||
@ -127,7 +143,7 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature
|
|||||||
|
|
||||||
// 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.getCurrentPacmanPos());
|
newNode = new Node89978445 (newMaze, parent.getCurrentPacmanPos());
|
||||||
Tree.grow (newNode, parent); // add node to the min-max tree
|
Tree.grow (newNode, parent); // add node to the min-max search tree
|
||||||
|
|
||||||
//recursive call for the rest of the tree
|
//recursive call for the rest of the tree
|
||||||
createSubTreePacman (newNode.getDepth (), newNode, newMaze, parent.getCurrentPacmanPos());
|
createSubTreePacman (newNode.getDepth (), newNode, newMaze, parent.getCurrentPacmanPos());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user