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 | 
							
								
								
									
										94
									
								
								src/gr/auth/ee/dsproject/node/Globals.java
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										94
									
								
								src/gr/auth/ee/dsproject/node/Globals.java
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -19,46 +19,55 @@ 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 |  | ||||||
|     |  | ||||||
|     |  | ||||||
|    /* |    /* | ||||||
|     * Evaluation settings |     * Evaluation settings | ||||||
|     */ |     */ | ||||||
|    /** |    /** | ||||||
|     *  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 | ||||||
|     * :)  |     * :)  | ||||||
|     */ |     */ | ||||||
| @ -68,8 +77,39 @@ public class Globals { | |||||||
|       { {11,  5}, {14,  8} }, |       { {11,  5}, {14,  8} }, | ||||||
|       { {11, 16}, {14, 19} } |       { {11, 16}, {14, 19} } | ||||||
|    }; |    }; | ||||||
|  | 
 | ||||||
|  |    /** | ||||||
|  |     * 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}, | ||||||
|  |    }; | ||||||
|  | 
 | ||||||
|     |     | ||||||
|    public static final int[] FALSE_POS = {-1, -1}; |    /* | ||||||
|  |     * 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; |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										400
									
								
								src/gr/auth/ee/dsproject/node/Node89978445.java
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										400
									
								
								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,16 +53,15 @@ 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; | ||||||
| 
 | 
 | ||||||
|       // allocate objects |       // allocate objects | ||||||
|       curGhostPos    = new int [PacmanUtilities.numberOfGhosts][2]; |       curGhostPos    = new int [PacmanUtilities.numberOfGhosts][2]; | ||||||
| @ -77,39 +78,33 @@ public class Node89978445 | |||||||
|     */ |     */ | ||||||
|    public Node89978445 (Room[][] Maze, int[] curXY) |    public Node89978445 (Room[][] Maze, int[] curXY) | ||||||
|    { |    { | ||||||
|       this.Maze = Maze; // Fill members |       this.Maze      = Maze; // Fill members | ||||||
|       nodeXY = curXY; |       nodeXY         = curXY; | ||||||
|       nodeEvaluation = Globals.NO_EVAL; |       nodeEvaluation = Globals.NO_EVAL; | ||||||
|       parent = null; |       parent         = null; | ||||||
| 
 | 
 | ||||||
|       // allocate objects |       // allocate objects | ||||||
|       curGhostPos    = new int [PacmanUtilities.numberOfGhosts][2]; |       curGhostPos    = new int [PacmanUtilities.numberOfGhosts][2]; | ||||||
|       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 | ||||||
|     * @param   maze  The room to set  |     *    SetMaze (Room) to Node object | ||||||
|  |     * @param maze    The room to set  | ||||||
|     */ |     */ | ||||||
|    public void setMaze (Room[][] maze) { |    public void setMaze (Room[][] maze) { | ||||||
|       this.Maze = maze; |       this.Maze = maze; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    /** |    /** | ||||||
|     * @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 () | ||||||
| @ -300,7 +324,11 @@ 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 newPos; |        *    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 |     * @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; | ||||||
|       return newPos; |       else if (Maze[newPos[0]][newPos[1]].isGhost ()) | ||||||
|  |          return Globals.POSITION_FALSE; | ||||||
|  |       else | ||||||
|  |          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 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. | ||||||
|  |        */ | ||||||
|       if (isInsideBox(xy)) |       if (isInsideBox(xy)) | ||||||
|          return Globals.MAX_DISTANCE; |          return Globals.DISTANCE_FALSE; | ||||||
| 
 | 
 | ||||||
|       /* |       /* | ||||||
|        *  init data for algorithm |        *  initialize data for algorithm | ||||||
|        */ |        */ | ||||||
|       for (int i=0 ; i<r ; ++i) { |       for (int i=0 ; i<PacmanUtilities.numberOfRows ; ++i) | ||||||
|          for (int j=0 ; j<c ; ++j) { |          for (int j=0 ; j<PacmanUtilities.numberOfColumns ; ++j) | ||||||
|             dist[i][j] = -1; |             dist[i][j] = Globals.DISTANCE_FALSE;   // dist array starts with -1 | ||||||
|             // 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 | ||||||
|       // loop data |  | ||||||
|       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; |       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 | ||||||
|  |             // loop every valid next position for the current position | ||||||
|             for (move=0 ; move<4 ; ++move) { |             for (move=0 ; move<4 ; ++move) { | ||||||
|                // loop every valid next position for the current position |  | ||||||
|                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,8 +502,8 @@ 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 | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|       return dist[xy[0]][xy[1]]; |       return dist[xy[0]][xy[1]]; | ||||||
| @ -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); | ||||||
|       // mix the life and goal to output |       else | ||||||
|       return ghostEval * Globals.EVAL_GHOSTDIST_FACTOR |          flagEval = normalize ((double)Globals.FLAGDIST_MAX - minFlagDist, Globals.FLAGDIST_MAX, Globals.EVAL_MIN, Globals.EVAL_MAX); | ||||||
|              + 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 |  * @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; | ||||||
|  | |||||||
							
								
								
									
										60
									
								
								src/gr/auth/ee/dsproject/pacman/Creature.java
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										60
									
								
								src/gr/auth/ee/dsproject/pacman/Creature.java
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @ -30,24 +30,28 @@ 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"; |    } | ||||||
|   } |     | ||||||
|  |    private int step = 1; | ||||||
|  |    private boolean amPrey; | ||||||
|  |     | ||||||
|  |    public Creature (boolean isPrey) { | ||||||
|  |       amPrey = isPrey; | ||||||
|  |    } | ||||||
| 
 | 
 | ||||||
|   private int step = 1; |    /** | ||||||
|   private boolean amPrey; |     * @brief | ||||||
| 
 |     *     For any current position creates a tree for minmax alpha-beta pruning algorithm | ||||||
|   public Creature (boolean isPrey) { |     *     apply the min-max algo and return the move representing by resulting node | ||||||
|     amPrey = isPrey; |     * @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