2013-05-15 1 views
1

J'ai un code écrit dans delphi, et quand j'ouvre le dossier d'exe sur l'ordinateur de cliens Il indique Liste d'index hors limite (0), j'ai recherché le google entier, mais ne pouvait pas réparer, comment je dois le corriger il y a somethins mal: D Merci à tousListe d'index hors limite (0) Delphi

code:

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

vous êtes probablement en train d'accéder à une liste de chaînes vide ici 'WordStr: = Dictionary [Idx];' puisque Dictionary.dat n'a pas été chargé à cause de manquant ou introuvable à cause du chemin relatif. – bummi

+8

Si vous avez "recherché tout Google", vous ne devez pas avoir recherché ce message d'erreur. Il y en a au moins deux ici à SO: http://stackoverflow.com/q/8778857/62576 et http://stackoverflow.com/q/3808921/62576, un dans le fichier d'aide de Delphi lui-même (http: // docwiki. embarcadero.com/Libraries/XE4/en/System.Classes.EListError) –

Répondre

9

Liste des index hors limite (0)

Cela signifie que vous att empoché pour référencer l'index 0 de la liste, mais il n'y a aucun élément à l'index 0. En d'autres termes, votre liste est vide.

Le seul endroit dans le code que je peux voir qui pourrait conduire à cette erreur est l'endroit où vous lisez les articles de Dictionary. Donc, je conclus que Dictionary est vide. Soit le fichier à partir duquel vous l'avez chargé n'est pas présent, soit ce fichier est vide.

A ce stade, dans le code

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

vous devez faire plus ignorer en silence le fichier manquant. Personnellement, je voudrais supprimer le chèque pour FileExists et tenter de charger le fichier, peu importe quoi. Si le chargement échoue, votre application déclenchera une exception à cet effet. Vous devriez également ajouter une vérification que le dictionnaire n'est pas vide.

Votre programme suppose que le répertoire de travail de votre processus est le même répertoire que celui contenant l'exécutable. Ce n'est pas toujours le cas. Au lieu d'utiliser des chemins relatifs, toujours une affaire fragile pour les programmes de GUI, spécifiez le chemin complet vers le fichier dictionnaire:

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

Vous avez un certain nombre de booléens:

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

Ceux-ci devraient tous être remplacés par un type énuméré:

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

ou quelque chose le long de ces lignes. Déclarer un champ FState: TState et l'initialiser à stHealthy. Chaque fois que l'utilisateur devine mal, écrivez inc(FState). Lorsque vous atteignez stDead, eh bien vous avez l'idée. Le point est qu'il y a un ordre total sur l'état et tous ces booléens vous fournissent plus de flexibilité qu'il est possible d'avoir. Il conduit également à un code verbeux et maladroit.

+0

Dictionary.LoadFromFile (ExtractFilePath (Application.ExeName) + 'Dictionary.dat'); cela a résolu, merci beaucoup. –

+3

Bien. Ne pas oublier d'accepter la réponse. Et lisez et comprenez le reste du conseil. –