1

我正在尝试用二维数组表示二维坐标网格。问题是,由于 Delphi 分配数组的方式,声明数组会翻转 X 和 Y 坐标。这使得难以读取数组的元素。例如,以下程序在尝试打印时给出范围检查错误:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

{$R+}
procedure play;
var
   grid: array of array of boolean;
   x, y: integer;
begin
  try
   setLength(grid, 3, 8);
   grid[1, 5] := true;
   for y := low(grid) to high(grid) do
   begin
      for x := low(grid[y]) to high(grid[y]) do
      begin
         if grid[x, y] then
            write('X')
         else write('.');
      end;
      writeln;
   end;
   readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end;

begin
   play;
end.

我必须向后写索引(如果 grid[y, x] then)以防止这种情况发生,但随后网格会横向打印,X 显示在 (5, 1) 而不是 (1, 5)。如果我尝试通过说 setLength(grid, 3, 8); 来改变网格的形状;然后下一行的赋值给出了范围检查错误。我最终不得不把我所有的坐标都写反了,每当我忘记它们是反的时,程序中就会发生不好的事情。

有谁知道使坐标顺序直观工作的任何技巧?

4

3 回答 3

4

您只需要在for语句中给出适当的界限。将lowhigh函数应用于多维数组时要特别注意。对于当前示例(二维数组),low(grid) 和 high(grid) 将返回第一维(行)的限制,而 low(grid[0]) 和 high(grid[0]) 将返回返回第一列的限制(假设它存在)。请注意以下限制的更改:

program Play_console;

{$APPTYPE CONSOLE}

uses
  SysUtils;

{$R+}
procedure play;
var
   grid: array of array of boolean;
   x, y: integer;
begin
  try
   setLength(grid, 3, 8);
   grid[1, 5] := true;
   for y := low(grid[0]) to high(grid[0]) do
   begin
      for x := low(grid) to high(grid) do
      begin
         if grid[x, y] then
            write('X')
         else write('.');
      end;
      writeln;
   end;

   readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end;

begin
   play;
end.

我对此进行了测试,它似乎完全符合您的要求。

于 2009-07-04T05:06:16.387 回答
1

[y, x] 是大多数(所有?)编程语言中常见的标准数组访问。如果您不这样做,任何查看您的代码的人都会感到困惑。

于 2009-07-03T23:04:58.437 回答
1

我想说标准表示不仅与一般编程约定一致,而且与一般图形一致。在方格纸上绘制 [1,4] ,您将得到与第二个(实际结果)示例相同的结果,除了 y 轴在屏幕坐标中翻转,但您并没有抱怨这一点。

更具体地说,x 轴始终是水平的,y 轴始终是垂直的。这就是您的示例所显示的。它没有逆转。

我说习惯就好。

于 2009-07-04T03:27:50.997 回答