Smart Pascal version of Crossword

Smart Pascal version of Crossword by Adam Renak: L6 Age ~16

Introduction

You can use this Smart Pascal version of Crossword on a PC, tablet or smart phone. The application downloads the word list from this website and splits it into the Words array. We use zero-based arrays so the processing code is slightly different from Adam Renak's Pascal original.

Crossword.html

If you see no display at school, the security system might have blocked it. You can try instead this direct link to the program running on its own page.

The Code

unit Unit1;

{
    Copyright (c) 2010 Adam Renak

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/

    Converted to Smart Pascal by PPS, 2015

}

interface

uses 
  System.Types, System.Lists, SmartCL.System, SmartCL.Scroll, SmartCL.Console,
  SmartCL.Components, SmartCL.Application, SmartCL.ConsoleApp, SmartCL.Inet,
  SmartCL.RegEx;

type
  TApplication = class(TW3CustomConsoleApplication)
  private
    const LIST_LENGTH = 80368;
    FHttp: TW3HttpRequest;
    Words: array of string;
    NarrowWords: array[0..99999] of string;
    NarrowFactor: integer;
    Input: string;
  protected
    procedure ApplicationStarting; override;
    procedure PopulateConsole; override;
    procedure ProcessCommand(aCommand: string); override;
  end;

implementation

procedure TApplication.ApplicationStarting;
var
  WordList: string;
begin
  FHttp := TW3HttpRequest.Create;
  FHttp.OnDataReady := lambda
      WordList := FHttp.ResponseText;
      Words := WordList.split('\n');
    end;
  FHttp.Get('res/DictWordlist.txt');
  inherited;
end;

procedure TApplication.PopulateConsole;
begin
  Header.Title.Caption := 'Crossword Aid';
  Console.WriteLn('Press Execute then enter the word to solve. Use ? to show unknowns.');
end;

procedure TApplication.ProcessCommand(aCommand: string);

  procedure NarrowLength; //Narrows the wordlist down to words of similar length
  var
    Count1, Count2: integer;
  begin
    Count2 := 0;
    for Count1 := 0 to LIST_LENGTH - 1 do
      begin
        if length(Input) = length(Words[Count1]) then
          begin
            inc(Count2);
            Narrowwords[Count2] := Words[Count1];
            Narrowfactor := Count2 + 1;
          end;
      end;
  end;

  procedure Narrow(vWord: string; position: integer); //Narrows list according to character position.
  var
    NarrowPos, InsertCount: integer;
  begin
    InsertCount := -1; //Sets the pointer that the new narrowlist begins at
    for NarrowPos := 0 to Narrowfactor - 1 do //From 0 to the current number of narrowed words - 1
      if vWord[position] = narrowwords[NarrowPos][position] then
        begin
          inc(InsertCount);
          NarrowWords[InsertCount] := NarrowWords[NarrowPos];
        end;
    Narrowfactor := InsertCount + 1;
  end;

begin
  Input := lowercase(aCommand); //Makes the input lower case
  Narrowlength;

  for var CharPosn := 1 to length(Input) do
    if Input[CharPosn] <> '?' then
      Narrow(input, CharPosn);

  //writes a list of matching words:
  Console.writeln('--------------------------------------');
  for var WriteCount := 0 to Narrowfactor - 1 do  // Writes out the possible words
     Console.writeln('MATCH: ' +  NarrowWords[writecount]);

  //If no match is found, it writes the five closest matches.
  if Narrowfactor = 0 then
    begin
      Console.writeln('No match found. Try these suggestions:' +  #13#10);
      for var WriteCount := Narrowfactor to Narrowfactor + 4 do  //Writes out the possible words
         Console.writeln(NarrowWords[writecount]);
    end;
   Console.writeln('--------------------------------------' + #13#10);
end;

end.
Programming - a skill for life!

by Adam Renak: L6 Age ~16