loseyou

导航

MyFirstgame 拼图

  1 package auto;
  2 
  3 
  4 /**
  5  * IDA*求解15puzzle问题
  6  * IDA*整合了IDDFS和A*算法。其中IDDFS控制了求解过程中的内存开销,A*算法意味着"启发式"搜索。
  7  * IDA*可以理解成迭代深度的A*算法,其中这里的"深度"指的是问题的解的"假定损耗"。
  8  * 使"假定损耗"不断迭代增加,检验是否能在"假定损耗"的前提找到可行解,如果不行的话,就继续迭代。
  9  * 这里和A*算法不同的是没有开放列表,由于采用了IDDFS的策略,IDA*是深度优先搜索的,故此没有开放列表。
 10  * @author wly
 11  * @date 2013-12-20
 12  *
 13  */
 14 public class IDAStarAlgorithm {
 15 
 16     //分别代表左、上、右、下四个移动方向的操作数
 17     private int[] up = {-1,0};
 18     private int[] down = {1,0};
 19     private int[] left = {0,-1};
 20     private int[] right = {0,1};
 21     
 22     /**注意,这里UP和DOWN,LEFT和RIGHT必须是两两相对的,因为后面代码中使用
 23      * ((dPrev != dCurr) && (dPrev%2 == dCurr%2))
 24      * 来判断前后两个移动方向是否相反
 25      */
 26     private final int UP = 0;
 27     private final int DOWN = 2;
 28     private final int LEFT = 1;
 29     private final int RIGHT = 3;
 30     
 31     private int SIZE;
 32     
 33     //各个目标点坐标
 34     private int[][] targetPoints; 
 35     
 36     //用于记录移动步骤,存储0,1,2,3,对应上,下,左,右
 37     private static int[] moves = new int[100000];
 38     
 39     private static long ans = 0;; //当前迭代的"设想代价"
 40     
 41     //目标状态
 42     private static int[][] tState = {
 43         {1 ,2 ,3 ,4 ,5} ,
 44         {6 ,7 ,8 ,9,10} ,
 45         {11,12,13,14,15} ,
 46         {16,17,18,19,20},
 47         {21,22,23,24,0}
 48     };
 49     
 50     private static int[][] sState = {
 51         {1,2,3,4,5},
 52         {6,7,8,9,0},
 53         {10,11,12,13,14},
 54         {15,16,17,18,19},
 55         {20,21,22,23,24}
 56     };
 57     
 58     //初始状态
 59 //    private static int[][] sState = {
 60 //        {12,1 ,10,2 } ,
 61 //        {7 ,11,4 ,14} ,
 62 //        {5 ,0 ,9 ,15} ,
 63 //        {8 ,13,6 ,3} 
 64 //    };
 65     
 66     private static int blank_row,blank_column;
 67     
 68     public IDAStarAlgorithm(int[][] state) {
 69         SIZE = state.length;
 70         targetPoints = new int[SIZE * SIZE][2];
 71         
 72         this.sState = state;
 73         //得到空格坐标
 74         for(int i=0;i<state.length;i++) {
 75             for(int j=0;j<state[i].length;j++) {
 76                 if(state[i][j] == 0) {
 77                     blank_row = i;
 78                     blank_column = j;
 79                     break;
 80                 }
 81             }
 82         }
 83         
 84         //得到目标点坐标数组
 85         for(int i=0;i<state.length;i++) {
 86             for(int j=0;j<state.length;j++) {
 87                 targetPoints[tState[i][j]][0] = i; //行信息
 88                 
 89                 targetPoints[tState[i][j]][1] = j; //列信息
 90             }
 91         }
 92         for(int i=0;i<moves.length;i++) {
 93             moves[i] = -1;
 94         }
 95     }
 96     
 97     /**
 98      * 讨论问题的可解性
 99      * @param state 状态
100      */
101     private boolean canSolve(int[][] state) {
102         if(state.length % 2 == 1) { //问题宽度为奇数
103             return (getInversions(state) % 2 == 0);
104         } else { //问题宽度为偶数
105             if((state.length - blank_row) % 2 == 1) { //从底往上数,空格位于奇数行
106                 return (getInversions(state) % 2 == 0);
107             } else { //从底往上数,空位位于偶数行
108                 return (getInversions(state) % 2 == 1);
109             }
110         }
111     }
112     
113     public static void main(String[] args) {
114         
115         IDAStarAlgorithm idaAlgorithm = new IDAStarAlgorithm(sState);
116         if(idaAlgorithm.canSolve(sState)) {
117             System.out.println("--问题可解,开始求解--");
118             //以曼哈顿距离为初始最小代价数
119             int j = idaAlgorithm.getHeuristic(sState);
120             System.out.println("初始manhattan距离:" + j);
121             int i = -1;//置空默认移动方向
122             
123             long time = System.currentTimeMillis();
124             //迭代加深"最小代价数"
125             for(ans=j;;ans++) {
126                 if(idaAlgorithm.solve(sState
127                         ,blank_row,blank_column,0,i,j)) {
128                     break;
129                 }
130             }
131             System.out.println("求解用时:"+(System.currentTimeMillis() - time));
132 
133             idaAlgorithm.printMatrix(sState);
134             int[][] matrix = idaAlgorithm.move(sState,moves[0]);
135             for(int k=1;k<ans;k++) {
136                 matrix = idaAlgorithm.move(matrix, moves[k]);
137             }
138             
139         } else {
140             System.out.println("--抱歉!输入的问题无可行解--");
141         }
142     }
143     
144     
145     public int[] getSolvePath(int[][] data) {
146         for(int i=0;i<moves.length;i++) {
147             moves[i] = -1;
148         }
149         if(canSolve(data)) {
150             System.out.println("--问题可解,开始求解--");
151             //以曼哈顿距离为初始最小代价数
152             int j = getHeuristic(data);
153             System.out.println("初始manhattan距离:" + j);
154             int i = -1;//置空默认移动方向
155             
156             long time = System.currentTimeMillis();
157             //迭代加深"最小代价数"
158             for(ans=j;;ans++) {
159                 if(solve(data
160                         ,blank_row,blank_column,0,i,j)) {
161                     break;
162                 }
163             }
164             System.out.println("求解用时:"+(System.currentTimeMillis() - time));
165 
166 //            printMatrix(data);
167 //            int[][] matrix = move(data,moves[0]);
168 //            for(int k=1;k<ans;k++) {
169 //                matrix = move(matrix, moves[k]);
170 //            }
171             return moves;
172         } else {
173             System.out.println("--抱歉!输入的问题无可行解--");
174             return null;
175         }
176     }
177     
178     public int[][] move(int[][]state,int direction) {
179         int row = 0;
180         int column = 0;
181         for(int i=0;i<state.length;i++) {
182             for(int j=0;j<state.length;j++) {
183                 if(state[i][j] == 0) {
184                     row = i;
185                     column = j;
186                 }
187             }
188         }
189         switch(direction) {
190         case UP:
191             state[row][column] = state[row-1][column];
192             state[row-1][column] = 0;
193             break;
194         case DOWN:
195             state[row][column] = state[row+1][column];
196             state[row+1][column] = 0;
197             break;
198         case LEFT:
199             state[row][column] = state[row][column-1];
200             state[row][column-1] = 0;
201             break;
202         case RIGHT:
203             state[row][column] = state[row][column+1];
204             state[row][column+1] = 0;
205             break;
206         }
207         printMatrix(state);
208         return state;
209     }
210     
211     public void printMatrix(int[][] matrix) {
212         System.out.println("------------");
213         for(int i=0;i<matrix.length;i++) {
214             for(int j=0;j<matrix.length;j++) {
215                 System.out.print(matrix[i][j] + " ");
216             }
217             System.out.println();
218         }
219     }
220     
221     /**
222      * 求解方法
223      * @param state 当前状态
224      * @param blank_row 空位的行坐标
225      * @param blank_column 空格的列坐标
226      * @param dep 当前深度
227      * @param d 上一次移动的方向
228      * @param h 当前状态估价函数
229      * @return
230      */
231     public boolean solve(int[][] state,int blank_row,int blank_column,
232             int dep,long d,long h) {
233         
234         long h1;
235         
236         //和目标矩阵比较,看是否相同,如果相同则表示问题已解
237         boolean isSolved = true;
238         for(int i=0;i<SIZE;i++) {
239             for(int j=0;j<SIZE;j++) {
240                 if(state[i][j] != tState[i][j]) {
241                     isSolved = false;
242                 }
243             }
244         }
245         if(isSolved) {
246             return true;
247         }
248         
249         if(dep == ans) {
250             return false;
251         }
252 
253         //用于表示"空格"移动后的坐标位置
254         int blank_row1 = blank_row;
255         int blank_column1  = blank_column;
256         int[][] state2 = new int[SIZE][SIZE];
257 
258         for(int direction=0;direction<4;direction++) {
259             for(int i=0;i<state.length;i++) {
260                 for(int j=0;j<state.length;j++) {
261                     state2[i][j] = state[i][j];
262                 }
263             }
264             
265             //本地移动方向和上次移动方向刚好相反,跳过这种情况的讨论
266             if(direction != d && (d%2 == direction%2)) {
267                 continue;
268             }
269             
270             if(direction == UP) {
271                 blank_row1 = blank_row + up[0];
272                 blank_column1 = blank_column + up[1];
273             } else if(direction == DOWN) {
274                 blank_row1 = blank_row + down[0];
275                 blank_column1 = blank_column + down[1];
276             } else if(direction == LEFT) {
277                 blank_row1 = blank_row + left[0];
278                 blank_column1 = blank_column + left[1];
279             } else {
280                 blank_row1 = blank_row + right[0];
281                 blank_column1 = blank_column + right[1];
282             }
283             
284             //边界检查
285             if(blank_column1 < 0 || blank_column1 == SIZE
286                     || blank_row1 < 0 || blank_row1 == SIZE) {
287                 continue ;
288             }
289             
290             //交换空格位置和当前移动位置对应的单元格    
291             state2[blank_row][blank_column] = state2[blank_row1][blank_column1];
292             state2[blank_row1][blank_column1] = 0;
293             
294             //查看当前空格是否正在靠近目标点
295             if(direction == DOWN && blank_row1 
296                     > targetPoints[state[blank_row1][blank_column1]][0]) {
297                 h1 = h - 1;
298             } else if(direction == UP && blank_row1 
299                     < targetPoints[state[blank_row1][blank_column1]][0]){
300                 h1 = h - 1;
301             } else if(direction == RIGHT && blank_column1 
302                     > targetPoints[state[blank_row1][blank_column1]][1]) {
303                 h1 = h - 1;
304             } else if(direction == LEFT && blank_column1 
305                     < targetPoints[state[blank_row1][blank_column1]][1]) {
306                 h1 = h - 1;
307             } else { 
308                 //这种情况发生在任意可能的移动方向都会使得估价函数值变大
309                 h1 = h + 1;
310             }
311             
312             if(h1+dep+1>ans) { //剪枝
313                 continue;
314             }
315             
316             moves[dep] = direction;
317             
318             //迭代深度求解
319             if(solve(state2, blank_row1, blank_column1, dep+1, direction, h1)) {
320                 return true;
321             }
322         }
323         return false;
324     }
325     
326     /**
327      * 得到估价函数值
328      */
329     public int getHeuristic(int[][] state) {
330         int heuristic = 0;
331         for(int i=0;i<state.length;i++) {
332             for(int j=0;j<state[i].length;j++) {
333                 if(state[i][j] != 0) {
334                     heuristic = heuristic + 
335                             Math.abs(targetPoints[state[i][j]][0] - i)
336                             + Math.abs(targetPoints[state[i][j]][1] - j);
337                     
338                 }
339             }
340         }
341         return heuristic;
342     }
343     
344     /**
345      * 计算问题的"倒置变量和"
346      * @param state
347      */
348     private int getInversions(int[][] state) {
349         int inversion = 0;
350         int temp = 0;
351         for(int i=0;i<state.length;i++) {
352             for(int j=0;j<state[i].length;j++) {
353                 int index = i* state.length + j + 1;
354                 while(index < (state.length * state.length)) {
355                     if(state[index/state.length][index%state.length] != 0 
356                             && state[index/state.length]
357                                     [index%state.length] < state[i][j]) {
358                         temp ++;
359                     }
360                     index ++;
361                 }
362                 inversion = temp + inversion;
363                 temp = 0;
364             }
365         }
366         return inversion;
367     }
368     
369 }
View Code
  1 package auto;
  2 
  3 
  4 import java.awt.BorderLayout;
  5 import java.awt.EventQueue;
  6 
  7 import javax.swing.ImageIcon;
  8 import javax.swing.JFrame;
  9 import javax.swing.JOptionPane;
 10 import javax.swing.JPanel;
 11 import javax.swing.border.EmptyBorder;
 12 
 13 import java.awt.GridLayout;
 14 
 15 import javax.swing.JLabel;
 16 
 17 import java.awt.GridBagLayout;
 18 import java.awt.GridBagConstraints;
 19 import java.awt.Insets;
 20 import java.awt.Color;
 21 
 22 import javax.swing.JButton;
 23 
 24 import java.awt.event.ActionListener;
 25 import java.awt.event.ActionEvent;
 26 import java.awt.event.MouseAdapter;
 27 import java.awt.event.MouseEvent;
 28 import java.util.Collection;
 29 import java.util.Date;
 30 import java.util.HashMap;
 31 import java.util.HashSet;
 32 import java.util.Iterator;
 33 import java.util.Map;
 34 import java.util.Set;
 35 import java.util.Map.Entry;
 36 import java.util.Stack;
 37 
 38 public class playGame extends JFrame {
 39 
 40     private JPanel contentPane;
 41 /*    private static JLabel p1;
 42     private static JLabel p2;
 43     private static JLabel p3;
 44     private static JLabel p4;
 45     private static JLabel p5;
 46     private static JLabel p6;
 47     private static JLabel p7;
 48     private static JLabel p8;
 49     private static JLabel p9;
 50 */
 51     private final int UP = 0;
 52     private final int DOWN = 2;
 53     private final int LEFT = 1;
 54     private final int RIGHT = 3;
 55     static JLabel[] p=new JLabel[10];
 56     static JLabel[][] pa;
 57     private int start=0;
 58     static int now;
 59     private static String[] na;
 60     private static String[] ni;
 61     static String[] nn;
 62     static HashSet<String> s;
 63     //static String ans="123456789";
 64     static int rear;
 65     static int[] a;
 66     static final int size=3;
 67     static int [][] state;
 68     static int [][] tstate;
 69     static int[] moves=new int[100010];
 70     static int ans;
 71     public static int blank_row,blank_column;
 72     public static playGame frame ;
 73     /**
 74      * Launch the application.
 75      */
 76     public static void main(String[] args) {
 77         EventQueue.invokeLater(new Runnable() {
 78             public void run() {
 79                 try {
 80                     frame = new playGame();
 81                     frame.setVisible(true);
 82                 } catch (Exception e) {
 83                     e.printStackTrace();
 84                 }
 85             }
 86         });
 87     }
 88 
 89     /**
 90      * Create the frame.
 91      */
 92     public playGame() {
 93         setForeground(Color.CYAN);
 94         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 95         setBounds(0, 0, 450, 300);
 96         setSize(600,530);
 97         contentPane = new JPanel();
 98         contentPane.setBackground(Color.WHITE);
 99         contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
100         setContentPane(contentPane);
101         GridBagLayout gbl_contentPane = new GridBagLayout();
102         gbl_contentPane.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
103         gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0};
104         gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
105         gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
106         contentPane.setLayout(gbl_contentPane);
107         
108         p[1] = new JLabel("\u56FE\u7247");
109         p[1].addMouseListener(new MouseAdapter() {
110             @Override
111             public void mouseClicked(MouseEvent e) {
112                 if(canswap(1)){
113                     swap(p[1],p[now]);
114                     swap(1,now);
115                     now=1;
116                     
117                     if(iscorrect()){
118                         p[now].setVisible(true);
119                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
120                     }
121                 }
122             }
123 
124         });
125         GridBagConstraints gbc_p1 = new GridBagConstraints();
126         gbc_p1.gridwidth = 2;
127         gbc_p1.gridheight = 2;
128         gbc_p1.insets = new Insets(0, 0, 5, 5);
129         gbc_p1.gridx = 1;
130         gbc_p1.gridy = 1;
131         contentPane.add(p[1], gbc_p1);
132         
133         p[2] = new JLabel("\u56FE\u7247");
134         p[2].addMouseListener(new MouseAdapter() {
135             @Override
136             public void mouseClicked(MouseEvent e) {
137                 if(canswap(2)){
138                     swap(p[2],p[now]);
139                     swap(2,now);
140                     now=2;
141                     
142                     if(iscorrect()){
143                         p[now].setVisible(true);
144                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
145                     }
146                 }
147             }
148         });
149         GridBagConstraints gbc_p2 = new GridBagConstraints();
150         gbc_p2.gridheight = 2;
151         gbc_p2.anchor = GridBagConstraints.NORTHWEST;
152         gbc_p2.gridwidth = 2;
153         gbc_p2.insets = new Insets(0, 0, 5, 5);
154         gbc_p2.gridx = 3;
155         gbc_p2.gridy = 1;
156         contentPane.add(p[2], gbc_p2);
157         
158         p[3] = new JLabel("\u56FE\u7247");
159         p[3].addMouseListener(new MouseAdapter() {
160             @Override
161             public void mouseClicked(MouseEvent e) {
162                 if(canswap(3)){
163                     swap(p[3],p[now]);
164                     swap(3,now);
165                     now=3;
166                     
167                     if(iscorrect()){
168                         p[now].setVisible(true);
169                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
170                     }
171                 }
172             }
173         });
174         GridBagConstraints gbc_p3 = new GridBagConstraints();
175         gbc_p3.gridheight = 2;
176         gbc_p3.gridwidth = 2;
177         gbc_p3.insets = new Insets(0, 0, 5, 5);
178         gbc_p3.gridx = 5;
179         gbc_p3.gridy = 1;
180         contentPane.add(p[3], gbc_p3);
181         
182         JButton last = new JButton("\u4E0A\u4E00\u5F20");
183         last.addActionListener(new ActionListener() {
184             public void actionPerformed(ActionEvent e) {
185                 if(start<0)
186                     start=start+3;
187                 init(start);
188             }
189         });
190         GridBagConstraints gbc_last = new GridBagConstraints();
191         gbc_last.insets = new Insets(0, 0, 5, 0);
192         gbc_last.gridx = 11;
193         gbc_last.gridy = 1;
194         contentPane.add(last, gbc_last);
195         
196         p[4] = new JLabel("\u56FE\u7247");
197         p[4].addMouseListener(new MouseAdapter() {
198             @Override
199             public void mouseClicked(MouseEvent e) {
200                 if(canswap(4)){
201                     swap(p[4],p[now]);
202                     swap(4,now);
203                     now=4;
204             
205                 
206                     if(iscorrect()){
207                         p[now].setVisible(true);
208                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
209                     }
210                 }
211             }
212         });
213         GridBagConstraints gbc_p4 = new GridBagConstraints();
214         gbc_p4.gridwidth = 2;
215         gbc_p4.gridheight = 2;
216         gbc_p4.insets = new Insets(0, 0, 5, 5);
217         gbc_p4.gridx = 1;
218         gbc_p4.gridy = 3;
219         contentPane.add(p[4], gbc_p4);
220         
221         p[5] = new JLabel("\u56FE\u7247");
222         p[5].addMouseListener(new MouseAdapter() {
223             @Override
224             public void mouseClicked(MouseEvent e) {
225                 if(canswap(5)){
226                     swap(p[5],p[now]);
227                     swap(5,now);
228                     now=5;
229                     
230                     if(iscorrect()){
231                         p[now].setVisible(true);
232                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
233                     }
234                 }
235             }
236         });
237         GridBagConstraints gbc_p5 = new GridBagConstraints();
238         gbc_p5.gridwidth = 2;
239         gbc_p5.gridheight = 2;
240         gbc_p5.insets = new Insets(0, 0, 5, 5);
241         gbc_p5.gridx = 3;
242         gbc_p5.gridy = 3;
243         contentPane.add(p[5], gbc_p5);
244         
245         p[6] = new JLabel("\u56FE\u7247");
246         p[6].addMouseListener(new MouseAdapter() {
247             @Override
248             public void mouseClicked(MouseEvent e) {
249                 if(canswap(6)){
250                     swap(p[6],p[now]);
251                     swap(6,now);
252                     now=6;
253                 
254                     if(iscorrect()){
255                         p[now].setVisible(true);
256                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
257                     }
258                 }
259             }
260         });
261         GridBagConstraints gbc_p6 = new GridBagConstraints();
262         gbc_p6.gridwidth = 2;
263         gbc_p6.gridheight = 2;
264         gbc_p6.insets = new Insets(0, 0, 5, 5);
265         gbc_p6.gridx = 5;
266         gbc_p6.gridy = 3;
267         contentPane.add(p[6], gbc_p6);
268         
269         JButton next = new JButton("\u4E0B\u4E00\u5F20");
270         next.addActionListener(new ActionListener() {
271             public void actionPerformed(ActionEvent e) {
272                 start++;
273                 if(start>=3)
274                     start-=3;
275                 init(start);
276             }
277         });
278         GridBagConstraints gbc_next = new GridBagConstraints();
279         gbc_next.insets = new Insets(0, 0, 5, 0);
280         gbc_next.gridx = 11;
281         gbc_next.gridy = 3;
282         contentPane.add(next, gbc_next);
283         
284         p[7] = new JLabel("\u56FE\u7247");
285         p[7].addMouseListener(new MouseAdapter() {
286             @Override
287             public void mouseClicked(MouseEvent e) {
288                 if(canswap(7)){
289                     swap(p[7],p[now]);
290                     swap(7,now);
291                     now=7;
292                     if(iscorrect()){
293                         p[now].setVisible(true);
294                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
295                     }
296                 }
297             }
298         });
299         GridBagConstraints gbc_p7 = new GridBagConstraints();
300         gbc_p7.gridwidth = 2;
301         gbc_p7.gridheight = 2;
302         gbc_p7.insets = new Insets(0, 0, 5, 5);
303         gbc_p7.gridx = 1;
304         gbc_p7.gridy = 5;
305         contentPane.add(p[7], gbc_p7);
306         
307         p[8] = new JLabel("\u56FE\u7247");
308         p[8].addMouseListener(new MouseAdapter() {
309             @Override
310             public void mouseClicked(MouseEvent e) {
311                 if(canswap(8)){
312                     swap(p[8],p[now]);
313                     swap(8,now);
314                     now=8;
315                     if(iscorrect()){
316                         p[now].setVisible(true);
317                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
318                     }
319                 }
320             }
321         });
322         GridBagConstraints gbc_p8 = new GridBagConstraints();
323         gbc_p8.gridwidth = 2;
324         gbc_p8.gridheight = 2;
325         gbc_p8.insets = new Insets(0, 0, 5, 5);
326         gbc_p8.gridx = 3;
327         gbc_p8.gridy = 5;
328         contentPane.add(p[8], gbc_p8);
329         
330         p[9] = new JLabel("\u56FE\u7247");
331         p[9].addMouseListener(new MouseAdapter() {
332             @Override
333             public void mouseClicked(MouseEvent e) {
334                 if(canswap(9)){
335                     swap(p[9],p[now]);
336                     swap(9,now);
337                     now=9;
338                     
339                     if(iscorrect()){
340                         p[now].setVisible(true);
341                         JOptionPane.showMessageDialog(null, "恭喜拼图成功");
342                     }
343                 }
344             }
345         });
346         GridBagConstraints gbc_p9 = new GridBagConstraints();
347         gbc_p9.gridwidth = 2;
348         gbc_p9.gridheight = 2;
349         gbc_p9.insets = new Insets(0, 0, 5, 5);
350         gbc_p9.gridx = 5;
351         gbc_p9.gridy = 5;
352         contentPane.add(p[9], gbc_p9);
353         
354         JButton auto = new JButton("\u81EA\u52A8\u6F14\u793A");
355         auto.addActionListener(new ActionListener() {
356             public void actionPerformed(ActionEvent e) {
357                 pa=new JLabel[3][3];
358                 for(int i=0;i<3;i++){
359                     for(int j=0;j<3;j++){
360                         pa[i][j]=p[i*3+j+1];
361                     }
362                 }
363                 gettstate();        
364                 AutoRunner au=new AutoRunner(tstate);
365                 if(au.canSolve(tstate)){
366                     System.out.println("--问题可解,开始求解--");
367                     //以曼哈顿距离为初始最小代价数
368                     int j = au.getHeuristic(tstate);
369                     System.out.println("初始manhattan距离:" + j);
370                     int i = -1;//置空默认移动方向
371                     
372                     long time = System.currentTimeMillis();
373                     //迭代加深"最小代价数"
374                     for(au.ans=j;;au.ans++) {
375                         if(au.solve(tstate
376                                 ,blank_row,blank_column,0,i,j)) {
377                             break;
378                         }
379                     }
380                     moves=au.getmoves();
381                     
382                     JOptionPane.showMessageDialog(null,"求解用时:"+(System.currentTimeMillis() - time)/1000.0);
383                 
384                     //JOptionPane.showMessageDialog(null, "第"+(0)+"步!");
385                     for(int k=0;k<au.ans;k++){
386                         tstate=move(tstate,moves[k]);
387                         for(i=0;i<tstate.length;i++){
388                             for(j=0;j<tstate[i].length;j++){
389                                 if(tstate[i][j]==0){
390                                     pa[i][j].setVisible(false);
391                                 }
392                                 else{
393                                     pa[i][j].setVisible(true);
394                                 }
395                             }
396                         }
397                         
398                         JOptionPane.showMessageDialog(null, "第"+(k+1)+"步!");
399                         try{
400                             Thread thread = Thread.currentThread();
401                             thread.sleep(1000);//暂停1.5秒后程序继续执行
402                         }catch (InterruptedException e1) {
403                             // TODO Auto-generated catch block
404                             e1.printStackTrace();
405                         }
406                         
407                     /*    try {
408                             Thread.sleep(1000);
409                         } catch (InterruptedException e1) {
410                             // TODO Auto-generated catch block
411                             e1.printStackTrace();
412                         }
413                     */
414                         print(tstate);
415                         }
416                     for(i=0;i<3;i++){
417                         for(j=0;j<3;j++){
418                             pa[i][j].setVisible(true);
419                         }
420                         
421                     }
422                     }else {
423                     
424                         JOptionPane.showMessageDialog(null,"--抱歉!输入的问题无可行解--");
425                         for(int i=0;i<3;i++){
426                             for(int j=0;j<3;j++){
427                                 p[i*3+j+1]=pa[i][j];
428                             }
429                         }
430                         init(start);
431                     }
432             
433                 for(int i=0;i<3;i++){
434                     for(int j=0;j<3;j++){
435                         p[i*3+j+1]=pa[i][j];
436                     }
437                 }
438             }
439                     /*int[][] matrix = au.move(tstate,moves[0]);
440                     for(int k=1;k<au.ans;k++) {
441                         matrix = au.move(matrix, moves[k]);
442                     }
443                     
444                 } else {
445                     System.out.println("--抱歉!输入的问题无可行解--");
446                 }
447                 */
448         });
449         GridBagConstraints gbc_auto = new GridBagConstraints();
450         gbc_auto.insets = new Insets(0, 0, 5, 0);
451         gbc_auto.gridx = 11;
452         gbc_auto.gridy = 5;
453         contentPane.add(auto, gbc_auto);
454         
455         JButton button = new JButton("\u672C\u5F20");
456         button.addActionListener(new ActionListener() {
457             public void actionPerformed(ActionEvent e) {
458                 init(start);
459             }
460         });
461         GridBagConstraints gbc_button = new GridBagConstraints();
462         gbc_button.gridx = 11;
463         gbc_button.gridy = 7;
464         contentPane.add(button, gbc_button);
465         playGame.init(start);
466     }
467 
468 /*    public static void show1(int[][] tstate2) {
469         // TODO Auto-generated method stub
470         for(int i=0;i<tstate2.length;i++){
471             for(int j=0;j<tstate2[i].length;j++){
472                 if(state[i][j]==0){
473                     pa[i][j].setVisible(false);
474                 }
475                 else{
476                     pa[i][j].setVisible(true);
477                 }
478             }
479         }
480         try {
481             Thread.sleep(1000);
482         } catch (InterruptedException e) {
483             // TODO Auto-generated catch block
484             e.printStackTrace();
485         }
486     }
487 */
488     public static void print(int[][] matrix){
489         System.out.println("------------");
490         for(int i=0;i<matrix.length;i++) {
491             for(int j=0;j<matrix.length;j++) {
492                 System.out.print(matrix[i][j] + " ");
493             }
494             System.out.println();
495         }
496     }
497 
498     public int[][] move(int[][]state1,int direction) {
499         int row = 0;
500         int column = 0;
501         for(int i=0;i<state1.length;i++) {
502             for(int j=0;j<state1.length;j++) {
503                 if(state1[i][j] == 0) {
504                     row = i;
505                     column = j;
506                 }
507             }
508         }
509         switch(direction) {
510         case UP:
511             swap(pa[row-1][column],pa[row][column]);
512 
513             state1[row][column] = state1[row-1][column];
514             state1[row-1][column] = 0;
515             break;
516         case DOWN:
517             swap(pa[row+1][column],pa[row][column]);
518             
519             state1[row][column] = state1[row+1][column];
520             state1[row+1][column] = 0;
521             break;
522         case LEFT:
523             swap(pa[row][column-1],pa[row][column]);
524             
525             state1[row][column] = state1[row][column-1];
526             state1[row][column-1] = 0;
527             break;
528         case RIGHT:
529             swap(pa[row][column+1],pa[row][column]);
530             
531             state1[row][column] = state1[row][column+1];
532             state1[row][column+1] = 0;
533             break;
534         }
535         return state1;
536     }
537     
538     public static void gettstate(){
539         tstate=new int[size][size];
540     //    int t=Integer.parseInt(""+ni[9].charAt(8));
541         for(int i=0;i<size;i++){
542             for(int j=0;j<size;j++){
543                 char a1=ni[i*3+j+1].charAt(8);
544                 String s1=""+a1;
545                 if(a1=='9'){
546                     tstate[i][j]=0;
547                     blank_row=i;
548                     blank_column=j;
549                 }
550                 else{
551                     tstate[i][j]=Integer.parseInt(s1);
552                 }
553             }
554         }
555         
556     }
557     private static void init(int s) {
558         // TODO Auto-generated method stub
559         char a='a';
560         a+=s;
561         na=new String[15];
562         ni=new String[15];
563         for(int i=1;i<10;i++){
564             na[i]="images/"+a+i+".jpg";
565             //System.out.println(na[i]);
566         }
567         int m[]=new int[10];  //随机产生10个不同的数(1,9);
568         for(int i=1;i<10;i++){
569             int n=(int) (Math.random()*1000%9+1);
570             while(canputin(m,i,n)==false){
571                 n=(int) (Math.random()*1000%9+1);
572             }
573             m[i]=n;
574             System.out.println(n);
575             ni[n]=na[i];   //插入方式i是位置,na[n]是图片
576             //correct 方法是第一个位置为图片1.。。
577         }
578         for(int i=1;i<10;i++){
579             System.out.println(ni[i]);
580         }
581         state=new int[size][size];
582         for(int i=0;i<size;i++){
583             for(int j=0;j<size;j++){
584                 char a1=na[i*3+j+1].charAt(8);
585                 String s1=""+a1;
586                 state[i][j]=Integer.parseInt(s1);
587             }
588         }
589         state[size-1][size-1]=0;
590         for(int i=1;i<10;i++)
591         {
592             p[i].setIcon(new ImageIcon(ni[i]));
593             p[i].setText("");
594             
595         }
596         
597         
598         for(int i=1;i<9;i++){
599             p[i].setVisible(true);
600         }
601         p[9].setVisible(false);
602         now=9;
603         
604     }
605 
606     private static boolean canputin(int[] m, int s, int n) {
607         // TODO Auto-generated method stub
608         for(int i=1;i<s;i++){
609             if(m[i]==n)
610                 return false;
611         }
612         return true;
613     }
614     
615     //swap中b为setVisible(false);
616     
617     
618     public static void swap(int m,int n){
619         String ss=ni[m];
620         ni[m]=ni[n];
621         ni[n]=ss;
622     }
623     private static boolean iscorrect(){
624         for(int i=1;i<10;i++){
625             if(!na[i].equals(ni[i]))
626                 return false;
627         }
628         return true;
629     }
630     
631     public static boolean canswap(int i){
632         if(i+1==now||i-1==now||i+3==now||i-3==now)
633             return true;
634         return false;
635     }
636     
637     
638 
639     public static void swap(JLabel a,JLabel b){
640         JLabel c=new JLabel();
641         c.setIcon(a.getIcon());
642         a.setIcon(b.getIcon());
643         b.setIcon(c.getIcon());
644         a.setVisible(false);
645         b.setVisible(true);
646     }
647 
648     
649     
650     private static boolean correct(String[] nt) {
651         // TODO Auto-generated method stub
652         for(int i=1;i<10;i++){
653             if(!na[i].equals(nt[i])){
654                 return false;
655             }
656         }
657         return true;
658     }
659 
660     private static boolean canplay() {
661         // TODO Auto-generated method stub
662         for(int i=1;i<10;i++){
663             if(!ni[i].equals(na[i]))
664                 return false;
665         }
666         return true;
667     }
668 }
View Code

 只想说目前封装的实在是太烂了!

posted on 2015-03-05 23:25  loseyou  阅读(184)  评论(0)    收藏  举报