- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
本类(class)使用图形打印迷宫。该程序将运行 3 次。在第一个之后,我保存了一个 steps 数组,它计算角色跨过一个点的次数。然后我将这个数组写入一个文件。在下一次运行之前,我打开文件。我需要使用文件的内容来“学习”下一次试验不去哪里(即避免死胡同,找到最快的完成路径)。
我有一个 hasBadBranch() 方法,我想为所有具有分支(交叉路口的北、南、东和西)且“steps” > 1 的交叉路口返回 true。我正在从中获取数组索引当我在我的 solve() 方法中添加 hasBadBranch 条件时,边界和角色不再正确地穿过迷宫。如果有人发现我的逻辑有任何缺陷,我将不胜感激。谢谢。
public class Maze extends JFrame {
private static final int MAX_WIDTH = 255;
private static final int MAX_HEIGHT = 255;
private char[][] maze = new char[MAX_HEIGHT][MAX_WIDTH];
private int[][] steps = new int[MAX_HEIGHT][MAX_WIDTH];
private Random random = new Random();
private JPanel mazePanel = new JPanel();
private int width = 0;
private int height = 0;
private boolean step = false;
private boolean timerFired = false;
private Timer timer;
private final int TIMER_DELAY = 20;
private final int SPRITE_WIDTH = 25;
private final int SPRITE_HEIGHT = 25;
private BufferedImage mazeImage;
private ImageIcon ground = new ImageIcon("sprites/ground.png");
private ImageIcon wall1 = new ImageIcon("sprites/cactus.png");
private ImageIcon wall2 = new ImageIcon("sprites/rock.png");
private ImageIcon finish = new ImageIcon("sprites/well.png");
private ImageIcon south1 = new ImageIcon("sprites/cowboy-forward-1.png");
private ImageIcon south2 = new ImageIcon("sprites/cowboy-forward-2.png");
private ImageIcon north1 = new ImageIcon("sprites/cowboy-back-1.png");
private ImageIcon north2 = new ImageIcon("sprites/cowboy-back-2.png");
private ImageIcon west1 = new ImageIcon("sprites/cowboy-left-1.png");
private ImageIcon west2 = new ImageIcon("sprites/cowboy-left-2.png");
private ImageIcon east1 = new ImageIcon("sprites/cowboy-right-1.png");
private ImageIcon east2 = new ImageIcon("sprites/cowboy-right-2.png");
private long startTime;
private long currentTime;
private static final int MAX_TIME = 500000;
/**
* Constructor for class Maze. Opens a text file containing the maze, then
* attempts to solve it.
*
* @param fname String value containing the filename of the maze to open.
*/
//Notes to user:
//delete steps.txt BEFORE testing begins and AFTER third run of program
//use appropriate file paths
public Maze(String fname) throws FileNotFoundException, IOException {
openMaze(fname);
mazeImage = printMaze();
readInFile();
timer = new Timer(TIMER_DELAY, new TimerHandler()); // setup a Timer to slow the animation down.
timer.start();
addWindowListener(new WindowHandler()); // listen for window event windowClosing
setTitle("Cowboy Maze");
setSize(width * SPRITE_WIDTH + 10, height * SPRITE_HEIGHT + 30);
setVisible(true);
add(mazePanel);
setContentPane(mazePanel);
solveMaze();
}
public void readInFile() throws FileNotFoundException, IOException {
//Note to user: adjust file path accordingly
File stepsFile = new File("C:\\Users\\Ashley Bertrand\\Desktop\\Data Structures\\Lab6\\mazeStartSourceMazesGraphics\\steps.txt");
if (stepsFile.isFile()) {
Scanner scanner = new Scanner(stepsFile);
int lineCount = 0;
while (scanner.hasNextLine()) {
String[] currentLine = scanner.nextLine().trim().split("\\s+");
for (int i = 0; i < currentLine.length; i++) {
steps[lineCount][i] = Integer.parseInt(currentLine[i]);
}
lineCount++;
}
System.out.println("Contents of steps.txt:");
for (int m = 0; m < width; m++) {
for (int n = 0; n < height; n++) {
System.out.print(steps[m][n]);
}
System.out.println();
}
System.out.println();
} else {
System.out.println("Running first trial so steps.txt does not exist");
}
}
/**
* Called from the operating system. If no command line arguments are
* supplied, the method displays an error message and exits. Otherwise, a
* new instance of Maze() is created with the supplied filename from the
* command line.
*
* @param args[] Command line arguments, the first of which should be the
* filename to open.
*/
public static void main(String[] args) throws FileNotFoundException, IOException {
int runny = 1;
if (args.length > 0) {
new Maze(args[0]);
} else {
System.out.println();
System.out.println("Usage: java Maze <filename>.");
System.out.println("Maximum Maze size:" + MAX_WIDTH + " x " + MAX_HEIGHT + ".");
System.out.println();
System.exit(1);
}
}
/**
* Finds the starting location and passes it to the recursive algorithm
* solve(x, y, facing). The starting location should be the only '.' on the
* outer wall of the maze.
*/
public void solveMaze() throws FileNotFoundException {
boolean startFound = false;
if (!startFound) {
for (int i = 0; i < width; i++) { // look for the starting location on the top and bottom walls of the Maze.
if (maze[0][i] == '.') {
maze[0][i] = 'S';
steps[0][i]++;
preSolve(i, 0, "south");
startFound = true;
} else if (maze[height - 1][i] == '.') {
maze[height - 1][i] = 'S';
steps[height - 1][i]++;
preSolve(i, height - 1, "north");
startFound = true;
}
}
}
if (!startFound) {
for (int i = 0; i < height; i++) { // look for the starting location on the left and right walls of the Maze.
if (maze[i][0] == '.') {
maze[i][0] = 'S';
steps[i][0]++;
preSolve(0, i, "east");
startFound = true;
} else if (maze[i][width - 1] == '.') {
maze[i][width - 1] = 'S';
steps[i][width - 1]++;
preSolve(width - 1, i, "west");
startFound = true;
}
}
}
if (!startFound) {
System.out.println("Start not found!");
}
}
public void preSolve(int x, int y, String facing) throws FileNotFoundException {
Scanner input = new Scanner(System.in);
System.out.println("Press 1 to start");
input.nextLine();
startTime = System.currentTimeMillis();
solve(x, y, facing);
}
/**
* Recursive algorithm to solve a Maze. Places an X at locations already
* visited. This algorithm is very inefficient, it follows the right hand
* wall and will never find the end if the path leads it in a circle.
*
* @param x int value of the current X location in the Maze.
* @param y int value of the current Y location in the Maze.
* @param facing String value holding one of four cardinal directions
* determined by the current direction facing.
*/
private void solve(int x, int y, String facing) throws FileNotFoundException {
Graphics2D g2 = (Graphics2D) mazePanel.getGraphics(); //don't mess with the next
while (!timerFired) { // wait for the timer.
try {
Thread.sleep(10);
} catch (Exception e) {
}
}
timerFired = false;
currentTime = System.currentTimeMillis();
if ((currentTime - startTime) > MAX_TIME) {
closingMethod();
}
if (maze[y][x] != 'F') { //this is if it doesn't find the finish on a turn.........
g2.drawImage(mazeImage, null, 0, 0);
g2.drawImage(printGuy(facing), x * SPRITE_WIDTH, y * SPRITE_HEIGHT, null, null);
mazePanel.setSize(width * SPRITE_WIDTH + 10, height * SPRITE_HEIGHT + 30);
maze[y][x] = 'X'; // mark this spot as visited. This is how you can keep track of where you've been.
if (facing.equals("east")) {
if (maze[y + 1][x] != '#' && maze[y + 1][x] != '%' && maze[y + 1][x] != 'S' && !hasBadBranch(y+1, x)) {
steps[y + 1][x]++;
solve(x, y + 1, "south");
} else if (maze[y][x + 1] != '#' && maze[y][x + 1] != '%' && maze[y][x + 1] != 'S' && !hasBadBranch(y, x+1)) {
steps[y][x + 1]++;
solve(x + 1, y, "east");
} else {
solve(x, y, "north");
}
} else if (facing.equals("west")) {
if (maze[y - 1][x] != '#' && maze[y - 1][x] != '%' && maze[y - 1][x] != 'S' && !hasBadBranch(y-1, x)) {
steps[y - 1][x]++;
solve(x, y - 1, "north");
} else if (maze[y][x - 1] != '#' && maze[y][x - 1] != '%' && maze[y][x - 1] != 'S'&& !hasBadBranch(y, x-1)) {
steps[y][x - 1]++;
solve(x - 1, y, "west");
} else {
solve(x, y, "south");
}
} else if (facing.equals("south")) {
if (maze[y][x - 1] != '#' && maze[y][x - 1] != '%' && maze[y][x - 1] != 'S' && !hasBadBranch(y, x-1)) {
steps[y][x - 1]++;
solve(x - 1, y, "west");
} else if (maze[y + 1][x] != '#' && maze[y + 1][x] != '%' && maze[y + 1][x] != 'S' && !hasBadBranch(y+1, x)) {
steps[y + 1][x]++;
solve(x, y + 1, "south");
} else {
solve(x, y, "east");
}
} else if (facing.equals("north")) {
if (maze[y][x + 1] != '#' && maze[y][x + 1] != '%' && maze[y][x + 1] != 'S' && !hasBadBranch(y, x+1)) {
steps[y][x + 1]++;
solve(x + 1, y, "east");
} else if (maze[y - 1][x] != '#' && maze[y - 1][x] != '%' && maze[y - 1][x] != 'S' && !hasBadBranch(y-1, x)) {
steps[y - 1][x]++;
solve(x, y - 1, "north");
} else {
solve(x, y, "west");
}
}
} else {
writeToFile();
System.out.println("Found the finish!");
currentTime = System.currentTimeMillis();
long endTime = currentTime - startTime;
long finalTime = endTime / 1000;
System.out.println("Final Time = " + finalTime);
}
}
public boolean hasBadBranch(int y, int x) {
//9999 will be used to tell character not to take that branch
if (steps[y][x] > 1) {
if (steps[y + 1][x] > 1) {
steps[y + 1][x] = 9999;
return true; //south
}
if (steps[y - 1][x] > 1) {
steps[y - 1][x] = 9999;
return true; //north
}
if (steps[y][x + 1] > 1) {
steps[y][x + 1] = 9999;
return true; //east
}
if (steps[y][x - 1] > 1) {
steps[y][x - 1] = 9999;
return true; //west
}
}
return false;
}
/**
* Opens a text file containing a maze and stores the data in the 2D char
* array maze[][].
*
* @param fname String value containing the file name of the maze to open.
*/
public void openMaze(String fname) {
String in = "";
int i = 0;
try {
Scanner sc = new Scanner(new File(fname));
while (sc.hasNext()) {
in = sc.nextLine();
in = trimWhitespace(in);
if (in.length() <= MAX_WIDTH && i < MAX_HEIGHT) {
for (int j = 0; j < in.length(); j++) {
if (in.charAt(j) == '#') { // if this spot is a wall, randomize the wall peice to display
if (random.nextInt(2) == 0) {
maze[i][j] = '#';
} else {
maze[i][j] = '%';
}
} else {
maze[i][j] = in.charAt(j);
}
}
} else {
System.out.println("Maximum maze size exceeded: (" + MAX_WIDTH + " x " + MAX_HEIGHT + ")!");
System.exit(1);
}
i++;
}
width = in.length();
height = i;
System.out.println("(" + width + " x " + height + ") maze opened.");
System.out.println();
sc.close();
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e);
}
}
/**
* Removes white space from the supplied string and returns the trimmed
* String.
*
* @param s String value to strip white space from.
* @return String stripped of white space.
*/
public String trimWhitespace(String s) {
String newString = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != ' ') {
newString += s.charAt(i);
}
}
return newString;
}
/**
* Returns the sprite facing the direction supplied.
*
* @param facing String value containing 1 of 4 cardinal directions to make
* the sprite face.
* @return Image of the sprite facing the proper direction.
*/
private Image printGuy(String facing) {
if (facing.equals("south")) { // draw sprite facing south
if (step) {
step = false;
return south1.getImage();
} else {
step = true;
return south2.getImage();
}
} else if (facing.equals("north")) { // draw sprite facing north
if (step) {
step = false;
return north1.getImage();
} else {
step = true;
return north2.getImage();
}
} else if (facing.equals("east")) { // draw sprite facing east
if (step) {
step = false;
return east1.getImage();
} else {
step = true;
return east2.getImage();
}
} else if (facing.equals("west")) { // draw sprite facing west
if (step) {
step = false;
return west1.getImage();
} else {
step = true;
return west2.getImage();
}
}
return null;
}
/**
* Prints the Maze using sprites.
*
* @return BufferedImage rendition of the maze.
*/
public BufferedImage printMaze() {
BufferedImage mi = new BufferedImage(width * SPRITE_WIDTH, height * SPRITE_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics g2 = mi.createGraphics();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (maze[i][j] == '#') { // draw wall
g2.drawImage(wall1.getImage(), j * SPRITE_WIDTH, i * SPRITE_HEIGHT, null, null);
} else if (maze[i][j] == '%') { // draw wall
g2.drawImage(wall2.getImage(), j * SPRITE_WIDTH, i * SPRITE_HEIGHT, null, null);
} else if (maze[i][j] == '.' || maze[i][j] == 'X') { // draw ground
g2.drawImage(ground.getImage(), j * SPRITE_WIDTH, i * SPRITE_HEIGHT, null, null);
} else if (maze[i][j] == 'F') { // draw finish
g2.drawImage(finish.getImage(), j * SPRITE_WIDTH, i * SPRITE_HEIGHT, null, null);
}
}
}
return mi;
}
public void writeToFile() throws FileNotFoundException {
PrintWriter printWriter = new PrintWriter("steps.txt");
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
printWriter.print(steps[i][j] + " ");
}
printWriter.println();
}
printWriter.close();
}
public void closingMethod() {
long endTime = currentTime - startTime;
long finalTime = endTime / 100;
System.exit(0);
}
private class TimerHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
timerFired = true;
}
}
private class WindowHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
removeAll();
closingMethod();
System.exit(0);
}
}
}
最佳答案
本质上,您所做的是使用具有固定探索规则(右手)的 DFS 来解决迷宫问题。您应该保存的信息是您踩在正方形上的次数。当您遇到死胡同时,您将返回十字路口尝试另一条分支。
所以在第二次求解时,当你找到分数 > 1 的交集时,你应该修改探索规则以避免分支分数 > 1(1 意味着你永远不必回来 == 以前的解决方案路径,2 (或更多)意味着你必须在死胡同(或几个)之后回来)。希望这是有道理的。
关于java - 解决迷宫的最短路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31576546/
假设您已经用 Python 编写了一个 m x n 矩阵。矩阵之外的值是不可能的。假设你是在矩阵中移动的东西(就像在迷宫中)并且你不能跨越边界。当您在迷宫中移动时,您会不断考虑您的选择,您可以走哪条路
我正在实现随机鼠标算法来探索迷宫。一段时间后,算法陷入无限循环。我调试了一下,它似乎在一条 channel 之间来回卡住了。 请看一下我的算法实现。 这是我的代码:方向是相对于机器人的。 public
我有一个用 java 编写的工作 ascii 迷宫解算器,使用 char 数组,它将正确路径的每个位置设置为前一个位置 + 1。我使用以下代码来从中获取正确路径,但是它仅适用于垂直运动。任何有关此事的
我有一个生成随机迷宫的程序。迷宫中会显示一个红点,并且迷宫中的每个方 block 都会闪烁红点。迷宫中的所有 block 都是 == 1,如果红点穿过该 block ,它就会递增++。红点朝最小数字的
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我创建了一个从文本文件上传的迷宫,该迷宫当前在运行时完全可见且功能正常。但是,我只想将播放的路线显示为可见,因此仅使起始位置和周围的墙壁/地板在开始时可见。有人知道该怎么做吗? 以下是 Board 类
起初我觉得这很容易,但是当我开始做的时候,我不知道如何继续下去了。我的想法是使用面板,然后绘制粗线,但是绘制墙壁并使我的角色不会超出这些墙壁的正确方法是什么?我无法想象我怎么可能做到这一点。这是一个迷
我从一个文件中得到了一个迷宫,我尝试使用一个程序编写一个类Exercise4,该程序将这样的迷宫文件读入二维 boolean 数组。然后在控制台上显示该数组,每一行一行。使用空白符号和 # 符号表示数
如何通过光栅图像数据找到非线性路径?例如,最低成本算法?起点和终点已知,并给出如下: 起点 = (0,0) 终点 = (12,-5) 例如,通过(灰度)光栅图像提取蜿蜒河流的近似路径。 # fake
在我的游戏中,玩家在迷宫中导航。我不知道如何与墙壁进行正确的碰撞检测。停留在某个区域很容易进行碰撞检测: if (x > rightWallX - playerWidth) x = rightWall
基本上,我一直在按照 Java 教程制作一个基本的迷宫游戏,其中我生成一个随机迷宫,并将其保存到文件中,然后使用 Jpanel 将其打印出来,但是在编译时我不断收到此错误。 Exception in
注意:这是 MSVC,C++17 问题。 免责声明:我知道有人尝试过,是的,我试图找到相关的 SO 答案。 我可以编码 UDL , 以实现将数字文字转换为 std::array,在编译时: /
我目前正在开发一个随机迷宫生成器,它将迷宫存储在一个名为 grid 的二维数组中。这将在稍后用于生成一个真正的 3D 迷宫,用户随后可以穿过该迷宫。 在做了一些研究之后,我尝试使用递归除法算法创建这个
题目地址:https://leetcode-cn.com/problems/the-maze-ii/ 题目描述 There is a ball in a maze with empty space
我正在尝试用 python 编写脚本来解决一种具有多个起点和多个终点的迷宫。正确的路径是从起点沿着直线前进。 例如一个有 4 条路径的迷宫: 起初我想使用左手/右手规则,但由于迷宫的特点,它没有太大意
我正在尝试在 opengl 中创建一个简单的 3D 迷宫。我最初的想法是有一个立方体网格,每个立方体的一些面是透明的(用于走廊)。但是,我在想出一种有效执行此操作的方法时遇到了一些麻烦。我不想为我的迷
我的 DFS 算法在解中缺少节点时遇到问题(检查图片)。每次我的算法遇到死胡同时都会发生这种情况:节点从堆栈中弹出并返回,直到找到可用的移动,并且再也不会重新包含在内。有没有一种简单的方法可以在不重新
所以我正在用 Java 构建 pacman 游戏来自学游戏编程。 我有一个基本的游戏窗口,其中绘制了吃 bean Sprite 和幽灵 Sprite ,吃 bean 使用箭头键移动,不会超出窗口的墙壁
我使用的代码只是取自一个示例,它确实为我的场景建了一堵墙: /** This loop builds a wall out of individual bricks. */ public vo
我正在从事一个包含这些条件的学校元素: 只使用 JS、HTML5 和 CSS 制作迷宫。 在 Angular 色周围制作 torch 效果。你不能穿墙照明。 我开始使用 Canvas 制作这款游戏
我是一名优秀的程序员,十分优秀!