D is always better than whatever language you're using.
struct Grid(T) {
uint width, height;
T[] array;
this(uint w, uint h) {
width = w;
height = h;
array.length = width * height;
}
static struct Coord { uint x, y; }
auto ref opIndex(int x, int y) {
const n = y * width + x;
return array[n];
}
auto ref opIndex(Coord p) {
const n = p.y * width + p.x;
return array[n];
}
int opApply(scope int delegate(Coord, ref T) dg) {
foreach (y; 0 .. height)
foreach (x; 0 .. width) {
auto ret = dg(
Coord(x, y),
this[x,y]
);
if (ret) return ret;
}
return 0;
}
}
auto grid = Grid!char(64, 32);
foreach (coord, c; grid) {
writefln(i`$(coord.x),$(coord.y): $(c)`);
}