unit ladderu;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ComCtrls, Menus, Buttons, Grids, Mask, ExtCtrls;

type
  TMainForm = class(TForm)
    MainMenu1: TMainMenu;
    File1: TMenuItem;
    Newwordfile1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    sgLadder: TStringGrid;
    Createpuzzle1: TMenuItem;
    LoadPuzzle1: TMenuItem;
    Action1: TMenuItem;
    ShowSolution1: TMenuItem;
    Image1: TImage;
    Help1: TMenuItem;
    HelpTopics1: TMenuItem;
    N2: TMenuItem;
    AboutPCLadder1: TMenuItem;
    PopupMenu1: TPopupMenu;
    PickWordFromList2: TMenuItem;
    Shownextword2: TMenuItem;
    Showsolution2: TMenuItem;
    Pickwordfromlist1: TMenuItem;
    Shownextword1: TMenuItem;
    Clearsolution1: TMenuItem;
    Clearsolution2: TMenuItem;
    pmVariable: TPopupMenu;
    Deletelast1: TMenuItem;
    Deletelast2: TMenuItem;
    N3: TMenuItem;
    Print1: TMenuItem;
    N3letterwords1: TMenuItem;
    N4letterwords1: TMenuItem;
    N5letterwords1: TMenuItem;
    N6letterwords1: TMenuItem;
    N7letterwords1: TMenuItem;
    N3letterwords2: TMenuItem;
    N4letterwords2: TMenuItem;
    N5letterwords2: TMenuItem;
    N6letterwords2: TMenuItem;
    N7letterwords2: TMenuItem;
    N4: TMenuItem;
    RandomPuzzle1: TMenuItem;
    Reversepuzzle1: TMenuItem;
    Reversepuzzle2: TMenuItem;
    N5: TMenuItem;
    N6: TMenuItem;
    lblStatus: TLabel;
    PrintDialog1: TPrintDialog;
    PrintSolution1: TMenuItem;
    Statistics1: TMenuItem;
    CheckProgress1: TMenuItem;
    Checkprogress2: TMenuItem;
    procedure Exit1Click(Sender: TObject);
    procedure sgLadderKeyPress(Sender: TObject; var Key: Char);
    procedure LoadPuzzle1Click(Sender: TObject);
    procedure sgLadderDrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    procedure Action1Click(Sender: TObject);
    procedure ShowSolution1Click(Sender: TObject);
    procedure ShowLadder(const vStartWord, vEndWord, vSol : String);
    procedure FormActivate(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure Shownextword1Click(Sender: TObject);
    procedure Clearsolution1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Pickwordfromlist1Click(Sender: TObject);
    procedure PopupMenu1Popup(Sender: TObject);
    procedure Deletelast1Click(Sender: TObject);
    procedure HelpTopics1Click(Sender: TObject);
    procedure AboutPCLadder1Click(Sender: TObject);
    procedure PrintPuzzle1Click(Sender: TObject);
    procedure SharedCreateClick(Sender: TObject);
    procedure SharedManageClick(Sender: TObject);
    procedure sgLadderSelectCell(Sender: TObject; Col, Row: Integer;
      var CanSelect: Boolean);
    procedure RandomPuzzle1Click(Sender: TObject);
    procedure Reversepuzzle1Click(Sender: TObject);
    procedure CheckProgressClick(Sender: TObject);
    procedure Statistics1Click(Sender: TObject);
  private
    { Private declarations }
    MinWidth,
    CurStep,
    NumSteps : Integer;
    StartWord, EndWord : String;
    StartLeng : Integer;
    HintPick, HintGive,
    HintSol : Integer;
    HintChk,
    Reversed: Boolean;
    CurWordList : TStringList;
    procedure RandomPuzzle;
    procedure DoFinish;
    procedure AppOnHint(Sender: TObject);
    function LoadPuzzle(const puzz : String) : Boolean;
    procedure AddNextGuess(const S : String);
    procedure WmGetMinMaxInfo(VAR Msg: TWMGetMinMaxInfo);
      message WM_GETMINMAXINFO;
    procedure VarWordListClick(Sender: TObject);
    procedure PaintAPuzzle(CV : TCanvas; PageWid, PageHig : Integer;
      Solution : Boolean);
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

uses Printers, ladSharU, CreateU, filemgru, loadpuzu, IniFiles, AboutBox, 
  finishu, statu;

{$R *.DFM}

procedure TMainForm.WmGetMinMaxInfo(VAR Msg: TWMGetMinMaxInfo);
begin
  Msg.MinMaxInfo^.ptMinTrackSize.X := MinWidth;
  Msg.MinMaxInfo^.ptMaxTrackSize.X := MinWidth;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  CurWordList := TStringList.Create;
  Application.Helpfile := ChangeFileExt(Application.ExeName, '.HLP');
  GenHint := '';
  Application.OnHint := AppOnHint;
  IniName := ChangeFileExt(Application.ExeName, '.INI');
  NameSpec := ExtractFileDir(Application.ExeName) +
    '\pcladr%d.DAT'
end;

procedure TMainForm.FormActivate(Sender: TObject);
begin
  RandomPuzzle;
end;

procedure TMainForm.FormResize(Sender: TObject);
begin
  MinWidth := sgLadder.Width+ 8 + 2*GetSystemMetrics(SM_CXFRAME);
  IF VertScrollBar.Range > ClientHeight THEN
    Inc(MinWidth, GetSystemMetrics(SM_CXVSCROLL));
end;

// fig 5 begin
procedure TMainForm.sgLadderDrawCell(Sender: TObject; ACol,
  ARow: Integer; Rect: TRect; State: TGridDrawState);
VAR
  bkMode : Integer;
  R1, R2 : TRect;
  C      : Char;
begin
  WITH Sender AS TStringGrid DO
    begin
      IF RowCount <= 1 THEN Exit;
      IF ACol=0 THEN
        begin
          IF ARow=0 THEN
            R2 := Bounds(0, 0, 25, 25)     // top left
          ELSE IF ARow=RowCount-1 THEN
            R2 := Bounds(0, 50, 25, 25)    // bottom left
          ELSE R2 := Bounds(0, 25, 25, 25) // left side
        end
      ELSE IF ACol = ColCount-1 THEN
        begin
          IF ARow=0 THEN
            R2 := Bounds(50, 0, 25, 25)    // top right
          ELSE IF ARow=RowCount-1 THEN
            R2 := Bounds(50, 50, 25, 25)   // bottom right
          ELSE R2 := Bounds(50, 25, 25, 25)// right side
        end
      ELSE R2 := Bounds(25, 0, 25, 25);    // middle
      R1 := Rect;
      Inc(R1.Right); Inc(R1.Bottom);
      Canvas.CopyRect(R1, Image1.Picture.Bitmap.Canvas, R2);
      IF (ACol>0) AND (ACol<=StartLeng) AND (Cells[0,ARow]<>'') THEN
        begin
          bkMode := SetBkMode(Canvas.Handle, TRANSPARENT);
          C := Cells[0, ARow][ACol];
          Canvas.Font := Font;
          IF ACol = StrToIntDef(Cells[1, ARow], -1) THEN
            Canvas.Font.Color := clRed
          ELSE Canvas.Font.Color := clBlack;
          DrawText(Canvas.Handle, @C, 1, Rect, DT_CENTER);
          SetBkMode(Canvas.Handle, bkMode);
        end;
      IF CheckProgress1.Checked AND (ACol=0) AND
       (Cells[2, ARow] = 'R') THEN
        begin
          Canvas.Brush.Color := clRed;
          WITH Rect DO
            Canvas.Ellipse(Left+4, Top+8, Right-12, Bottom-8);
        end;
      IF State * [gdSelected, gdFocused] <> [] THEN
        Canvas.DrawFocusRect(Rect);
    end;
end;
// fig 5end

procedure TMainForm.sgLadderKeyPress(Sender: TObject; var Key: Char);
VAR S : String;
begin
  WITH Sender AS TStringGrid DO
    begin
      IF Col=0 THEN Exit;
      IF Col=ColCount-1 THEN Exit;
      CASE UpCase(Key) OF
        'A'..'Z' : ;
        #8 : begin
          IF CurStep=1 THEN Exit;
          Cells[0, CurStep-1] := '';
          Cells[1, CurStep-1] := '';
          Cells[2, CurStep-1] := '';
          CurStep := CurStep-1;
          Refresh;
          Exit;
        end;
        ELSE Exit;
      end;
      S := Cells[0,CurStep-1];
      IF UpCase(Key) <> S[Col] THEN
        begin
          S[Col] := UpCase(Key);
          AddNextGuess(S);
        end;  
    end;
end;

procedure TMainForm.sgLadderSelectCell(Sender: TObject; Col, Row: Integer;
  var CanSelect: Boolean);
begin
  CanSelect := (Col > 0) AND (Col < (Sender AS TStringGrid).ColCount-1);
end;

procedure TMainForm.PopupMenu1Popup(Sender: TObject);
begin
  WITH sgLadder DO
    ShowNextWord2.Enabled :=
      Cells[ColCount-1, CurStep-1] = Cells[0, CurStep-1];
end;

procedure TMainForm.Action1Click(Sender: TObject);
begin
  ShowSolution1.Enabled := (StartWord <> '') AND (EndWOrd <> '');
  WITH sgLadder DO
    ShowNextWord1.Enabled :=
      Cells[ColCount-1, CurStep-1] = Cells[0, CurStep-1];
end;

procedure TMainForm.SharedManageClick(Sender: TObject);
begin
  WITH TFileManageForm.Create(Self) DO
    try
      SetWordLength((Sender AS TMenuItem).Tag);
      ShowModal;
    finally
      Free;
    end;
end;

procedure TMainForm.SharedCreateClick(Sender: TObject);
begin
  WITH TCreateForm.Create(Self) DO
    try
      SetWordLength((Sender AS TMenuItem).Tag);
      IF ShowModal = mrOK THEN
        ShowLadder(sFrom, sTo, sSol);
    finally
      Free;
    end;
end;

procedure TMainForm.LoadPuzzle1Click(Sender: TObject);
begin
  WITH TLoadPuzzForm.Create(Self) DO
    try
      IF ShowModal = mrOK THEN
        ShowLadder(sFrom, sTo, sSol);
    finally
      Free;
    end;
end;

procedure TMainForm.RandomPuzzle1Click(Sender: TObject);
begin
  RandomPuzzle;
end;

procedure TMainForm.PrintPuzzle1Click(Sender: TObject);
begin
  IF PrintDialog1.Execute THEN
    WITH Printer DO
      begin
        BeginDoc;
        PaintAPuzzle(Canvas, PageWidth, PageHeight,
          (Sender AS TMenuItem).Tag=1);
        EndDoc;
      end;
end;

procedure TMainForm.Exit1Click(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.Pickwordfromlist1Click(Sender: TObject);
VAR
  T      : TextFile;
  CurWord,
  S1, S2 : String;
  N, Loc : Integer;
  Found  : Boolean;
  PopPt  : TPoint;
  slTemp : TStringList;
begin
  Inc(HintPick);
  Found := False;
  CurWord := sgLadder.Cells[0, CurStep-1];
  AssignFile(T, Format(NAMESPEC, [StartLeng]));
  Reset(T);
  Screen.Cursor := crHourglass;
  try
    WHILE NOT EoF(T) DO
      begin
        ReadLn(T, S1);
        IF Pos(CurWord, S1)=1 THEN
          begin
            Found := True;
            Break;
          end;
      end;
  finally
    CloseFile(T);
    Screen.Cursor := crDefault;
  end;
  IF Found THEN S1 := Copy(S1, StartLeng+4, 255)
  ELSE S1 := '';
  WITH pmVariable.Items DO
    WHILE Count > 0 DO Delete(0);
  IF S1 = '' THEN
    begin
      pmVariable.Items.Add(NewItem('(sorry, no words)', 0, False,
        True, NIL, 0, 'mnu'+S2));
    end
  ELSE
    begin
      Loc := -1;
      slTemp := TStringList.Create;
      try
        FOR N := 1 TO Length(S1) DO
          begin
            IF (S1[N]>='1') AND (S1[N]<='7') THEN
              Loc := Ord(S1[N])-Ord('0')
            ELSE
              begin
                S2 := CurWord;
                S2[Loc] := S1[N];
                slTemp.Add(S2);
              end;
          end;
        slTemp.Sort;
        FOR N := 0 TO slTemp.Count-1 DO
          WITH pmVariable DO
            begin
              Items.Add(NewItem(slTemp[N], 0, False, True,
                VarWordListClick, 0, 'mnu'+slTemp[N]));
              IF Items.Count > 10 THEN
                IF Items.Count MOD 10 = 1 THEN
                  Items[Items.Count-1].Break := mbBarBreak;
            end;
      finally
        slTemp.Free;
      end;
    end;
  PopPt := sgLadder.ClientToScreen(Point(24*(StartLeng+1), 24*CurStep));
  pmVariable.Popup(PopPt.X, PopPt.Y);
end;

procedure TMainForm.VarWordListClick(Sender: TObject);
begin
  WITH sgLadder DO
    begin
      IF CurStep = RowCount-1 THEN Exit;
      AddNextGuess((Sender AS TMenuItem).Caption);
    end;
end;

procedure TMainForm.Clearsolution1Click(Sender: TObject);
VAR N : Integer;
begin
  WITH sgLadder DO
    begin
      FOR N := 1 TO RowCount-2 DO
        begin
          Cells[0,N] := '';
          Cells[1,N] := '';
          Cells[2,N] := '';
        end;
      CurStep := 1;
      Refresh;
    end;
end;

procedure TMainForm.Deletelast1Click(Sender: TObject);
begin
  WITH sgLadder DO
    begin
      IF CurStep=1 THEN Exit;
      Cells[0, CurStep-1] := '';
      Cells[1, CurStep-1] := '';
      Cells[2, CurStep-1] := '';
      CurStep := CurStep-1;
      Refresh;
      Exit;
    end;
end;

procedure TMainForm.Reversepuzzle1Click(Sender: TObject);
VAR
  N : Integer;
  S : String;
begin
  Reversed := NOT Reversed;
  WITH sgLadder DO
    begin
      FOR N := 1 TO RowCount-2 DO
        begin
          Cells[0,N] := '';
          Cells[1,N] := '';
          Cells[2,N] := '';
        end;
      S := StartWord;
      StartWord := EndWord;
      EndWord := S;
      Cells[0, 0] := StartWord;
      Cells[0, RowCount-1] := EndWord;
      WITH Cols[ColCount-1] DO
        FOR N := 0 TO (RowCount DIV 2)-1 DO
          begin
            S := Strings[N];
            Strings[N] := Strings[RowCount-1-N];
            Strings[RowCount-1-N] := S;
          end;
      CurStep := 1;
      Refresh;
    end;
end;

procedure TMainForm.Shownextword1Click(Sender: TObject);
begin
  Inc(HintGive);
  WITH sgLadder DO
    begin
      IF CurStep = RowCount-1 THEN Exit;
      AddNextGuess(Cells[ColCount-1, CurStep]);
    end;
end;

procedure TMainForm.ShowSolution1Click(Sender: TObject);
VAR N : Integer;
begin
  Inc(HintSol);
  WITH sgLadder DO
    begin
      FOR N := 1 TO RowCount-1 DO
        begin
          Cells[0, N] := Cells[ColCount-1, N];
          Cells[1, N] := IntToStr(OneDifferentLoc(Cells[0, N], Cells[0, N-1]));
          Cells[2, N] := '';
        end;
      CurStep := RowCount-1;
      Refresh;
    end;
end;

procedure TMainForm.CheckProgressClick(Sender: TObject);
begin
  CheckProgress1.Checked := NOT (Sender AS TMenuItem).Checked;
  CheckProgress2.Checked := CheckProgress1.Checked;
  IF CheckProgress1.Checked THEN
    HintChk := True;
  sgLadder.Refresh;
end;

procedure TMainForm.HelpTopics1Click(Sender: TObject);
begin
  Application.HelpCommand(HELP_FINDER, 0);
end;

procedure TMainForm.AboutPCLadder1Click(Sender: TObject);
begin
  WITH TAboutForm.Create(Self) DO
  try
    ShowModal;
  finally
    Free;
  end;
end;

procedure TMainForm.ShowLadder(const vStartWord, vEndWord, vSol : String);
VAR
  NewH, N, WasLeng : Integer;
  S : String;
begin
  HintPick  := 0;
  HintGive  := 0;
  HintSol   := 0;
  HintChk   := CheckProgress1.Checked;
  Reversed  := False;
  StartWord := vStartWord;
  WasLeng   := StartLeng;
  StartLeng := Length(vStartWord);
  EndWord   := vEndWord;
  NumSteps  := Length(vSol) DIV 2;
  CurStep   := 1;
  WITH sgLadder DO
    begin
      ColCount := StartLeng+2;
      FOR N := RowCount-1 DOWNTO 0 DO
        Rows[N].Clear;
      RowCount := NumSteps+1;
      Width := ColCount*Succ(DefaultColWidth);
      Height := RowCount*Succ(DefaultRowHeight);
      Cells[0,0] := StartWord;
      Cells[0,RowCount-1] := EndWord;
      WITH Cols[ColCount-1] DO
        begin
          Strings[0] := StartWord;
          S := StartWord;
          FOR N := 1 TO NumSteps DO
            begin
              S[Ord(vSol[(N*2)-1])-Ord('0')] := vSol[N*2];
              Strings[N] := S;
            end;
        end;
      Col := 1;
      Row := 1;
      Refresh;
    end;
  NewH := (Height - ClientHeight) + sgLadder.Height +
    sgLadder.Top + 12;
  IF Top+NewH+2 >= Screen.Height THEN
  NewH := Screen.Height - Top-2;
  // Tweak height to get new MinWidth set
  Height := NewH+1;
  Height := NewH;
  Refresh;
  IF WasLeng <> StartLeng THEN
    begin
      Screen.Cursor := crHourglass;
      try
        CurWordList.Clear;
        CurWordList.Sorted := False;
        CurWordList.LoadFromFile(Format(NameSpec, [StartLeng]));
        FOR N := 0 TO CurWordList.Count-1 DO
          CurWordList[N] := Copy(CurWordList[N], 1, StartLeng);
        CurWordList.Sorted := True;
      finally
        Screen.Cursor := crDefault;
      end;
    end;
end;

procedure TMainForm.AddNextGuess(const S : String);
VAR dif : Integer;
begin
  WITH sgLadder DO
    begin
      IF CurStep = RowCount-1 THEN Exit;
      IF CurWordList.IndexOf(S) = -1 THEN
        begin
          MessageDlg(Format('"%s" is not in the word list. Try '+
            'again.', [S]), mtError, [mbOK], 0);
          exit;
        end;
      dif := NumDifferent(S, EndWord);
      IF dif > (RowCount-1-CurStep) THEN
        Cells[2, CurStep] := 'R';
      Cells[0, CurStep] := S;
      Cells[1, CurStep] := IntToStr(OneDifferentLoc(
        Cells[0, CurStep-1], S));
      CurStep := CurStep+1;
      Refresh;
      IF OneDifferentEZ(Cells[0, CurStep-1], EndWord) THEN
        DoFinish;
    end;
end;

procedure TMainForm.DoFinish;
begin
  WITH TIniFile.Create(IniName) DO
    try
      IF Reversed THEN
        WriteBool('Solved',Format('%s-%s', [EndWord, StartWord]), True)
      ELSE
        WriteBool('Solved',Format('%s-%s', [StartWord, EndWord]), True);
    finally
      Free;
    end;
  WITH TFinishForm.Create(Self) DO
    try
      SetValues(HintPick, HintGive, HintSol, HintChk);
      SetPlace(Self.Left, Self.Top, Self.Width);
      ShowModal;
    finally
      Free;
    end;
end;

function TMainForm.LoadPuzzle(const puzz : String) : Boolean;
// Puzzle string has form 'HATE-LOVE=1L3V2O'
VAR
  S, sFrom, sTo : String;
  Loc           : Integer;
begin
  Result := False;
  S := Puzz;
  Loc := Pos('-', S);
  IF Loc = 0 THEN Exit;
  sFrom := Copy(S, 1, Loc-1);
  Delete(S, 1, Loc);
  Loc := Pos('=', S);
  IF Loc = 0 THEN Exit;
  sTo := Copy(S, 1, Loc-1);
  IF Length(sFrom) <> Length(sTo) THEN Exit;
  Delete(S, 1, Loc);
  ShowLadder(sFrom, sTo, S);
  Result := True;
end;

procedure TMainForm.RandomPuzzle;
VAR
  Tries  : Integer;
  slTemp : TStringList;
begin
  Randomize;
  slTemp := TStringList.Create;
  try
    WITH TIniFile.Create(IniName) DO
      try
        ReadSectionValues('Puzzles', slTemp);
        IF slTemp.Count=0 THEN
          LoadPuzzle('HATE-LOVE=1L3V2O')
        ELSE
          begin
            Tries := 0;
            REPEAT
              Inc(Tries)
            UNTIL LoadPuzzle(slTemp[Random(slTemp.Count)]) OR
                  (Tries > 3);
          end;
      finally
        Free;
      end;
  finally
    slTemp.Free;
  end;
end;

procedure TMainForm.AppOnHint(Sender: TObject);
VAR S : String;
begin
  S := Application.Hint;
  IF Length(S) < 2 THEN S := GenHint;
  IF Screen.ActiveForm IS TFileManageForm THEN
    TFileManageForm(Screen.ActiveForm).SetHint(False, S)
  ELSE IF Screen.ActiveForm IS TCreateForm THEN
    TCreateForm(Screen.ActiveForm).SetHint(False, S);
end;

procedure TMainForm.PaintAPuzzle(CV : TCanvas; PageWid, PageHig : Integer;
  Solution : Boolean);
CONST
  Blank = '_______';
VAR
  R       : TRect;
  Steps,
  dX, dY  : Integer;
  OKSize  : Boolean;
  S       : String;
  N, XOrg : Integer;

  procedure CellOut(const S : String; Chg : Integer);
  VAR N : Integer;
  begin
    R := Bounds(XOrg, R.Bottom, dX, dY);
    FOR N := 0 TO StartLeng-1 DO
      begin
        IF Chg = 0 THEN
         CV.Font.Style := [fsBold]
        ELSE IF (N=Chg-1) THEN
          CV.Font.Style := [fsBold, fsItalic]
        ELSE CV.Font.Style := [];
        DrawText(CV.Handle, PChar(S)+N, 1, R, DT_CENTER OR DT_VCENTER);
        OffsetRect(R, dX, 0);
      end;
  end;

begin
  Steps := sgLadder.RowCount-1;
  CV.Font.Size := 20;
  CV.Font.Style := [fsBold];
  REPEAT
    FillChar(R, SizeOf(R), 0);
    DrawText(CV.Handle, 'W', 1, R, DT_CALCRECT);
    dX := R.Right + 4;
    dY := R.Bottom + 6;
    OKSize := dY*(Steps+5) < PageHig;
    IF NOT OkSize THEN CV.Font.Size := CV.Font.Size-1;
  UNTIL OKSize;
  CV.Font.Style := [];
  IF Solution THEN
    S := 'Solution for puzzle generated by PC Ladder'
  ELSE S := 'Puzzle generated by PC Ladder';
  R := Rect(0, PageHig-2*DY, PageWid, PageHig);
  DrawText(CV.Handle, PChar(S), Length(S), R, DT_CENTER OR DT_VCENTER);
  S := '(PC Ladder Copyright © 1998 by Ziff-Davis, Inc.)';
  R := Rect(0, PageHig-DY, PageWid, PageHig);
  DrawText(CV.Handle, PChar(S), Length(S), R, DT_CENTER OR DT_VCENTER);
  S := Format('From %s to %s in %d steps', [StartWord, EndWord, Steps]);
  R := Rect(0, 0, PageWid, dY);
  DrawText(CV.Handle, PChar(S), Length(S), R, DT_CENTER OR DT_VCENTER);
  XOrg := (PageWid-(dX*Length(StartWord))) DIV 2;
  OffsetRect(R, 0, dY);
  CellOut(StartWord, 0);
  IF Solution THEN
    begin
      FOR N := 1 TO Steps-1 DO
        CellOut(sgLadder.Cells[StartLeng+1, N],
          OneDifferentLoc(sgLadder.Cells[StartLeng+1, N],
                       sgLadder.Cells[StartLeng+1, N-1]));
    end
  ELSE
    FOR N := 1 TO Steps-1 DO
      CellOut(Blank, 0);
  CellOut(EndWord, 0);
end;


procedure TMainForm.Statistics1Click(Sender: TObject);
VAR
  sl_temp : TStringList;
  NumPuzz, NumSolv : Integer;
begin
  sl_temp := TStringList.Create;
  try
    WITH TIniFile.Create(IniName) DO
      try
        ReadSection('Puzzles', sl_temp);
        NumPuzz := sl_temp.Count;
        ReadSection('Solved', sl_temp);
        NumSolv := sl_temp.Count;
      finally
        Free;
      end;
  finally
    sl_temp.Free;
  end;
  WITH TStatForm.Create(Self) DO
    try
      SetStats(NumPuzz, NumSolv);
      SetPlace(Self.Left, Self.Top, Self.Width);
      ShowModal;
    finally
      Free;
    end;
end;

end.



