1
public class TileGrid implements Iterable<Tile> {
    private wheelSize = [a positive integer];
    private Tile[][] grid = new Tile[wheelSize * 2 + 1][wheelSize * 2 + 1]

    @Override
    public Iterator<Tile> iterator() {
        return ????????;
    }
}

I've made a TileGrid class to keep track of a hex-grid for me. It stores Tile-objects in a two dimensional array called grid. Now I want to make the TileGrid class Iterable so that I can easily loop through all Tile-objects. The problem is that there is some positions in the array that is naturally not used (due to the shape of the hex-grid) and thus contains the value null.

My question is this: How do I create an iterator that iterates through all positions in grid except the ones that is null?

I do not want to use some kind of ArrayList since I'm using the array indexes to mark the position of the Tiles.

Z3wz
  • 61
  • 1
  • 8
  • You can just check for null values and continue if null – Mark Aug 17 '15 at 17:16
  • We need more information. What have you already tried? When iterating over a standard 2D array, you can iterate rows then columns, columns then rows, or something more exotic (like a zig-zag). What iteration order do you want? – Jeffrey Aug 17 '15 at 17:16
  • Create an inner class of TileGrid, e.g. `TileIterator`, that implements `Iterator` and maintains the current position in private fields (e.g. `x` and `y`). As you advance the x,y position, you skip empty cells. – Andreas Aug 17 '15 at 17:17

2 Answers2

2

You have to return an Instance of an Implementation of the Iterator class. The iterator you return should be able to access your array so that the code makes sense.(http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html)

public Iterator<Tile> iterator() {
   return new TileGridIterator(grid);
}

That means you need to write a class that implements the Iterator-Interface and that implements all methods that are specified in the API of that interface.

An example of this could look like that:

import java.util.Iterator;
import java.util.NoSuchElementException;

public class TileGridIterator implements Iterator<Tile> {
    int x = 0;
    int y = 0;
    int nextX = 0;
    int nextY = -1;
    Tile[][] grid;

    public TileGridIterator(Tile[][] grid) {
        this.grid = grid;
    }

    public boolean hasNext() {
        while(nextX <= x && nextY < y) {
            nextY++;
            if(nextY == grid[nextX].length) {
               nextY = 0;
               nextX++;
            }
            if(nextX >= grid.length) {
                return false;
            }
            if(grid[nextX][nextY] != null) {
                return true;
            }
        }
        if(nextX < grid.length && nextY < grid[nextX].length && grid[nextX][nextY] != null) {
            return true;
        }
        else {
            return false;
        }
    }

    public Tile next() {
        if(hasNext()) {
            x = nextX;
            y = nextY;
            return grid[x][y];
        }else {
            throw new NoSuchElementException("no more elements left");
        }
    }
}

ps: thanks for the question, it was an interesting task for me.

HopefullyHelpful
  • 1,652
  • 3
  • 21
  • 37
1

@HopefullyHelpful

My version:

public Iterator<Tile> iterator() {
    return new TileIterator(grid);
}

.

class TileIterator implements Iterator<Tile> {

    int x = 0, y = -1;
    int newX, newY;
    Tile[][] grid;

    TileIterator(Tile[][] grid) {
        this.grid = grid;
        updateNewIndex();
    }

    public boolean hasNext() {
        if (newX == -1) {
            return false;
        }
        return true;
    }

    public Tile next() {
        x = newX;
        y = newY;
        updateNewIndex();
        if (x == -1) {
            throw new NoSuchElementException("no more elements left");
        }
        return grid[x][y];
    }

    private void updateNewIndex() {
        newX = x;
        newY = y;
        do {
            newY++;
            if (newY == grid[newX].length) {
                newY = 0;
                newX = newX + 1;
                if (newX == grid.length) {
                    newX = newY = -1;
                }
            }
        } while (newX != -1 && grid[newX][newY] == null);
    }
}

Thanks again for your answer as it helped me make this.

Z3wz
  • 61
  • 1
  • 8