用java解决骑士巡游问题

 

AutoRun.java

/*** * 解决骑士巡游问题更具创意的方法之一是由J. C. Warnsdorff在1823年提出的。其规则是:骑士总是移向具有最少出口且没有到达过的方格之一。 * @author Administrator * */ public class AutoRun { //int[][] map = new int[8][8];//二维数组保存走过的地图数据, //”never pass”表示没走过,”pass”表示走过 int step = 1;//走过了多少个没有重复的格子 int x = 7;//象开始时的x坐标 int y = 0;//象开始时的y坐标 public static void main(String[] args) { AutoRun run = new AutoRun(); } public AutoRun(){ Node root = new Node(null ,0,0);//初始化根节点 Node childNode = run(root); int[][] map = childNode.getMap(); for (int i = 0; i < 8; i++) {//打印步骤 for (int j = 0; j < 8; j++) { System.out.print( (map[i][j] + ” “).substring(0, 4)); } System.out.println(); } } public Node run(Node node){ if (node.getStep()==64) //如果走完了64个格子返回最后的节点,这是递归的退出条件 return node; node.canGo(node);//生成子节点 List<Node> childNodes = node.getChildNodes(); if (childNodes == null)//没子节点的话返回null return null; for (int i = 0; i < childNodes.size(); i++) {//递归调用run Node currentNode = run(childNodes.get(i)); return currentNode; } return null; } }

 

Node.java

public class Node { private int x;//节点的x坐标 private int y;//节点的y坐标 private int step;//走到了第几步 private List<Node> childNodes = new ArrayList<Node>();// 子节点 private Node fatherNode = null;//父节点 private int[][] map = new int[8][8];//走过的地图 /*** * Node的构造函数,传入它的父节点和要走的,x、y的坐标 * * @param x 要走的x坐标 * @param y 要走的y坐标 * */ public Node(Node fatherNode, int x, int y) { this.fatherNode = fatherNode; this.x = x; this.y = y; if (fatherNode != null) { this.step = this.fatherNode.step + 1;//增加步数 for (int i = 0; i < fatherNode.map.length; i++)//把父节点的地图传给子节点 for (int j = 0; j < fatherNode.map[i].length; j++) this.map[i][j] = fatherNode.map[i][j]; } else this.step = 1;//如果是跟节点的话步数从1开始 this.map[x][y] = this.step;//把node所在的地图位置的值设置为当前的步数 /*测试步骤 for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { System.out.print( (this.map[i][j] + ” “).substring(0, 4)); } System.out.println(); } System.out.println(); System.out.println(); System.out.println(); */ } public Node() { } /*** * 根据输入的node节点,生成它能走的子节点,并根据子节点的子节点个数从小到大排序 * * @param node 传入的节点 */ public void canGo(Node node) { int x = node.getX(); int y = node.getY(); if (checkOrient(x,y,1)) { Node data = new Node(node, x – 2, y + 1); node.AddChildNode(data); } if (checkOrient(x,y,2)) { Node data = new Node(node, x – 1, y + 2); node.AddChildNode(data); } if (checkOrient(x,y,3)) { Node data = new Node(node, x + 1, y + 2); node.AddChildNode(data); } if (checkOrient(x,y,4)) { Node data = new Node(node, x + 2, y + 1); node.AddChildNode(data); } if (checkOrient(x,y,5)) { Node data = new Node(node, x + 2, y – 1); node.AddChildNode(data); } if (checkOrient(x,y,6)) { Node data = new Node(node, x + 1, y – 2); node.AddChildNode(data); } if (checkOrient(x,y,7)) { Node data = new Node(node, x – 1, y – 2); node.AddChildNode(data); } if (checkOrient(x,y,8)) { Node data = new Node(node, x – 2, y – 1); node.AddChildNode(data); } for (int i = 0; i < childNodes.size(); i++) for (int j = 0; j < childNodes.size() – i – 1; j++) if (childNodes.get(j).getChildNodeCount() > childNodes.get(j + 1).getChildNodeCount()) { Collections.swap(childNodes, j, j + 1); } } /*** * 检查这个方向是否可行 * @param x x坐标 * @param y y坐标 * @param orient 方向参数,1-8,8个方向 * @return */ public boolean checkOrient(int x,int y,int orient){ switch (orient){ case 1: return checkBound(x – 2, y + 1) && !checkHavePass(x – 2, y + 1); case 2: return checkBound(x – 1, y + 2) && !checkHavePass(x – 1, y + 2); case 3: return checkBound(x + 1, y + 2) && !checkHavePass(x + 1, y + 2); case 4: return checkBound(x + 2, y + 1) && !checkHavePass(x + 2, y + 1); case 5: return checkBound(x + 2, y – 1) && !checkHavePass(x + 2, y – 1); case 6: return checkBound(x + 1, y – 2) && !checkHavePass(x + 1, y – 2); case 7: return checkBound(x – 1, y – 2) && !checkHavePass(x – 1, y – 2); case 8: return checkBound(x – 2, y – 1) && !checkHavePass(x – 2, y – 1); } return false; } /*** * 统计该节点的子节点个数 * @return 子节点个数 */ public int getChildNodeCount() { int count = 0; if (checkOrient(x,y,1)) count++; if (checkOrient(x,y,2)) count++; if (checkOrient(x,y,3)) count++; if (checkOrient(x,y,4)) count++; if (checkOrient(x,y,5)) count++; if (checkOrient(x,y,6)) count++; if (checkOrient(x,y,7)) count++; if (checkOrient(x,y,8)) count++; return count; } /*** * 检查是否之前到过这个格 * * @param x 象的x坐标 * @param y 象的y坐标 * @return */ private boolean checkHavePass(int x, int y) { if (map[x][y] != 0) { return true; } return false; } /*** * 检查是否越界,即坐标是否在0-7的范围内 * * @param x 象的x坐标 * @param y 象的y坐标 * @return 象是否可行 */ private boolean checkBound(int x, int y) { if (x >= 0 && x < 8 && y >= 0 && y < 8) return true; return false; } /*** * 增加子节点 * * @param stepData */ public void AddChildNode(Node node) { childNodes.add(node); } public List<Node> getChildNodes() { return childNodes; } public void setChildNodes(List<Node> childNodes) { this.childNodes = childNodes; } public Node getFatherNode() { return fatherNode; } public void setFatherNode(Node fatherNode) { this.fatherNode = fatherNode; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getStep() { return step; } public void setStep(int step) { this.step = step; } public int[][] getMap() { return map; } public void setMap(int[][] map) { this.map = map; } }

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/laigood/article/details/6024289
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞