马踏棋盘游戏(骑士周游问题)
马踏棋盘游戏链接
分析:
在8×8的棋盘中,“马”走“日”字走遍整个棋盘。
如图白色初始化位置,黄色点当前马可以走的位置,以此类推。
代码实现:
Java语言实现
import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;
/**
* 马踏棋盘
* @author mw
*/
public class HorseChessBoard {
// 二维数组表示棋盘
private static int X = 6; // 列 col
private static int Y = 6; // 行 row
private static int[][] chessBoard = new int[Y][X];
private static boolean[] visited = new boolean[X*Y]; //记录某个点是否走过
private static boolean finished = false; // 记录马是否遍历完数组
public static void traversalChessBoard(int[][] chessBoard,int row,int col,int step){
// 先把当前这个点是第几步记录下来
chessBoard[row][col] = step;
// 标记当前点已访问
visited[row*X+col] = true;
// 获取当前这个点可以走的其他点
ArrayList<Point> ps = next(new Point(col, row));
// 使用贪心算法优化
sort(ps);
while (!ps.isEmpty()){
// 取出一个点
Point p = ps.remove(0);
// 判断是否走过 没有走过 递归遍历
if(!visited[p.y * X + p.x]){
// 递归遍历
traversalChessBoard(chessBoard,p.y,p.x,step+1);
}
}
// 当退出while循环后,看是否遍历成功,如果没有成功,重置相应的值,然后进行回溯
if(step < X*Y && !finished){
chessBoard[row][col] = 0;
visited[row * X + col] = false;
}else {
finished = true;
}
}
// 把马下一步可能走的位置 按从小到大排序
public static void sort(ArrayList<Point> list){
list.sort(new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
return next(o1).size() - next(o2).size();
}
});
}
// 获取当前马所在位置 能走的下一步所有位置
public static ArrayList<Point> next(Point curPoint){
// 创建ArrayList
ArrayList<Point> ps = new ArrayList<>();
// 创建一个点 准备放入 ps中
Point p1 = new Point();
// 判断5这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x-2)>=0 && (p1.y = curPoint.y-1 )>=0) {
ps.add(new Point(p1));
}
// 判断6这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x-1)>=0 && (p1.y = curPoint.y-2 )>=0) {
ps.add(new Point(p1));
}
// 判断7这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x + 1)< X && (p1.y = curPoint.y-2 )>=0) {
ps.add(new Point(p1));
}
// 判断8这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x + 2)<X && (p1.y = curPoint.y-1 )>=0) {
ps.add(new Point(p1));
}
// 判断1这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x + 2)<X && (p1.y = curPoint.y+1 )<Y) {
ps.add(new Point(p1));
}
// 判断2这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x + 1)<X && (p1.y = curPoint.y+2 )<Y) {
ps.add(new Point(p1));
}
// 判断3这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x - 1)>=0 && (p1.y = curPoint.y+2 )<Y) {
ps.add(new Point(p1));
}
// 判断4这个位置是否可以走 如果可以 则放入ps
if((p1.x = curPoint.x - 2)>=0 && (p1.y = curPoint.y+1 )<Y) {
ps.add(new Point(p1));
}
return ps;
}
}
测试
这里游戏用6×6棋盘
初始化马的位置[1,6],将坐标放入代码中
public static void main(String[] args) {
int row = 1;
int col = 6;
System.out.println("开始");
long start = System.currentTimeMillis();
traversalChessBoard(chessBoard,row-1,col-1,1);
long end = System.currentTimeMillis();
System.out.println("结束消耗时间:"+(end - start)+"毫秒");
System.out.println("游戏棋盘路径");
for (int[] rows : chessBoard){
for (int step : rows){
System.out.print(step + "\t");
}
System.out.println();
}
}
运行结果
开始
结束消耗时间:5毫秒
游戏棋盘路径
12 7 32 21 10 1
33 20 11 8 35 22
6 13 34 31 2 9
19 30 17 36 23 26
14 5 28 25 16 3
29 18 15 4 27 24
在游戏里按照结果进行验证
马踏棋盘游戏链接