1

I am trying to make a breadth-first search to solve a square-shifting puzzle (the one where you move squares into an empty space until it's solved). My breadth-first algorithm uses a queue. Unfortunately, it only seems to be working for the UP and DOWN cases, and not the LEFT or RIGHT cases:

                if (up)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x - 1][y];
                current[x - 1][y] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

            if (down)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x + 1][y];
                current[x + 1][y] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

            if (left)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x][y - 1];
                current[x][y - 1] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

            if (right)
            {
                int[][] current = copy(v.state);
                current[x][y] = current[x][y + 1];
                current[x][y + 1] = 0;

                State w = new State(current);
                w.distance = v.distance + 1;
                w.path = v;
                System.out.println(q.insert(w));
            }

I think it's a problem with my queue, the implementation of which is below. Is there something wrong with my queue, or is it another problem? Does the Java API have a queue class I could use?

public class ArrayQueue {
State[] items;
int maxSize;
int front;
int rear;
int numItems;

public ArrayQueue(int max)
{
    items = new State[max];
    maxSize = max;
    front = 0;
    rear = -1;
    numItems = 0;
}

public boolean insert(State item)
{
    if (isFull()) return false;
    rear = (rear + 1) % items.length;
    items[rear] = item;
    return true;
}

public State remove()
{
    if (isEmpty()) return null;
    State removed = items[front];
    front = (front + 1) % items.length;
    return removed;
}

public boolean isFull()
{
    if ((front + 1) % maxSize == rear)
        return true;
    else
        return false;
}

public boolean isEmpty()
{
    if ((rear + 1) % maxSize == front)
            return true;
    else
        return false;
}
}

Here is the copy method:

public static int[][] copy(int[][] input)       //This method is necessary because we are trying to clone a multi-dimensional array.
{                                               //Just using clone() will copy the outer arrays but they will be arrays of references to the original inner arrays.
int[][] output = new int[input.length][];
for (int i = 0; i < input.length; i++)
    output[i] = input[i].clone();
return output;
}
Andrew Latham
  • 5,982
  • 14
  • 47
  • 87
  • 1
    How about [`Queue`](http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Queue.html)? – Oliver Charlesworth Nov 29 '11 at 01:13
  • *Does the Java API have a queue class I could use?* Did you LOOK for one? The [API docs](http://www.oracle.com/technetwork/java/javase/documentation/api-jsp-136079.html) are online, and you should have them bookmarked. – Hot Licks Nov 29 '11 at 01:19
  • And why do you suspect your queue, if it works for up/down but not left/right? – Hot Licks Nov 29 '11 at 01:21
  • The most salient difference, to me, between your up/down cases and your left/right cases is that the former are moving the square from one `int[]` to another, while the latter are moving the square within the same `int[]`. This makes me wonder if the problem might actually be in your `copy` method; if it's only doing a one-deep copy, you'd see different behavior between these two cases. – ruakh Nov 29 '11 at 01:25
  • @HotLicks There's no need to be so derisive. When I search Google, all I see is an interface, and when I try to use it anyway just on the off-chance that there might be a Queue class, I get the error message "Cannot instantiate the type Queue". – Andrew Latham Nov 29 '11 at 01:26
  • @ruakh I don't see a problem in the copy method, but I edited the question to add the code at the end. – Andrew Latham Nov 29 '11 at 01:32
  • @AndrewLatham: I agree, your `copy` looks fine. Never mind that thought. :-) – ruakh Nov 29 '11 at 01:37

2 Answers2

2

The JDK provides a Queue interface and a number of implementations, which can be found in the "All Known Implementing Classes" section of the Queue documentation.

For your purposes, a LinkedList should probably be good enough.

Mansoor Siddiqui
  • 20,853
  • 10
  • 48
  • 67
0

I guess, that the issue is with 'front' and 'rear'. They need to point to the same position 0 in the beginning, so when they are equal, the queue is empty. 'Rear' will point to position to write (write, and then shift forward) and 'front' to position to read (read and then shift). 'Rear' seems to move ahead faster while the queue is filling up. When it goest to the end, it will return to the begging. So you'll need to perform (rear + 1) % max == front to check, if you can safely insert a new item.

Also, consider to use some of the standart implementations, as Mr.Siddiqui suggested.

sviklim
  • 1,054
  • 1
  • 15
  • 30