递归-迷宫最短路径问题

1.这是迷宫最短路径的代码以及效果图,为了备忘,mark一下
效果图:
在这里插入图片描述
代码:

package recursiontest;

import java.util.ArrayList;
import java.util.List;

public class MiGong2 {
	public static void main(String[] args) {
		MiGongCore mi = new MiGongCore();
		mi.play();
	}
}

/**
 * 
 * @Description 迷宫,求出最短的路径并且输出所有的地图
 * @author jiama
 * @Date 2021年9月23日
 */
class MiGongCore {
	int count = 0;// 数路径走过格数
	int count1 = 0;// 数方案个数
	int mapCount = 0;//迷宫图像数

	public void play() {
		int[][] map = new int[8][7];

		for (int i = 0; i < 8; i++) {
			map[i][0] = 1;
			map[i][6] = 1;
		}
		for (int i = 0; i < 7; i++) {
			map[0][i] = 1;
			map[7][i] = 1;
		}
		map[3][1] = 1;
		map[3][2] = 1;

		// 设置一个变动的迷宫
		int[][] temp = copyMap(map);

		// 设置一个开始的数组用于放执行策略标记为上下左右
		int[] policy = new int[] { 1, 2, 3, 4 };

		// 初始化min值
		change(policy, temp, 1, 1);
		int min = count;

		// 添加所有的polices
		List<int[]> list = policis(policy);

		// 执行计算路径,并且把路径地图保存为res
		int[][] restemp = null;
		List<int[][]> listRes = new ArrayList<>();
		boolean resb = false;
		for (int[] p : list) {
			resb = change(p, temp, 1, 1);
			if (resb) {
				if (min > count) {
					min = count;
				}
			}
			temp = copyMap(map);
			count = 0;
		}
		for (int[] p : list) {
			resb = change(p, temp, 1, 1);
			if (resb) {
				if (min == count) {
					if (!isDuplicatedMap(temp, listRes)) {
						listRes.add(temp);
					}
				}
			}
			temp = copyMap(map);
			count = 0;
		}

		for (int[][] res : listRes) {

			// 输出地图
			mapCount++;
			System.out.println("输出地图" + mapCount);
			for (int i = 0; i < res.length; i++) {
				for (int j = 0; j < res[i].length; j++) {
					System.out.print(res[i][j] + " ");
				}
				System.out.println();
			}
			System.out.printf("最短路径的步数:%d\n\n", min);
		}
	}

	/**
	 * 
	 * @Description 玩游戏,如果走不通的话就设置为3
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param policy 游戏策略((下-右-上-左)等)
	 * @param map    游戏地图
	 * @param x      横坐标
	 * @param y      纵坐标
	 * @return
	 */
	public boolean change(int[] policy, int[][] map, int x, int y) {
		if (map[6][5] == 2) {
			return true;
		}

		if (map[x][y] == 0) {
			count++;
			map[x][y] = 2;
			for (int i = 0; i < policy.length; i++) {
				if (policy[i] == 1) {
					if (up(policy, map, x, y) == true) {
						return true;
					}
				} else if (policy[i] == 2) {
					if (down(policy, map, x, y) == true) {
						return true;
					}
				} else if (policy[i] == 3) {
					if (left(policy, map, x, y) == true) {
						return true;
					}
				} else if (policy[i] == 4) {
					if (right(policy, map, x, y) == true) {
						return true;
					}
				} else {
					throw new RuntimeException("输入错策略,检查策略情况");
				}
			}
			map[x][y] = 3;
			return false;

		} else {
			// 如果map坐标的值为1、2、3,停止寻找
			return false;
		}
	}

	/**
	 * 
	 * @Description 向上
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param policy
	 * @param map
	 * @param x
	 * @param y
	 * @return
	 */
	public boolean up(int[] policy, int[][] map, int x, int y) {
		return change(policy, map, x - 1, y);
	}

	/**
	 * 
	 * @Description 向下
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param policy
	 * @param map
	 * @param x
	 * @param y
	 * @return
	 */
	public boolean down(int[] policy, int[][] map, int x, int y) {
		return change(policy, map, x + 1, y);
	}

	/**
	 * 
	 * @Description 向左
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param policy
	 * @param map
	 * @param x
	 * @param y
	 * @return
	 */
	public boolean left(int[] policy, int[][] map, int x, int y) {
		return change(policy, map, x, y - 1);
	}

	/**
	 * 
	 * @Description 向右
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param policy
	 * @param map
	 * @param x
	 * @param y
	 * @return
	 */
	public boolean right(int[] policy, int[][] map, int x, int y) {
		return change(policy, map, x, y + 1);
	}

	/**
	 * 
	 * @Description 返回一个策略的集合
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param policy
	 * @return
	 */
	public List<int[]> policis(int[] policy) {
		AllArray allArray = new AllArray();
		return allArray.array(policy);
	}

	/**
	 * 
	 * @Description 复制地图
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param map
	 * @return
	 */
	public int[][] copyMap(int[][] map) {
		int[][] temp1 = new int[map.length][];
		for (int i = 0; i < temp1.length; i++) {
			temp1[i] = new int[map[i].length];
			for (int j = 0; j < temp1[i].length; j++) {
				temp1[i][j] = map[i][j];
			}
		}
		return temp1;
	}

	/**
	 * 
	 * @Description 判断在集合中是否存在相同的地图
	 * @author jiama
	 * @Date 2021年9月23日
	 * @param newMap
	 * @param list
	 * @return
	 */
	public boolean isDuplicatedMap(int[][] newMap, List<int[][]> list) {
		if (list.isEmpty()) {
			return false;
		}
		for (int[][] preMap : list) {
			int count = 0;// 标准
			int count1 = 0;// 测试
			for (int i = 0; i < newMap.length; i++) {
				for (int j = 0; j < newMap[i].length; j++) {
					if (newMap[i][j] == 2) {
						count++;
					}

				}
			}
			for (int i = 0; i < newMap.length; i++) {
				for (int j = 0; j < newMap[i].length; j++) {
					if (newMap[i][j] == 2) {

						if (newMap[i][j] == preMap[i][j]) {
							count1++;
						}
					}

				}
			}
			if (count == count1) {
				return true;
			}
		}
		return false;
	}
}

class AllArray {

	List<int[]> list = new ArrayList<>();
	int[] newArr = new int[4];

	public List<int[]> array(int[] arr) {
		boolean[] newb = new boolean[arr.length];
		return method(newb, arr, -1);
	}

	private List<int[]> method(boolean[] newb, int[] arr, int count) {
		count++;
		if (count == 4) {
			return list;
		}
		for (int i = 0; i < arr.length; i++) {
			if (!newb[i]) {
				newArr[count] = arr[i];
				newb[i] = true;
				List<int[]> list = method(newb, arr, count);
				newb[i] = false;
				if (isDuplicated(list, newArr)) {
					continue;
				}
				list.add(copyArray(newArr));
			}
		}
		return list;
	}

	public int[] copyArray(int[] arr) {
		int[] copArr = new int[arr.length];
		for (int i = 0; i < copArr.length; i++) {
			copArr[i] = arr[i];
		}
		return copArr;
	}

	public boolean isDuplicated(List<int[]> list, int[] newArr) {

		if (list.size() == 0) {
			return false;
		}
		int[] arr = list.get(list.size() - 1);
		int count = 0;
		for (int i = 0; i < newArr.length; i++) {
			if (arr[i] == newArr[i]) {
				count++;
			}
		}
		if (count == 4) {
			return true;
		}
		return false;
	}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值