I am working on a method to recursively solve made up of cells.
The method just quite isn't working. Any suggestions would be appreciated.
Parameters: srow = starting x value. scol = staring y value erow = end
x value. ecol = end y value. L = Linked List of solved path points
Code:
private InputGraphicMaze2 maze;
private int R, C;
//code added by me
private String[] [] cell; //an array to keep track of cells that are proven dead ends.
public YourMazeWithPath2()
{
// an R rows x C columns maze
maze = new InputGraphicMaze2();
R=maze.Rows(); C=maze.Cols();
//code added by me
cell = new String[R+2][C+2];
for (int i=0; i<R+2; i++) {
for (int k=0; k<C+2; k++) {
cell[i][k] = "no";
}
}
// Path holds the cells of the path
LinkedList<Point> Path = new LinkedList<Point>();
// Create the path
CreatePath(maze, 1, 1, R, C, Path);
// show the path in the maze
maze.showPath(Path);
}
private void setDead(int x, int y) {
cell[x][y] = "dead";
}
private void setVisited(int x, int y) {
cell[x][y] = "visited";
}
public boolean CreatePath(InputGraphicMaze2 maze,
int srow, int scol, int erow, int ecol, LinkedList<Point> L)
{
int x = srow;
int y = scol;
Point p = new Point(x, y);
if ((x<1) || (y<1) || (x>R) || (y>C)) {
return false; //cell is out of bounds
}
else if ((x==R) && (y==C)) {
return true; // cell is the exit cell
}
else {
if ((maze.can_go(x, y, 'U')) && (x!=1) && (!cell[x-1][y].equals("dead")) && (!cell[x-1][y].equals("visited"))) {
L.addLast(p);
setVisited(x,y);
CreatePath(maze, x-1, y, R, C, L);
return false;
}
else if ((maze.can_go(x, y, 'R')) && (y!=C) && (!cell[x][y+1].equals("dead")) && (!cell[x][y+1].equals("visited"))) {
L.addLast(p);
setVisited(x, y);
CreatePath(maze, x, y+1, R, C, L);
return false;
}
else if ((maze.can_go(x, y, 'D')) && (x!=R) && (!cell[x+1][y].equals("dead")) && (!cell[x+1][y].equals("visited"))) {
L.addLast(p);
setVisited(x, y);
CreatePath(maze, x+1, y, R, C, L);
return false;
}
else if ((maze.can_go(x, y, 'L')) && (y!=1) && (!cell[x][y-1].equals("dead")) && (!cell[x][y-1].equals("visited"))) {
L.addLast(p);
setVisited(x, y);
CreatePath(maze, x, y-1, R, C, L);
return false;
}
else {
if ((maze.can_go(x, y, 'U')) && (x!=1) && (cell[x][y-1].equals("visited"))) {
setDead(x, y);
if (L.contains(p))
L.remove(p);
CreatePath(maze, x-1, y, R, C, L);
return false;
}
else if ((maze.can_go(x, y, 'R')) && (y!=C) && (cell[x][y+1].equals("visited"))) {
setDead(x, y);
if (L.contains(p))
L.remove(p);
CreatePath(maze, x, y+1, R, C, L);
return false;
}
else if ((maze.can_go(x, y, 'D')) && (x!=R) && (cell[x+1][y].equals("visited"))) {
setDead(x, y);
if (L.contains(p))
L.remove(p);
CreatePath(maze, x+1, y, R, C, L);
return false;
}
else if ((maze.can_go(x, y, 'D')) && (y!=1) && (cell[x][y-1].equals("visited"))) {
setDead(x, y);
if (L.contains(p))
L.remove(p);
CreatePath(maze, x, y-1, R, C, L);
return false;
}
else {
return false;
}
}
}
}
From Another similar thread, just for seeing the problem in a less verbose language, take a look at
this tiny JS recursive maze solver made by user #Sergey Rudenko
var map = [
[1,1,0,0,0,0,0,0],
[0,1,1,0,0,0,0,0],
[1,1,1,0,0,0,0,0],
[1,0,0,1,1,1,1,1],
[1,1,0,0,1,0,0,1],
[0,1,1,0,1,0,0,1],
[1,1,1,0,1,0,0,1],
[1,0,0,0,1,1,1,1]
]
var goalx = 7;
var goaly = 7;
function findpath(x,y){
// illegal move check
if (x < 0 || x > (map[0].length -1) || y < 0 || y > (map.length - 1)) return false; //if it is outside of map
if (map[y][x]==0) return false; //it is not open
// end move check
if (x== goalx && y== goaly){
console.log('Reached goal at: ' + x + ':' + y);
return true; // if it is the goal (exit point)
}
if(map[y][x] == 9 || map[y][x] == 8)
return false;
console.log('Im here at: ' + x + ':' + y);
map[y][x]=9; //here marking x,y position as part of solution path outlined by "9"
if(findpath(x+1,y))
return true;
if(findpath(x,y+1))
return true;
if(findpath(x,y-1))
return true;
if(findpath(x-1,y))
return true;
return false;
};
findpath(0, 0);
JSfiddle
Yep. Its tiny, simplistic, naive and lacking but heck, its recursive and it works!
Besides, you see clearly common parts to many maze traversing algorithm.
For a more serious reading, this page has excellent in-depth-but-not-scientific-paper tutorials about many game related algorithms.
There are some pertinent questions to answer when shopping for an algorithm:
Need any solution?
Need every solution?
Need the fastest?
Whats the topography of the maze? A grid? A graph?
Want to implement movement cost in the future?
Want to implement heuristics to choose best route?
Finally, if you didn't come across it yet, check a* algorithm. Very popular.
Have fun!
This is a basic graph-traversal problem. I suggest you use dfs as opposed to bfs. Pretty much any textbook on algorithms and datastructure will have the implementation.
You simply have to tweak the recursive part to stop searching once you have reached the goal. On the other hand, if you are looking for all paths to the goal, just do all-to-all path and then go from there. For hints, you can look up Bellman–Ford or Dijkstra's algorithm (http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm). Again, any good textbook with a chapter on graphs.
Related
So I'm currently learning Java, and i struggle a lot to get my Code working.
I made a "Fun" Code in which some circles are popping up and it calculates how many of them are on the Upper Side of the Screen. (I know, some silly code.)
I'm coding it in the "Processing" Environment, Language is Java.
Here's my main File:
Circle[] circles = new Circle[50];
int index = 0;
boolean finished = false;
void setup() {
size(900, 900);
background(0);
for(int i = 0; i < circles.length; i++) {
circles[i] = new Circle();
}
if(finished = true) {
}
}
void draw() {
if(index < circles.length) {
circles[index].show(circles);
index++;
} else {
finished = true;
}
}
void count(Circle[] arr) {
int n = 0;
for(Circle c : arr) {
if(c.getY() > height / 2) {
n++;
}
}
println(n);
}
And here's the "Problem" Circle class:
class Circle {
private int x, y;
private float r = random(10, 25);
Circle() {
this.x = Math.round(random(0 + r, width - r));
this.y = Math.round(random(0 + r, height - r));
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public void show(Circle[] arr) {
if(isColliding(arr)) {
this.x = Math.round(random(0 + r, width - r));
this.y = Math.round(random(0 + r, height - r));
} else {
ellipse(this.x, this.y, r * 2, r * 2);
stroke(255);
fill(255);
}
}
public boolean isColliding(Circle[] arr) {
boolean result = false;
if(arr == null) {
result = false;
} else {
for(Circle c : arr) {
float d = dist(c.getX(), c.getY(), this.x, this.y);
if(d < r * 2) {
result = true;
println("Collision at: " + c.getX() + " " + c.getY());
break;
}
}
}
return result;
}
}
As you can see, i already have a isColliding Method, and the Outputs in the Console seem to be right, however it won't work in the show() Method, the Circles won't stop intersecting each other.
So how can i make it work, that the Position is re-calculated when it is colliding?
Are you sure your collision method works? Unless I'm missing something, it should ALWAYS return true as you're passing in an array that includes itself.
That aside, I'd start looking at how your show() logic is laid out. You are checking for overlap, and then assigning a new random position if it finds any. This new position could very likely be on a circle that has already been drawn and in a good position.
Put your re-positioning in a loop so that it checks to make sure that it didn't just place itself onto an existing circle.
public void show(Circle[] arr)
{
/*
You could potentially get into a situation where you will NEVER find an empty spot.
Add an escape method for the loop.
*/
int failLimit = 500;
while(failLimit-- > 0 && isColliding(arr))
{
this.x = Math.round(random(0 + r, width - r));
this.y = Math.round(random(0 + r, height - r));
}
ellipse(this.x, this.y, r * 2, r * 2);
stroke(255);
fill(255);
}
You could simplify this and make it a bit more efficient by spawning in circles one at a time, checking to make sure their positions are good then.
This question already has answers here:
Algorithm for finding all paths in a NxN grid
(11 answers)
Closed 6 years ago.
Imagine a robot sitting on the upper left hand corner of an NxN grid. The robot can only move in two directions: right and down. Imagine certain squares are “off limits”, such that the robot can not step on them. Design an algorithm to get all possible paths for the robot.
Here is the reference implementation I got, I think the implementation is wrong since it only find one path, other than all possible paths (more details, in line 10, the robot only goes down if no valid path in right. But to find all possible paths, the robot should try both right and down)? Want to confirm my understanding is correct.
ArrayList<Point> current_path = new ArrayList<Point>();
public static boolean getPaths(int x, int y) {
Point p = new Point(x, y);
current_path.add(p);
if (0 == x && 0 == y) return true; // current_path
boolean success = false;
if (x >= 1 && is_free(x - 1, y)) { // Try right
success = getPaths(x - 1, y); // Free! Go right
}
if (!success && y >= 1 && is_free(x, y - 1)) { // Try down
success = getPaths(x, y - 1); // Free! Go down
}
if (!success) {
current_path.remove(p); // Wrong way!
}
return success;
}
thanks in advance,
Lin
Here's what you can do:
public static class Point {
int x, y;
public Point (int x, int y) {
this.x = x;
this.y = y;
}
#Override
public String toString() {
return String.format("[%d, %d]", x, y);
}
}
public static void getPathsRec(int x, int y, Deque<Point> currentPath,
List<List<Point>> paths) {
if (x == 0 && y == 0) {
List<Point> path = new ArrayList<Point>();
for (Point p : currentPath)
path.add(p);
paths.add(path);
//System.out.println(currentPath);
return;
}
if (x > 0 && is_free(x-1, y)) {
currentPath.push(new Point(x-1, y));
getPathsRec(x-1, y, currentPath, paths);
currentPath.pop();
}
if (y > 0 && is_free(x, y-1)) {
currentPath.push(new Point(x, y-1));
getPathsRec(x, y-1, currentPath, paths);
currentPath.pop();
}
}
static int n = 2;
public static List<List<Point>> getPaths() {
List<List<Point>> paths = new ArrayList<List<Point>>();
Deque<Point> d = new ArrayDeque<Point>();
d.push(new Point(n-1, n-1));
getPathsRec(n - 1, n - 1, d, paths);
//System.out.println(paths);
return paths;
}
This is a simple backtracking. The idea is to visit the next state recursively but to make sure that after the call the state goes back to it's previous state(like it was before the call). Here this is done with popping the element from the Deque.
Notice that for simplicity you could introduce new class Path which would be something like:
class Path {
List<Point> points;
}
to make the code more readable. Then getPaths() would return List<Path> which is much nicer.
Also consider redefining getPathsRec to have the signature getPathsRec(Point p, Deque<Point>, List<Path> ), that is having one argument Point instead of having x, y. Having x, y seems redundant considering the fact that you've defined class Point. Again this would make it look better.
Your solution is wrong because once the it reach (0 == x && y==0), the success value will always set to true. Hence, it wouldn't go into later if
Below is the sample answer for your problem. It uses backtracking algorithm:
public class test {
static int n = 3; //substitute your n value here
static ArrayList<Point> current_path = new ArrayList<Point>();
static boolean[][] blockedCell = new boolean[n][n];
public static void FindAllWay(int x, int y)
{
if (x <0 || y < 0) return;
Point p = new Point(x, y);
current_path.add(p);
if (0 == x && 0 == y){
System.out.println(current_path.toString());
current_path.remove(current_path.size()-1);
return;
}
if ((x > 0) && !blockedCell[x-1][y]) //go right
{
blockedCell[x-1][y] = true;
FindAllWay(x-1, y);
blockedCell[x-1][y] = false;
}
if ((y > 0) &&!blockedCell[x][y-1]) // go down
{
blockedCell[x][y-1] = true;
FindAllWay(x, y-1);
blockedCell[x][y-1] = false;
}
current_path.remove(current_path.size()-1);
}
public static void main(String[] args)
{
FindAllWay(n-1,n-1);
}
}
I keep trying to run my program and one of my classes keeps sending me this error
"d.r cannot be resolved or is not a field"
the deer is supposed to be apart of a frogger-type game where they have to get to one side of the road without being hit by cars. The deers regenerate every time it gets to the street sign at the other side of the road.
class Deer {
float r; // radius
float x, y; // location
color col;
Deer(float tempR) {
r = tempR;
x = 500;
y = 250;
col = color(50, 10, 10, 150);
}
void setLocation(float tempX, float tempY) {
x = 500;
y = 250;
}
void display() {
//moveYourDeer Right();
fill(255);
ellipse(x, y, r * 2, r * 2);
}
void moveYourDeerLeft() {
if (keyPressed) {
if (key == 'a' || key == 'A') {
r--;
}
}
}
void moveYourDeerRight() {
if (keyPressed) {
if (key == 's' || key == 'S') {
r--;
}
}
}
void moveYourDeerForward() {
if (keyPressed) {
if (key == 'w' || key == 'W') {
r++;
}
}
}
void moveYourDeerBackwards() {
if (keyPressed) {
if (key == 'z' || key == 'Z') {
r++;
}
}
}
boolean intersect(StreetSign d) {
// Calculate distance
float distance = dist(x, y, d.x, d.y);
// Compare distance to sum of radii
if (distance < r + d.r) {
return true;
}
else {
return false;
}
}
// If the deer is caught by sign
void caught() {
// Stop it from moving by setting speed equal to zero
speed = 0;
// Set the location to somewhere way off-screen
y = -1000;
}
}
The class that is trying to access Deer.r is not allowed to do that. You should make r public:
class Deer {
public float r; // radius
(...)
Or make a getter for r and then use d.getR():
public float getR() {
return r;
}
I'm working on a plugin for the minecraft server api known as Bukkit.
My issues are getting the blocks as I don't know how to achieve this.
At the moment, I have the following:
public boolean loadSigns(Location loc1, Location loc2){
Selection selection = new Selection(loc1, loc2);
if(selection.getMax().getBlockY() - selection.getMin().getBlockY() != 0){
return false;
}
if ((selection.getMax().getBlockX() - selection.getMin().getBlockX()) != 0 && (selection.getMin().getBlockZ() - selection.getMax().getBlockZ() != 0)) {
return false;
}
World w = loc1.getWorld();
Integer x1 = loc1.getBlockX();
Integer y1 = loc1.getBlockY();
Integer z1 = loc1.getBlockZ();
Integer x2 = loc2.getBlockX();
Integer z2 = loc2.getBlockZ();
#SuppressWarnings("deprecation")
int dir = new Location(w, x1, y1, z1).getBlock().getData();
if (x1 - x2 == 0) {
for (int a = Math.max(x1, x2); a >= Math.min(x1, x2); a--) {
Location l = new Location(w, a, y1, z1);
BlockState b = l.getBlock().getState();
if (b instanceof Sign) {
signs.add((Sign) b);
} else {
return false;
}
}
} else {
for (int a = Math.min(z1, z2); a <= Math.max(z1, z2); a++) {
Location l = new Location(w, x1, y1, a);
BlockState b = l.getBlock().getState();
if (b instanceof Sign) {
signs.add((Sign) b);
} else {
return false;
}
}
}
if (dir == 3 || dir == 5) {
Collections.reverse(signs);
}
update();
return true;
}
loc1 is the left/start of the sign row; loc2 is the end/right of the sign row.
The problem with this is that any sign facing east or west only gets the first/start sign and not any of the others. If you need to see any other code, please say so.
P.S. new Selection(Location, Location); is just a cuboid region.
Instead of posting here where most of the people have no idea how the Bukkit api works, ask here --> https://forums.bukkit.org/forums/plugin-development.5/
Because here the community is WAY nicer, and all questions are answered, even the ones that are just one sentence
i implemented a simple A* and noticed that it does get into an infity loop if all 4 spots around my Character are filled. Current i am stuck how i get it work so they start running into the nearest possible spot. Any Guesses on it? (sorry for the long code)
the A*
private Node aStarSearch(int startX, int startY) {
openList.clear();
closeList.clear();
successor.clear();
Node startNode = new Node(null, startX, startY, 0, 0);
openList.add(startNode);
while (openList.size() != 0) {
// sort the list
Collections.sort(openList, nodeComperator);
Node q = openList.remove(0); // get the first object
int qx = q.x;
int qy = q.y;
// start adding the successors
// left
Node left = createNeighbor(q, qx - 1, qy);
if (left != null && !closeList.contains(left))
successor.add(left);
// right
Node right = createNeighbor(q, qx + 1, qy);
if (right != null && !closeList.contains(right))
successor.add(right);
// // down
Node down = createNeighbor(q, qx, qy - 1);
if (down != null && !closeList.contains(down))
successor.add(down);
// up
Node up = createNeighbor(q, qx, qy + 1);
if (up != null && !closeList.contains(up))
successor.add(up);
// calc
for (Node suc : successor) {
if (suc.x == (int) this.screen.character.mapPos.x
&& suc.y == (int) this.screen.character.mapPos.y)
return suc;
boolean add = true;
if (betterIn(suc, openList)) // openList und der
add = false;
if (betterIn(suc, closeList)) // closedList
add = false;
if (add)
openList.add(suc);
}
closeList.add(q);
}
return null;
}
private Node createNeighbor(Node parrent, int x, int y) {
if (x >= 0 && y >= 0 && x < this.screen.map.width
&& y < this.screen.map.height
&& this.screen.map.mapArray[x][y] != Config.CANTMOVEONPOSITION
&& this.screen.map.mapArray[x][y] != Config.MONSTERSTATE) {
Node n = new Node(parrent, x, y);
n.g = calcG(n);
n.h = calcH(n, (int) this.screen.character.mapPos.x,
(int) this.screen.character.mapPos.y);
return n;
}
return null;
}
private float calcG(Node n) {
Node p = n.getParrent();
return p.g + 1;
}
private float calcH(Node n, int targetX, int targetY) {
float dx = Math.abs(n.x - targetX);
float dy = Math.abs(n.y - targetY);
return (float) Math.sqrt((float) (dx * dx) + (dy * dy));
}
private boolean betterIn(Node n, List<Node> l) {
for (Node no : l) {
if (no.x == n.x && no.y == n.y && (no.g + no.h) <= (n.g + n.h))
return true;
}
return false;
}
My Node:
public class Node {
public int x, y;
public float g, h;
private Node parrent;
public Node(Node parrent, int x, int y, float g, float h) {
this.parrent = parrent;
this.x = x;
this.y = y;
this.g = g;
this.h = h;
}
public Node(Node parrent, int x, int y) {
this.parrent = parrent;
this.x = x;
this.y = y;
}
public Node getParrent() {
return parrent;
}
public void setParrent(Node parrent) {
this.parrent = parrent;
}
#Override
public boolean equals(Object o) {
// override for a different compare
return ((Node) o).x == this.x && ((Node) o).y == this.y;
}
#Override
public int hashCode() {
// if x and y are the same they are the same
return x + y;
}
}
If i do use nodes that are blocked but give them a high h they do not walk correct anymore so i dont know whats going wrong here.
Your A* algorithm seems a little bit screwy. But the code's not very clear -- for UP, DOWN, LEFT, RIGHT you repeat the same section (which should be broken out to a method).
It's not clear whether "discovered" nodes are clearly represented -- they should be a Set -- whereas you have "open", "closed" and "successor".
Checking each of your UP,DOWN,LEFT,RIGHT neighbors should be factored out to a method, which you call 4 times with neighborX and neighborY positions.
There isn't a single clear line which correctly tests whether a given neighbor (it's a neighbor, not a successor) has already been "discovered".
Neither am I sure about the post-processing of successors. Viz:
// calc
for (Node suc : successor) {
if (suc.x == (int) this.screen.character.mapPos.x
&& suc.y == (int) this.screen.character.mapPos.y)
return suc;
boolean add = true;
if (betterIn(suc, openList)) // openList und der
add = false;
if (betterIn(suc, closeList)) // closedList
add = false;
if (add)
openList.add(suc);
}
Since you sort "open nodes" on every iteration & pick the probable best, this doesn't really make sense to me & may be erroneous.
Presumably the algorithm should terminate promptly, when all four directions around the character are blocked. Failure to terminate implies that openList is not be processed correctly/ or incorrect nodes are being added.
Put some Log4J logging in & write a simple unit-test to verify it's correct behaviour in these conditions.
I also recommend rolling the 'createNeighbor', 'discovered check' and 'add to successor list' code into one method exploreNeighbor( Node q, int offsetX, int offsetY).
I've improved style & variable naming somewhat. You should also move towards using getters -- getX(), getY() for example.
exploreNeighbor( q, -1, 0); // left
exploreNeighbor( q, +1, 0); // right
exploreNeighbor( q, 0, -1); // up
exploreNeighbor( q, 0, +1); // down
protected boolean exploreNeighbor (Node parent, int offsetX, int offsetY) {
int x = q.getX() + offsetX;
int y = q.getY() + offsetY;
if (x < 0 || x >= screen.map.width)
return null;
if (y < 0 || y >= screen.map.height)
return false;
int content = screen.map.mapArray[x][y];
if (content == Contents.CANTMOVEONPOSITION ||
content == Contents.MONSTERSTATE) {
return false;
}
// represent Neighbor Position;
//
Node n = new Node(parent, x, y);
n.g = calcG(n);
n.h = calcH(n, (int) this.screen.character.mapPos.x,
(int) this.screen.character.mapPos.y);
// check if Discovered yet;
//
if (discoveredSet.contains( n)) {
// already queued or visited.
return false;
}
// queue it for exploration.
openQueue.add( n);
return true;
}
Good luck..