如何在 Delphi 中表示坐标网格?

发布于 2024-07-26 06:56:22 字数 902 浏览 2 评论 0原文

我试图用二维数组表示二维坐标网格。 问题是,由于 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] 那么)以防止发生这种情况,但随后网格会横向打印,其中 X显示在 (5, 1) 而不是 (1, 5)。 如果我尝试通过 setLength(grid, 3, 8); 来更改网格的形状 那么下一行的赋值会给出范围检查错误。 我最终不得不向后写所有坐标,每当我忘记它们是向后的时,程序中就会发生不好的事情。

有谁知道有什么技巧可以使坐标顺序直观地工作吗?

I'm trying to represent a two-dimensional coordinate grid with a two-dimensional array. Problem is, declaring the array flips the X and Y coordinates because of the way Delphi allocates the array. This makes it difficult to read elements of the array. For example, the following program gives a range check error while trying to print:

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.

I have to write the index backwards (if grid[y, x] then) to keep that from happening, but then the grid prints out sideways, with the X shown at (5, 1) instead of at (1, 5). If I try to change the shape of the grid by saying setLength(grid, 3, 8); then the assignment on the next line gives a range check error. I end up having to write all of my coordinates backwards, and any time I forget they're backwards, bad things end up happening in the program.

Does anyone know any tricks to make the coordinate order work intuitively?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甩你一脸翔 2024-08-02 06:56:22

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

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.

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

You just need to give the proper bounds in the for statements. It's important to pay careful attention when applying the low and high functions to multi-dimensional arrays. For the current example (a 2-dimensional array), low(grid) and high(grid) will return the limits on the first dimension (row), whereas low(grid[0]) and high(grid[0]) will return the limits on the first column (assuming it exists). Note the changed for limits below:

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.

I tested this and it seems to do exactly what you want.

々眼睛长脚气 2024-08-02 06:56:22

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

[y, x] is common and standard array access across most (all?) programming languages. It will be confusing for anyone looking at your code if you do it otherwise.

哎呦我呸! 2024-08-02 06:56:22

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

更具体地说,x 轴始终是水平的,y 轴始终是垂直的。 这就是你的例子所显示的。 这不是颠倒过来的。

我想说只是习惯而已。

I'd say that the standard representation isn't only consistent with general programming convention, it's consistent with graphing in general. Plot [1,4] on graph paper and you'll get the same thing as in your second (actual result) example, with the exception that the y axis is flipped in screen coordinates, but you're not complaining about that.

More specifically, the x axis is consistently horizontal, and the y axis is consistently vertical. That's what your example shows. It's not reversed.

I'd say just get used to it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文