Crossword using Text File as Resource

PPS Adaptation of Crossword by Adam Renak: L6 Age ~16

Introduction

We followed guidance to (1) create the resource from DictWordList.txt, (2) instruct the compiler to compile it into the 1 MB Crossword.exe, and (3) retrieve the file from the executable. Lazarus resources are more straightforward than the alternative Windows resources recommended in the guidance. You can download the data file DictWordlist.txt required by the program. These points outline the adaptation:

  1. Resource creation - Using the Windows Command Prompt, we changed directory to the project folder then gave the instruction C:\lazarus\tools\lazres mylazres.lrs DictWordList.txt. The response was: DictWordList.txt ResourceName='DictWordList' Type='TXT'.
  2. Resource inclusion - The compiler directive {$I mylazres.lrs} at the start of the main section instructs the compiler to include the file in the executable.
  3. Resource retrieval - The code immediately following the directive writes the text file to disk on the first execution of the program. Select menu item Project > Project Inspector > Add other items > New Requirement and select LCLBase.

Differences in Set-up for Lazarus on the Raspberry Pi

We created the resource file by typing the command lazres mylazres.lrs DictWordList.txt into the LXTerminal. We needed to add the packages LCL and lclbase using the Project Inspector. In order to run the console program from within Lazarus, we selected menu item Run > Run Parameters, checked the box titled Use launching application and copied into the corresponding edit box the code /usr/bin/x-terminal-emulator -T 'Crossword' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine). You can download, extract, change file permissions and run on the Pi the compressed executable Crossword.gz (431 KB). To run it, change directory to where you have extracted it and type the commands chmod a+x Crossword then ./Crossword into the LXTerminal.

The Program

program Crossword;
{$APPTYPE CONSOLE}

{
    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/

    Adapted to use resource file by PPS, 2015
}

uses
  SysUtils, LResources; // Add LCLBase (& LCL for Linux) using Project Inspector
const
  ListLength = 213563;
var
  Words: array[1..ListLength] of string;
  NarrowWords: array[1..100000] of string;
  Count1, Count2, CharPosn, writecount, NarrowFactor: integer;
  input: string;
  Dictionary: TLResource;
  DataFile: textfile;

Procedure LoadWordlist;
var
  Wordlist: textfile;
  Count: integer;
begin
  AssignFile(Wordlist, 'DictWordList.txt');
  Reset(Wordlist);
  Count := 1;
  while not eof(Wordlist) do
    begin
      readln(Wordlist, Words[count]);
      inc(count);
    end;
  CloseFile(Wordlist);
end;

Procedure NarrowLength; //Narrows the wordlist down to words of similar length
begin
  Count2 := 0;
  for Count1 := 1 to ListLength do
    begin
      if length(input) = length(words[count1]) then
        begin
          inc(count2);
          Narrowwords[count2] := words[count1];
          Narrowfactor := count2;
        end;
    end;
end;

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

begin
  {$I mylazres.lrs}
  if not fileExists('DictWordList.txt') then
    begin
      writeln('Creating dictionary file for first use', #13#10);
      Dictionary := LazarusResources.Find('DictWordList');
      if Dictionary = nil then
        raise Exception.Create('resource DictWordList is missing');
      Assignfile(DataFile, 'DictWordList.txt');
      rewrite(DataFile);
      write(DataFile, Dictionary.Value);
      closeFile(DataFile);
    end;

  Loadwordlist;
  repeat
    writeln('Input the word to solve. Use ? to show unknowns:');
    readln(input);
    input := lowercase(input); //Makes the input lower case
    Narrowlength;

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

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

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

end.
Programming - a skill for life!

by Adam Renak: L6 Age ~16