Delphi 保存后如何将棋盘加载到程序中?

Delphi 保存后如何将棋盘加载到程序中?,delphi,Delphi,我有一个程序,将棋盘保存到文本文件中。我试图在保存后将电路板读回程序。当我调用这个过程时,我得到了这个错误 代码,我有装载在板上 Procedure LoadBoard(Var Board : Tboard); var fptr:text; i,j,x:integer; line:string; load:char; begin Write('Do you want a load a game? (Enter Y for yes)'); Readln(load);

我有一个程序,将棋盘保存到文本文件中。我试图在保存后将电路板读回程序。当我调用这个过程时,我得到了这个错误

代码,我有装载在板上

Procedure LoadBoard(Var Board : Tboard);
var
  fptr:text;
  i,j,x:integer;
  line:string;
  load:char;

begin
  Write('Do you want a load a game? (Enter Y for yes)');
  Readln(load);
  If (Ord(load) >= 97) and (Ord(load) <= 122)
    Then load := Chr(Ord(load) - 32);

  if load='Y' then
    begin
      assignfile(fptr,'SBoard.txt');
      reset(fptr);
      i:=1;
      repeat
        readln(fptr,line);
        j:=1;
        x:=1;
        repeat
          begin
            if (line[x]<>',') and (line[x+1]<>',')
            then
              begin
                Board[i,j][1]:=line[x];
                Board[i,j][2]:=line[x+1];
              end;
            if line[x]=','
            then
              j:=j+1;
              x:=x+1;
          end;
        until j=9;
        i:=i+1;
      until i=9;
      close(fptr);
    end;
end;
程序加载板(Var板:Tboard);
变量
fptr:文本;
i、 j,x:整数;
行:字符串;
加载:char;
开始
写下('您想加载游戏吗?(输入Y表示是)';
Readln(加载);

如果(Ord(load)>=97)和(Ord(load),则使用文本文件并逐行保存电路板会使事情变得过于复杂

我认为您应该使用
TStringList
来保存和加载:

Const
  BoardDimension = 8;
  BoardFileName = 'SBoard.txt';

Type
  TBoard = Array [1 .. BoardDimension, 1 .. BoardDimension] Of String;

procedure SaveBoard(Board: TBoard);
var
  i, j: Integer;
  Line, BoardFile: TStringList;
begin
  BoardFile := TStringList.Create;
  Line := TStringList.Create;

  for i := 1 to BoardDimension do
  begin
    Line.Clear;
    for j := 1 to BoardDimension do
      Line.Add(Board[i, j]);
    BoardFile.Add(Line.CommaText);
  end;

  Line.Free;
  BoardFile.SaveToFile(BoardFileName);
  BoardFile.Free;
end;

procedure LoadBoard(Board: TBoard);
var
  i, j: Integer;
  Line, BoardFile: TStringList;
begin
  if not FileExists(BoardFileName) then
    exit; // Show error message

  BoardFile := TStringList.Create;
  BoardFile.LoadFromFile(BoardFileName);

  Line := TStringList.Create;

  for i := 1 to BoardDimension  do
  begin
    Line.CommaText := BoardFile[i];
    for j := 1 to BoardDimension  do
      Board[i, j] := Line[j];
  end;

  Line.Free;
  BoardFile.Free;
end;
如果您想测试加载一个save proceudre,您可以这样做:

procedure Test;
var
  Board: TBoard;
  BoardA: TBoard;
  i, j: Integer;
begin
  randomize;
  for i := 1 to BoardDimension  do
    for j := 1 to BoardDimension  do
      Board[i, j] := Random(500).ToString;

   SaveBoard(Board); //Save Board
   LoadBoard(BoardA); //Load the file into a NEW board

  for i := 1 to BoardDimension  do //Comapre the two boards
    for j := 1 to BoardDimension  do
      if Board[i,j] <> BoardA[i,j] then
        raise Exception.Create('Wrong file format');
end;
程序测试;
变量
板:t板;
BoardA:TBoard;
i、 j:整数;
开始
随机化;
对于i:=1,以确定尺寸
对于j:=1到尺寸do
Board[i,j]:=Random(500).ToString;
保存板(板);//保存板
加载板(BoardA);//将文件加载到新的板中
对于i:=1到BoardDimension do//Comapre两块板
对于j:=1到尺寸do
如果Board[i,j]Board[i,j]那么
引发异常。创建('错误的文件格式');
结束;

由于
板上的字符串成员为空(长度为零),因此没有可访问的字符位置,因此会出现访问冲突异常

要修复当前代码,在将内容分配给字符位置之前,应在每个字符串成员上使用
SetLength()
。您尚未显示字符串包含的内容,因此只有您知道设置的长度应该是多少


另一方面,在之前对您的问题的回答中,有人建议您使用其他几种方法来保存您的棋盘。您应该回顾这些方法,并可能选择其中一种。回答这些答案并告诉您为什么没有选择它们也是礼貌的。可能我们无法解释这些好处。

与您无关r访问冲突:谷歌“FEN”表示位置通常被存储的方式。它还包含50个移动规则信息、密码、移动对象……以及一行短文本中的所有内容。()当您学习如何调试程序时,您将节省大量时间,而不是针对您面临的每一个问题都提出问题。第一个问题:如果您使用
writeln(fptr,board[i,j]将电路板状态保存为多个字符串,则会节省大量时间
为什么要逐个字符地将它们加载回2D字符串数组,而不是直接作为字符串加载?例如
Board[i,j]:=line;
还有,为什么不使用for循环而不是重复循环?既然你知道电路板的确切尺寸,我相信你可以用for循环来做这件事更容易。另一个快速提示。开始用更有意义的名称命名变量。今天你可能仍然知道使用了什么变量x,但何时你必须使用几个月后看一看你的代码,你可能不会有丝毫的想法,必须看一看你的代码才能确定。我自己也不得不努力学习这一课。但在我的例子中,我有三分之一的字母表:-),因此,为变量选择一个更有意义的名称将大大提高代码的可读性。