索引列表超出范围(0)Delphi

时间:2013-05-15 21:09:31

标签: delphi

我在delphi中编写了一个代码,当我在cliens计算机上打开exe文件时说 索引列表超出范围(0),我搜索了整个谷歌,但无法修复,我该如何解决?有些错误:D感谢所有

代码:

    unit UntMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Controls, StdCtrls, Forms,
  Graphics, ExtCtrls, Mask, Dialogs, Spin;

type
  TfrmMain = class(TForm)
    Panel1: TPanel;
    PaintBox1: TPaintBox;
    Button1: TButton;
    Timer1: TTimer;
    Edit1: TEdit;
    SpinEdit1: TSpinEdit;
    Button2: TButton;
    procedure PaintBox1Paint(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure Timer1Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    Head: Boolean;
    Body: Boolean;
    RArm: Boolean;
    LArm: Boolean;
    LLeg: Boolean;
    RLeg: Boolean;
    WordStr:String;
    SlashedWord: string;
    Loaded: Boolean;
  protected
   Dictionary: TStringList;
   procedure reset;
   procedure HangMan;
   function SolveWord(SlashedWord, WordStr: String; C: Char): String;
   function isHanged: Boolean;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

uses UntHangman, UntAbout;

{$R *.dfm}

function TfrmMain.isHanged: Boolean;
begin
result:= (Head=True) AND (Body=True) AND (RARM=True) AND (LARM=true) AND (RLeg=True) AND (LLeg=true);
end;

procedure TfrmMain.HangMan;
begin
 if not Head then begin Head:= true; PaintBox1.Invalidate; exit; end else
 if not Body then begin Body:= true; PaintBox1.Invalidate; exit; end else
 if not RArm then begin RArm:= true; PaintBox1.Invalidate; exit; end else
 if not LArm then begin LArm:= true; PaintBox1.Invalidate; exit; end else
 if not RLeg then begin RLeg:= true; PaintBox1.Invalidate; exit; end else
 if not LLeg then begin LLeg:= true; PaintBox1.Invalidate; exit; end;
end;

function TfrmMain.SolveWord(SlashedWord, WordStr: String; C: Char): String;
var
 idx: Integer;
begin
 result:= SlashedWord;
 for Idx := 1 to length(WordStr) do
 begin
  if upcase(WordStr[Idx]) = upcase(C) then
  begin
   result[Idx]:= C;
  end;
 end;
end;


procedure TfrmMain.Timer1Timer(Sender: TObject);
var
 I: Integer;
begin
I:= SpinEdit1.Value;
if I <> 0 then
 begin

 I:= I-1;

 SpinEdit1.Value:=   SpinEdit1.Value -1;
 end
 else
begin
 Timer1.Enabled:= False;
 ShowMessage('You Lost!');
 reset;
 end;
end;

function SlashWord(Str: String): String;
var
 I: Integer;
begin
 for I := 1 to length(str) do
  if Str[I] <> ' ' then
   result:= result + '-'
  else
   result:= result + ' ';
end;

procedure TfrmMain.reset;
begin

 Head:= False;
 Body:= False;
 LArm:= False;
 RArm:= False;
 LLeg:= False;
 RLeg:= False;
 paintBox1.Invalidate;

 Edit1.Clear;
 SpinEdit1.Value:= 30;
end;

procedure TfrmMain.Button1Click(Sender: TObject);
var
 idx: Integer;
begin
idx:= random(Dictionary.Count);

 WordStr:= Dictionary[Idx];
 SlashedWord:= SlashWord(WordStr);
 Edit1.Text:= SlashedWord;
 Loaded:= True;

 Timer1.Enabled:= True;
end;

procedure TfrmMain.Button2Click(Sender: TObject);
begin
 frmAbout.ShowModal;
 PaintBox1.Invalidate;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
 self.KeyPreview:= True;
 randomize;
 Dictionary:= TStringList.Create;

 if FileExists('Dictionary.dat') then
 Dictionary.LoadFromFile('Dictionary.dat');
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
Dictionary.Free;
end;

procedure TfrmMain.FormKeyPress(Sender: TObject; var Key: Char);
begin
if loaded then
 begin

 if pos(upcase(Key), Uppercase(WordStr)) > 0 then
 begin
 SlashedWord:= SolveWord(SlashedWord, WordStr, Key);
 Edit1.Text:= SlashedWord;
if Uppercase(SlashedWord) = UpperCase(WordStr) then
  begin
 Timer1.Enabled:= False;
 ShowMessage('You Won!');
 reset;

    exit;
  end;
 end
 else
 begin

  HangMan;
 if isHanged then
  begin

   Timer1.Enabled:= False;

   Edit1.Text:= WordStr;
   ShowMessage('You Lost!');

   reset;
   exit;
  end;
 end;
 end;
end;

procedure TfrmMain.PaintBox1Paint(Sender: TObject);
var
 X,Y: Integer;
begin
 inherited;
 with PaintBox1 do
 begin
 Canvas.Pen.Color:= clBlack;
 Canvas.Pen.Width:= 5;
 Canvas.Pen.Style:= psSolid;
 Canvas.Rectangle(1,1, ClientWidth-1, ClientHeight-1);
 Canvas.Brush.Color:= clWhite;
 Canvas.FloodFill(10,10,clBlack, fsBorder);
 Canvas.MoveTo(ClientWidth div 2, 1);
 Canvas.LineTo(Clientwidth div 2, ClientHeight Div 4);
 X:= Clientwidth div 2; Y:= ClientHeight Div 4;
 Canvas.Pen.Width:= 3;
 if Head then

 Canvas.Ellipse(X-25, Y-25, X+25, Y+25);
 Y:= Y + 25;
 Canvas.MoveTo(X, Y);
 if Body then
 Canvas.LineTo(X, Y + 100);
 Canvas.MoveTo(X, Y + 25);
 if LArm then
 Canvas.LineTo(X-25, Y+50);

 Canvas.MoveTo(X, Y + 25);

 if RArm then
 Canvas.LineTo(X+25, Y+50);

 Canvas.MoveTo(X, Y + 100);
 if LLeg then
 Canvas.LineTo(X-25, Y+150);

 Canvas.MoveTo(X, Y + 100);
 if RLeg then
 Canvas.LineTo(X+25, Y+150);
 end;
end;

end.

1 个答案:

答案 0 :(得分:9)

  

索引列表超出范围(0)

这意味着您尝试引用列表的索引0,但索引0处没有元素。换句话说,您的列表为空。

我可以看到代码中唯一可能导致该错误的位置是您从Dictionary读取项目的位置。所以,我得出结论Dictionary是空的。您加载的文件不存在,或者该文件为空。

此时代码

if FileExists('Dictionary.dat') then
  Dictionary.LoadFromFile('Dictionary.dat');

你需要做的不仅仅是默默地忽略丢失的文件。就个人而言,我会删除FileExists的检查并尝试加载文件,无论如何。如果加载失败,您的应用程序将引发异常。您还应该添加检查字典不为空。

您的程序假定您的进程的工作目录与包含可执行文件的目录相同。情况可能并非总是如此。而不是使用相对路径,对于GUI程序来说总是一件脆弱的事情,请指定字典文件的完整路径:

Dictionary.LoadFromFile(ExtractFilePath(Application.ExeName)+'Dictionary.dat');

你有许多布尔值:

Head: Boolean;
Body: Boolean;
RArm: Boolean;
LArm: Boolean;
LLeg: Boolean;
RLeg: Boolean;

这些都应该用枚举类型替换:

type
  TState = (stHealthy, stHead, stBody, ..., stDead);

或类似的东西。声明字段FState: TState并初始化为stHealthy。每次用户猜错时,请写inc(FState)。当你到达stDead时,你就明白了。重点是国家有一个总订单,所有这些布尔为您提供了比可能的更多的灵活性。它还会导致冗长和笨拙的代码。