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	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 | ||||
|  */ | ||||
| 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 | ||||
|     */ | ||||
|    public static final double EVAL_GHOSTDIST_MIN_FACTOR = 0.8; | ||||
|    public static final double EVAL_LGHOSTDIST_AVER_FACTOR = 1 - EVAL_GHOSTDIST_MIN_FACTOR; | ||||
|    // ghosts | ||||
|    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 | ||||
|     * affect the final evaluation value | ||||
|     * Evaluation mixing factor representing how much the individual | ||||
|     * evaluation values(host, flag, torus) affect the final evaluation of the position | ||||
|     */ | ||||
|    public static final double EVAL_GHOSTDIST_FACTOR = 0.6; | ||||
|    /** | ||||
|     * 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; | ||||
|    public static final double EVAL_GHOSTDIST_FACTOR = 0.65; | ||||
|    public static final double EVAL_FLAGDIST_FACTOR = 0.40; | ||||
|    public static final double EVAL_TORUSDIST_FACTOR = 0.04; | ||||
| 
 | ||||
| 
 | ||||
|    /* | ||||
|     * Tree settings | ||||
|     */ | ||||
|    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 | ||||
|     * :)  | ||||
|     */ | ||||
| @ -69,7 +78,38 @@ public class Globals { | ||||
|       { {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.awt.image.PackedColorModel; | ||||
| import gr.auth.ee.dsproject.pacman.PacmanUtilities; | ||||
| import gr.auth.ee.dsproject.pacman.Room; | ||||
| 
 | ||||
| @ -25,9 +24,12 @@ import gr.auth.ee.dsproject.pacman.Room; | ||||
|  */ | ||||
| public class Node89978445 | ||||
| { | ||||
|    double nodeEvaluation;     /*< | ||||
|                                * Pacman's current move evaluation | ||||
|    double nodeEvaluation;     /** | ||||
|                                * Pacman's current move evaluation as return value of evaluation () | ||||
|                                * 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[][] curGhostPos;       // Array holding the Ghost (x,y) pairs | ||||
| @ -40,9 +42,9 @@ public class Node89978445 | ||||
|     * Tree navigation references. These variables are handled by | ||||
|     * PacTree | ||||
|     */ | ||||
|    Node89978445            parent; | ||||
|    ArrayList<Node89978445> children; | ||||
|    int depth; | ||||
|    Node89978445            parent;     // reference to parent node in search tree | ||||
|    ArrayList<Node89978445> children;   // references to children nodes in search tree | ||||
|    int depth;                          // the depth of the node in search tree | ||||
| 
 | ||||
|    /* | ||||
|     * ============ Constructors ============== | ||||
| @ -51,14 +53,13 @@ public class Node89978445 | ||||
|     * @brief | ||||
|     *    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 Node89978445 object | ||||
|     *    Using this constructor means that the user MUST call setMaze()  | ||||
|     *    and setPosition() manually after the creation of the Node89978445 object | ||||
|     */ | ||||
|    public Node89978445 () | ||||
|    { | ||||
|       // Fill members | ||||
|       this.Maze = null; | ||||
|       nodeXY = Globals.FALSE_POS; | ||||
|       this.Maze      = null;  // Fill members | ||||
|       nodeXY         = Globals.POSITION_FALSE; | ||||
|       nodeEvaluation = Globals.NO_EVAL; | ||||
|       parent         = null; | ||||
| 
 | ||||
| @ -87,21 +88,14 @@ public class Node89978445 | ||||
|       flagPos        = new int [PacmanUtilities.numberOfFlags][2]; | ||||
|       curFlagStatus  = new boolean[PacmanUtilities.numberOfFlags]; | ||||
|       children       = new ArrayList<Node89978445> (); | ||||
|        | ||||
|       // calculate helper arrays | ||||
|       curGhostPos    = findGhosts (); | ||||
|       flagPos        = findFlags (); | ||||
|       curFlagStatus  = checkFlags (); | ||||
|        | ||||
|       //Evaluate the position | ||||
|       nodeEvaluation = evaluate (); | ||||
|    } | ||||
| 
 | ||||
|    /* | ||||
|     * ============== Setters =============== | ||||
|     */ | ||||
|    /** | ||||
|     * @brief   SetMaze (Room) to Node object | ||||
|     * @brief | ||||
|     *    SetMaze (Room) to Node object | ||||
|     * @param maze    The room to set  | ||||
|     */ | ||||
|    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 | ||||
|     */ | ||||
|    public void setPosition (int[] curXY) { | ||||
| @ -121,9 +116,12 @@ 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 | ||||
|     * @brief | ||||
|     *    If not done calls the evaluation algorithm and returns the 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 () | ||||
|    { | ||||
| @ -132,7 +130,7 @@ public class Node89978445 | ||||
|          // Safety filters | ||||
|          if (Maze == null) | ||||
|             return Globals.NO_EVAL; | ||||
|          if (nodeXY == Globals.FALSE_POS) | ||||
|          if (nodeXY == Globals.POSITION_FALSE) | ||||
|             return Globals.NO_EVAL; | ||||
|          // calculate helper arrays | ||||
|          curGhostPos = findGhosts (); | ||||
| @ -145,12 +143,21 @@ public class Node89978445 | ||||
|          return nodeEvaluation; | ||||
|     } | ||||
| 
 | ||||
|    /** | ||||
|     * @return  Nodes position in maze | ||||
|     */ | ||||
|    public int[] getCurrentPacmanPos () { | ||||
|       return nodeXY; | ||||
|    } | ||||
|    /** | ||||
|     * @return  Current ghost position ina maze | ||||
|     */ | ||||
|    public int[][] getCurrentGhostPos () { | ||||
|       return curGhostPos; | ||||
|    } | ||||
|    /** | ||||
|     * @return  The depth of the node tin the min-max tree | ||||
|     */ | ||||
|    public int getDepth () { | ||||
|       return depth; | ||||
|    } | ||||
| @ -158,15 +165,32 @@ public class Node89978445 | ||||
|    /* | ||||
|     * ============= 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) | ||||
|    { | ||||
|       int dx = nextPos[0] - curPos[0]; | ||||
|       int dy = nextPos[1] - curPos[1]; | ||||
|             | ||||
|       if      (dx < 0)  return Room.NORTH; | ||||
|       else if (dx > 0)  return Room.SOUTH; | ||||
|       else if (dy < 0)  return Room.WEST; | ||||
|       else              return Room.EAST; | ||||
|       if      (dx == -1 || dx ==  PacmanUtilities.numberOfRows-1) | ||||
|          return Room.NORTH; | ||||
|       else if (dx == 1  || dx == -PacmanUtilities.numberOfRows+1) | ||||
|          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; | ||||
|    } | ||||
| 
 | ||||
|    /** | ||||
|     * @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 | ||||
|     */ | ||||
|    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; | ||||
|    public static int[] pacmanValidMove (Node89978445 node, int move) { | ||||
|       return node.pacmanValidMove (node.nodeXY, move); | ||||
|    } | ||||
| 
 | ||||
| 
 | ||||
| @ -240,7 +265,7 @@ public class Node89978445 | ||||
|                ret[g][0] = x; | ||||
|                ret[g][1] = y; | ||||
|                // boundary check | ||||
|                if (++g > PacmanUtilities.numberOfGhosts) | ||||
|                if (++g >= PacmanUtilities.numberOfGhosts) | ||||
|                   keepGoing = false; | ||||
|             } | ||||
|          } | ||||
| @ -259,7 +284,7 @@ public class Node89978445 | ||||
|    private int[][] findFlags () | ||||
|    { | ||||
|       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 | ||||
| 
 | ||||
|       // Loop entire Maze (i, j) | ||||
| @ -267,10 +292,10 @@ public class Node89978445 | ||||
|          for (int y=0 ; keepGoing && y<PacmanUtilities.numberOfColumns ; ++y) { | ||||
|             if (Maze[x][y].isFlag()) { | ||||
|                // In case of a Ghost save its position to return object | ||||
|                ret[g][0] = x; | ||||
|                ret[g][1] = y; | ||||
|                ret[f][0] = x; | ||||
|                ret[f][1] = y; | ||||
|                // boundary check | ||||
|                if (++g > PacmanUtilities.numberOfFlags) | ||||
|                if (++f >= PacmanUtilities.numberOfFlags) | ||||
|                   keepGoing = false; | ||||
|             } | ||||
|          } | ||||
| @ -281,7 +306,6 @@ public class Node89978445 | ||||
|    /** | ||||
|     * @brief | ||||
|     *    Loop through flags and check their status | ||||
|     * @param   none | ||||
|     * @return  Object with flag status | ||||
|     */ | ||||
|    private boolean[] checkFlags () | ||||
| @ -301,6 +325,10 @@ public class Node89978445 | ||||
|     * ============ private evaluation helper methods ============== | ||||
|     */ | ||||
| 
 | ||||
|    /** | ||||
|     * Helper enumerator to make a function pointer like trick | ||||
|     * inside @ref moveDist() | ||||
|     */ | ||||
|    private enum Creature { | ||||
|       GHOST, PACMAN | ||||
|    } | ||||
| @ -308,6 +336,11 @@ public class Node89978445 | ||||
|    /** | ||||
|     * @brief | ||||
|     *    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) | ||||
|    { | ||||
| @ -324,15 +357,30 @@ public class Node89978445 | ||||
|       // 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 Globals.POSITION_FALSE; | ||||
|       /* | ||||
|        * 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; | ||||
|    } | ||||
| 
 | ||||
|    /** | ||||
|     * @brief | ||||
|     *    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) | ||||
|    { | ||||
| @ -347,88 +395,98 @@ public class Node89978445 | ||||
|       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] < 0)   newPos[0] = PacmanUtilities.numberOfRows-1; | ||||
|       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; | ||||
| 
 | ||||
|       // Valid filters | ||||
|       if (!isInsideBox(pacman) && (Maze[pacman[0]][pacman[1]].walls[move] == 0)) | ||||
|          return Globals.FALSE_POS; | ||||
|       if (Maze[pacman[0]][pacman[1]].walls[move] == 0) | ||||
|          return Globals.POSITION_FALSE; | ||||
|       else if (Maze[newPos[0]][newPos[1]].isGhost ()) | ||||
|          return Globals.POSITION_FALSE; | ||||
|       else | ||||
|          return newPos; | ||||
|    } | ||||
| 
 | ||||
|    /** | ||||
|     * @brief | ||||
|     *    A Breadth-first search to find the shortest path distance | ||||
|     *    from an origin point to another point in the maze as if a | ||||
|     *    a creature could walk through | ||||
|     * @param origin     origin (x, y) | ||||
|     * @param xy         The x, y coordinate in Maze | ||||
|     * @param creature   The type of creature for whom the path is for | ||||
|     *    from an origin point to another point in the maze as if | ||||
|     *    a creature could walk through origin to xy | ||||
|     * @param origin     origin's x, y (starting point) | ||||
|     * @param xy         destination's x, y | ||||
|     * @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 | ||||
|     * @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 | ||||
|       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 (Globals.MAX_DISTANCE - 1);  // Queue to feed with possible position | ||||
|       int [][] dist = new int [r][c]; | ||||
|       /*< | ||||
|        * 2D array holding all the distances from the origin to each square of the maze | ||||
|        */ | ||||
| 
 | ||||
|       // If target square is inside a box abort with max distance | ||||
|       if (isInsideBox(xy)) | ||||
|          return Globals.MAX_DISTANCE; | ||||
|       // Queue to feed with possible position | ||||
|       Queue2D q = new Queue2D (Globals.DISTANCE_MAX - 1); | ||||
|       // 2D array holding all the distances from the origin to each square of the maze | ||||
|       int[][] dist = new int [PacmanUtilities.numberOfRows][PacmanUtilities.numberOfColumns]; | ||||
| 
 | ||||
|       /* | ||||
|        *  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) { | ||||
|          for (int j=0 ; j<c ; ++j) { | ||||
|             dist[i][j] = -1; | ||||
|             // dist array starts with -1 | ||||
|          } | ||||
|       } | ||||
|       // loop data | ||||
|       if (isInsideBox(xy)) | ||||
|          return Globals.DISTANCE_FALSE; | ||||
| 
 | ||||
|       /* | ||||
|        *  initialize data for algorithm | ||||
|        */ | ||||
|       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 | ||||
|       q.insert (origin);                           // 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. | ||||
|        * Main loop of the algorithm. | ||||
|        * For every position pulled from queue with the same "steps" value: | ||||
|        * - check all the valid moves around current's position | ||||
|        * - mark them with the current "steps" value in dist[][] array | ||||
|        * - push them to queue | ||||
|        * - 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) { | ||||
|          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 | ||||
|             for (move=0 ; move<4 ; ++move) { | ||||
|                switch (creature) { | ||||
|                   case GHOST:    xyNext = ghostValidMove (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 (dist[xyNext[0]][xyNext[1]] == -1) { | ||||
|                if (xyNext != Globals.POSITION_FALSE) { | ||||
|                   if (dist[xyNext[0]][xyNext[1]] == Globals.DISTANCE_FALSE) { | ||||
|                      // 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 | ||||
|                          *  first match: The first time we reach destination we | ||||
|                          *  have measured the distance. No need any other try | ||||
|                          */ | ||||
|                         done = true; | ||||
|                         break; | ||||
| @ -444,7 +502,7 @@ public class Node89978445 | ||||
|          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 | ||||
|                done = true;   // There is no path to destination, abort | ||||
|             ++steps;          // Update distance counter | ||||
|          } | ||||
|       } | ||||
| @ -453,47 +511,103 @@ public class Node89978445 | ||||
| 
 | ||||
|    /** | ||||
|     * @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 () | ||||
|    { | ||||
|       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; | ||||
|       double eval       = 0;     // mixed evaluation value | ||||
|       double ghostEval  = 0, gd; // ghost evaluation value | ||||
|       double flagEval   = 0;     // flag evaluation value | ||||
|       double torusEval  = 0;     // torus evaluation value | ||||
|       int[] ghostDist   = new int[PacmanUtilities.numberOfGhosts];   // hold the ghost distances | ||||
|       int[] flagDist    = new int[PacmanUtilities.numberOfFlags];    // hold the flag distances | ||||
|       int[] torusDist   = new int[Globals.TORUS_BORDERS.length];     // hold the torus square distances | ||||
|       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) { | ||||
|          ghostDist [i] = moveDist (curGhostPos[i], nodeXY, Creature.GHOST); | ||||
|          if ((ghostDist [i] = shortestMoveDist (curGhostPos[i], nodeXY, Creature.GHOST)) >= 1) { | ||||
|             averGhostDist += ghostDist [i]; | ||||
|             if (minGhostDist > ghostDist[i]) | ||||
|                minGhostDist = ghostDist[i]; | ||||
|          } | ||||
|       } | ||||
|       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; | ||||
|       gd = Globals.EVAL_GHOSTDIST_MIN_FACTOR * minGhostDist + Globals.EVAL_GHOSTDIST_AVER_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; | ||||
|       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) { | ||||
|          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]) | ||||
|                   minFlagDist = flagDist[i]; | ||||
|             } | ||||
|          } | ||||
|       } | ||||
|       // 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 | ||||
|              + flagEval * Globals.EVAL_FLAGDIST_FACTOR; | ||||
|       /* | ||||
|        *  === Torus borders distances part === | ||||
|        */ | ||||
|       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 | ||||
|  * @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  Konstantina Tsechelidou 8445 konstsec@ece.auth.gr | ||||
| @ -30,9 +32,11 @@ public class Tree | ||||
|    /* | ||||
|     * ========== private helpers  ============== | ||||
|     */ | ||||
|    /** @return the minimum of x and y */ | ||||
|    private static double min (double x, double y) { | ||||
|       return (x < y) ? x : y; | ||||
|    } | ||||
|    /** return the maximum of x and y */ | ||||
|    private static double max (double x, double y) { | ||||
|       return (x > y) ? x : y; | ||||
|    } | ||||
| @ -59,38 +63,59 @@ public class Tree | ||||
|          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) | ||||
|    { | ||||
|       double v, ev; | ||||
|       Node89978445 vNode = null; | ||||
| 
 | ||||
|       if ((depth == 0) || (node.children.isEmpty())) | ||||
|       if ((depth == 0) || (node.children.isEmpty()))  // Escape | ||||
|          return node; | ||||
|        | ||||
|       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) { | ||||
|             ev = minmaxAB (node.children.get (i), depth-1, a, b, false).getEvaluation(); | ||||
|             // select the maximum output node | ||||
|             if (ev > v) { | ||||
|                v = ev; | ||||
|                vNode = node.children.get (i); | ||||
|             } | ||||
|             a = max (v, a); | ||||
|             if (b <= a) | ||||
|             a = max (v, a);   // mark alpha | ||||
|             if (b <= a)       // cut-off alpha | ||||
|                break; | ||||
|          } | ||||
|          return vNode; | ||||
|       } | ||||
|       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) { | ||||
|             ev = minmaxAB(node.children.get (i), depth-1, a, b, true).getEvaluation(); | ||||
|             if (ev < v) { | ||||
|                v = ev; | ||||
|                vNode = node.children.get (i); | ||||
|             } | ||||
|             b = min (v, b); | ||||
|             if (b <= a) | ||||
|             b = min (v, b);   // mark beta | ||||
|             if (b <= a)       // cut-off beta | ||||
|                break; | ||||
|          } | ||||
|          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 String getName () | ||||
|   { | ||||
|    public String getName () { | ||||
|       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) | ||||
|    { | ||||
|       int [] bestPos = {-1, -1};    // Best position in maze to play | ||||
|       int bestMove = 0; | ||||
|       Node89978445 bestNode;        // The node with the best evaluation | ||||
|       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); | ||||
| 
 | ||||
|       // 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(); | ||||
| 
 | ||||
|       // 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) | ||||
|    { | ||||
| @ -82,16 +94,16 @@ public class Creature implements gr.auth.ee.dsproject.pacman.AbstractCreature | ||||
| 
 | ||||
|          // scan possible valid moves | ||||
|          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 | ||||
|                newMaze = PacmanUtilities.copy (Maze); | ||||
|                PacmanUtilities.movePacman (newMaze, parent.getCurrentPacmanPos(), nextPosition); | ||||
|           | ||||
|                // Create a node for the move in the new stated game maze | ||||
|                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()); | ||||
|             } | ||||
|          } | ||||
| @ -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) | ||||
|    { | ||||
| @ -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 | ||||
|             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 | ||||
|             createSubTreePacman (newNode.getDepth (), newNode, newMaze, parent.getCurrentPacmanPos()); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user