1 /*
2 * 馬踏棋盤問題:(貪婪法求解)
3 * 棋盤有64個位置,“日”字走法,剛好走滿整個棋盤
4 */
5
6 //下一個走法的方向類
7 class Direction{
8 int x;
9 int y;
10 int wayOutNum;
11 }
12
13 public class Hores_chessboard_1 {
14 static final int[] dx = { -2, -1, 1, 2, 2, 1, -1, -2 }; // x方向的增量
15 static final int[] dy = { 1, 2, 2, 1, -1, -2, -2, -1 }; // y方向的增量
16 static final int N = 8;
17 static int[][] chessboard = new int[N][N]; // 棋盤
18
19 /**
20 *
21 * @param nami
22 * @param x,y爲棋子的位置
23 * @return 如果棋子的位置不合法,則返回一個大於8的數。
24 * 否則返回棋子的下個出路的個數
25 */
26 static int wayOut(int x, int y){
27 int count = 0;
28 int tx, ty, i;
29 //判斷是否超出棋盤邊界,該位置是否已經下過
30 if(x<0 || x>7 || y<0 || y>7 || chessboard[x][y]!=0){
31 return 9;
32 }
33 for(i=0; i<N; i++){
34 tx = x+dx[i];
35 ty = y+dy[i];
36 //如果棋子的下個出路可行,則出路數自加一次
37 if(tx>-1 && tx<8 && ty>-1 && ty<8 && chessboard[tx][ty]==0)
38 count++;
39 }
40 return count;
41 }
42
43 /**
44 * 按照棋子的下個出路的個數從低到高排序
45 * @param next 棋子的八個位置的數組
46 */
47 static void sort(Direction[] next){
48 int i, j, index;
49 Direction temp = null;
50 //這裏用的選擇排序
51 for(i=0; i<N; i++){
52 index = i;
53 for(j=i+1; j<N; j++){
54 if(next[index].wayOutNum > next[j].wayOutNum)
55 index = j;
56 }
57 if(i != index){
58 temp = next[i];
59 next[i] = next[index];
60 next[index] = temp;
61 }
62 }
63 }
64
65 static void Move(int x, int y, int step){
66 int i, j;
67 int tx, ty;
68 //如果step==64,則說明每個棋格都走到了,現在只需要打印結果就完了
69 if(step == N*N){
70 for(i=0; i<N; i++){
71 for(j=0; j<N; j++){
72 System.out.printf("%3d", chessboard[i][j]);
73 }
74 System.out.println();
75 }
76 System.exit(0);
77 }
78
79 //下一個棋子的N個位置的數組
80 Direction[] next = new Direction[N];
81
82 for(i=0; i<N; i++){
83 Direction temp = new Direction();
84 temp.x = x+dx[i];
85 temp.y = y+dy[i];
86 next[i] = temp;
87 //循環得到下個棋子N處位置的下個出路的個數
88 next[i].wayOutNum = wayOut(temp.x, temp.y);
89 }
90
91 //配合貪婪算法,按下個棋子的下個出路數排序後,next[0]就是下個出路數最少的那個
92 sort(next);
93
94 for(i=0; i<N; i++){
95 tx = next[i].x;
96 ty = next[i].y;
97 chessboard[tx][ty] = step;
98 Move(tx, ty, step+1);
99 /*如果上面Move()往下一步走不通,則回溯到這裏
100 重置chessboard[tx][ty]爲0,接着i++,又循環...... */
101 chessboard[tx][ty] = 0;
102 }
103 }
104
105 public static void main(String[] args) {
106 int i, j;
107 //初始化棋盤
108 for(i=0; i<8; i++){
109 for(j=0; j<8; j++){
110 chessboard[i][j] = 0;
111 }
112 }
113 System.out.println("請輸入棋子開始位置(0-7):");
114 Scanner sc = new Scanner(System.in);
115 int x = sc.nextInt();
116 int y = sc.nextInt();
117 //第一步不用比較,賦值第一步
118 chessboard[x][y] = 1;
119 Move(x, y, 2);
120 }
121 }